私は現在Cortex M0 / M4をコーディングしています。C++で使用しているアプローチは次のとおりです(C ++タグがないため、この答えはトピックとは異なる場合があります)は次のとおりです。
CInterruptVectorTableコントローラーの実際の割り込みベクトルに格納されているすべての割り込みサービスルーチンを含むクラスを使用します。
#pragma location = ".intvec"
extern "C" const intvec_elem __vector_table[] =
{
{ .__ptr = __sfe( "CSTACK" ) }, // 0x00
__iar_program_start, // 0x04
CInterruptVectorTable::IsrNMI, // 0x08
CInterruptVectorTable::IsrHardFault, // 0x0C
//[...]
}
クラスCInterruptVectorTableは割り込みベクトルの抽象化を実装しているため、ランタイム中にさまざまな関数を割り込みベクトルにバインドできます。
そのクラスのインターフェースは次のようになります。
class CInterruptVectorTable {
public :
typedef void (*IsrCallbackfunction_t)(void);
enum InterruptId_t {
INTERRUPT_ID_NMI,
INTERRUPT_ID_HARDFAULT,
//[...]
};
typedef struct InterruptVectorTable_t {
IsrCallbackfunction_t IsrNMI;
IsrCallbackfunction_t IsrHardFault;
//[...]
} InterruptVectorTable_t;
typedef InterruptVectorTable_t* PinterruptVectorTable_t;
public :
CInterruptVectorTable(void);
void SetIsrCallbackfunction(const InterruptId_t& interruptID, const IsrCallbackfunction_t& isrCallbackFunction);
private :
static void IsrStandard(void);
public :
static void IsrNMI(void);
static void IsrHardFault(void);
//[...]
private :
volatile InterruptVectorTable_t virtualVectorTable;
static volatile CInterruptVectorTable* pThis;
};
ベクトルテーブルはオブジェクトではないstaticため、コントローラーはthisポインターを提供できないため、ベクトルテーブルに格納される関数を作成する必要があります。そのため、その問題を回避するために、pThis内部に静的ポインタがありCInterruptVectorTableます。静的割り込み関数の1つに入ると、pThis-pointerにアクセスして、の1つのオブジェクトのメンバーにアクセスできますCInterruptVectorTable。
プログラムでは、を使用しSetIsrCallbackfunctionてstatic、割り込みが発生したときに呼び出される関数への関数ポインターを提供できます。ポインタはに保存されますInterruptVectorTable_t virtualVectorTable。
そして、割り込み関数の実装は次のようになります:
void CInterruptVectorTable::IsrNMI(void) {
pThis->virtualVectorTable.IsrNMI();
}
そのため、それはstatic別のクラス(の場合もありますprivate)のメソッドを呼び出し、static thisそのオブジェクトのメンバー変数(1つだけ)にアクセスするための別の-pointerを含めることができます。
IInterruptHandlerオブジェクトへのポインタのように構築してインターフェイスし、ポインタを格納できるのでstatic this、これらすべてのクラスで-pointer は必要ありません。(たぶん、私たちはアーキテクチャの次の反復でそれを試すでしょう)
割り込みハンドラーの実装が許可されているオブジェクトはハードウェアアブストラクションレイヤー内のオブジェクトのみであり、通常、ハードウェアブロックごとに1つのオブジェクトしかないため、static this-pointersでうまく機能するため、他のアプローチはうまく機能します。また、ハードウェアアブストラクションレイヤーは、割り込みにさらに別のアブストラクションを提供します。ICallbackこれは、ハードウェアの上のデバイスレイヤーに実装されます。
グローバルデータにアクセスしますか?確かにそうですが、- thisポインタや割り込み関数のように、必要なグローバルデータのほとんどをプライベートにすることができます。
防弾ではなく、オーバーヘッドが追加されます。このアプローチを使用してIO-Linkスタックを実装するのは難しいでしょう。しかし、タイミングが極端に厳しくない場合、これは非常にうまく機能し、どこからでもアクセスできるグローバル変数を使用せずに、モジュールの割り込みと通信の柔軟な抽象化を取得できます。