私は組み込みロボットプロジェクト用の小さなフレームワークを作成しています。ザイリンクスのZynq FPGA(FPGAとARM Cortex A9を1チップに内蔵)を使用しています。C++の割り込みルーチンにメソッドをアタッチする
アイデアは比較的単純です。私のmain()
では、私は割り込みを初期化して、メインから同様にルーチン(run()
メソッド)を呼び出す必要があります。何らかの形で、run()
メソッドは、コード内の別々の場所にある間に割り込みにアタッチする必要があります。
割り込みは、スタティックTimer
クラスで初期化されます。 initInterrupt()
の内部には、が付属しており、Timer
クラスにも含まれています。最終的には、すべてのコードをinterruptRoutine()
の範囲で実行する必要があります。
どういうわけか、run()
メソッドをmain.cc
ファイル(Timer
クラスより上)に入れて、すべてのロジックと他のすべての関数呼び出しを格納したいとします。
これをどのように達成できますか?
main.cc:
int main() {
Timer::initInterrupt();
Timer::run([] {
// All logic goes here?
// Very hopeful thinking that this is possible...
});
}
タイマークラス:
class Timer {
public:
static void initInterrupt(void);
static void interruptRoutine(void*);
static void run();
};
/**
* Initialize main interrupt routine
*/
void initInterrupt(void) {
// Declare pointers
XScuTimer_Config* ConfigPtr;
XScuGic_Config* IntcConfig;
// Initialize timers by looking up config and initializing with that config
ConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);
XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr, ConfigPtr->BaseAddr);
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
XScuGic_CfgInitialize(&IntcInstance, IntcConfig,
IntcConfig->CpuBaseAddress);
// Initialize exception handling
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler, &IntcInstance);
// Connect interrupt routine to exception handler
XScuGic_Connect(&IntcInstance, TIMER_IRPT_INTR,
(Xil_ExceptionHandler) interruptRoutine, (void *) (&TimerInstance));
// Enable interrupts
XScuGic_Enable(&IntcInstance, TIMER_IRPT_INTR);
XScuTimer_EnableInterrupt(&TimerInstance);
// Enable exception handler
Xil_ExceptionEnable();
// Set auto reload so timer reloads when interrupt is cleared
XScuTimer_EnableAutoReload(&TimerInstance);
// Set timer value
XScuTimer_LoadTimer(&TimerInstance, TIMER_LOAD_VALUE);
// Start interrupt
XScuTimer_Start (&TimerInstance);
}
/**
* main interrupt routine
*/
inline void Timer::interruptRoutine(void *CallBackRef) {
// Define pointer to timer
XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;
// If timer is expired, clear interrupt status
if (XScuTimer_IsExpired(TimerInstancePtr)) {
XScuTimer_ClearInterruptStatus(TimerInstancePtr);
// Currently all the application logic is handled in here
}
}
inline void Timer::run(Callback){
// We want all our application logic to be handled in here but it has to be called from the main()
}
私はそれが私が説明したより少し複雑だと思う。私は私の 'Timer'クラスがどんなロジックについて何かを知ることを望んでいません。それはSRPに続く。メインはすべての権限を委譲しますが、私は何とか割り込みでそのコードをすべて実行する必要があります。問題は、私が今ここで行うことができる唯一の場所は 'interruptRoutine()'の 'Timer'クラスの中にあることです。 – Ortix92
@ Ortix92 - 私が言及した派生クラスの仮想メソッドはどうですか?それはあなたのために働くだろうか?それ以外の場合は、通常のコールバック関数を使用してください。 – Roddy