2016-12-16 2 views
0

クラスメソッドを割り込みサービスルーチンとして使用できますか?そして、実装をクラスメソッドを使用するC++ ISR?

void interrupt far ISR(...); 

::メソッド(プロトタイプ)を作成するために、私はC++で試してみた

static void interrupt far ISR(...) {} 

私は、ISRが書かれており、機能を使用してCで働いてい

#pragma interrupt 
    void interrupt far MyClass::ISR(...) { 
    ... 
    } 

「setvect」でこれを使用しようとすると、さまざまなエラーが発生します。

setvect(muint16Vector, &ISR); 

ISRはシリアルポートをサービスするクラスを作成しようとしていますが、ISRはポートからのRxデータを処理します。 ISRはインスタンス固有のメンバーを使用します。

私は3つのシリアルポートを持っているので、クラスの3つのインスタンスを作成したいと思います。あなただけの時に呼び出すためのインスタンスであるグローバル変数を作成する必要があり

+0

非静的メンバー関数は、クラスの*インスタンス*で呼び出す必要があります。非メンバ関数ポインタとしては使用できません。静的メンバー関数でラップするか、C言語のように実際の非メンバ関数を使用してください。 –

+0

@Someprogrammerdude、もう少し詳しく説明するテキストを追加します。ありがとうございます。 – SPlatten

+0

どのような引数が割り込みハンドラに渡されますか?引数の1つがシリアルポート番号である場合は、オブジェクトの配列を使用し、シリアルポート番号引数を使用してその配列にインデックスを付け、実際のメンバ関数を呼び出すことができます。 –

答えて

0

リアル答えは 'いいえ'です.C++ではISRハンドラとしてメソッドを直接使用することはできません。

標準のC関数を使用し、ISR関数で接着剤を使用して、必要なオブジェクトを参照する必要があります。

これは非常に面倒な解決策に終わります。

0

:コメントで与えられた情報を使用して

class Handler { 
    void ISR(...) {} 
}; 

static unique_ptr<Handler> g_handler; 

#pragma interrupt 
extern "C" static void interrupt far ISR(...) { 
    if (g_handler) 
    g_handler->ISR(...); 
} 

g_handler = std::make_unique<Handler>(); 
setvect(muint16Vector, &ISR); 
+0

ISRはどのハンドラを呼び出すのかをどのように知っていますか? – SPlatten

+0

@SPlatten:どういう意味ですか?私は完全なコードを投稿しました。これは、グローバル変数を設定しているためです。 –

+0

オブジェクトのインスタンスが3つあります。どのオブジェクトが関連しているかをISRはどのように知っていますか? – SPlatten

1

が、これは可能な解決策である:

class SerialPort 
{ 
public: 
    // Unrelated functions... 

    void isr(); // The serial interrupt handler 

    // Other unrelated stuff... 
}; 

std::array<SerialPort, 3> serial_ports; // Or SerialPort serial_ports[3]; 

static void serial_isr(int const port_index) 
{ 
    // Common code for all serial ports that for some reason 
    // can't be in the class... 

    serial_ports[port_index].isr(); // Call actual ISR 
} 

extern "C" void interrupt serial_isr_1() 
{ 
    // Special code for only this serial port... 

    serial_isr(0); 
} 

extern "C" void interrupt serial_isr_2() 
{ 
    // Special code for only this serial port... 

    serial_isr(1); 
} 

extern "C" void interrupt serial_isr_3() 
{ 
    // Special code for only this serial port... 

    serial_isr(2); 
} 
+0

月曜日にやってみようと思っていたことはまさにその通りです。 – SPlatten

関連する問題