MicroBlazeのタイマー割り込みを使ってみました.一秒くらいに一回,”Interrupt timer!!”っていうようなサンプルです.
ベタには,割り込みベクタに読んでほしい関数へのポインタを指定しておいて,割り込みコントローラやタイマのレジスタに値を設定する.割り込みで呼ばれる関数では割り込み要因をチェックして所望の処理云々というのを実装すればよいのですが,XilinxのSDKのドライバ関数を呼び出すとすっきりと実装できました.(べたに書くのとどっちがいいか…というのはありますが…)
タイマー割り込みが動くと自分でタスクスケジューラとか書きたくなってきますね.
リソース一式
MicroBoardをターゲットとしてEDKで作成したMicroBlazeなプロセッサシステムとソフトウェア一式です.
タイマ割り込みの使い方・詳解
後で書く
#include <stdio.h> #include "platform.h" #include "xtmrctr.h" #include "xintc.h" #include "xparameters.h" #include "xbasic_types.h" void print(char *str); void timer_int_handler(); void timer_int_handler() { volatile static int cnt; volatile unsigned int csr; csr = XTmrCtr_GetControlStatusReg(XPAR_AXI_TIMER_0_BASEADDR, 0); xil_printf("Interrupt timer!! %d\r\n", cnt++); XTmrCtr_SetControlStatusReg(XPAR_AXI_TIMER_0_BASEADDR, 0, csr); } XTmrCtr tmr; XIntc intc; int main() { init_platform(); print("Hello World\n\r"); XStatus status; status = XIntc_Initialize(&intc, XPAR_INTC_0_DEVICE_ID); if (status != XST_SUCCESS){print("intc init error\n\r"); return status;} status = XTmrCtr_Initialize(&tmr, XPAR_AXI_TIMER_0_DEVICE_ID); if (status != XST_SUCCESS){print("timer init error\n\r"); return status;} status = XIntc_Connect(&intc, XPAR_INTC_0_TMRCTR_0_VEC_ID, (XInterruptHandler)XTmrCtr_InterruptHandler, (void*)&tmr); if (status != XST_SUCCESS){print("connect error\n\r"); return status;} status = XIntc_Start(&intc, XIN_REAL_MODE); if (status != XST_SUCCESS){print("intc start error\n\r"); return status;} XIntc_Enable(&intc, XPAR_INTC_0_TMRCTR_0_VEC_ID); XTmrCtr_SetHandler(&tmr, (void*)timer_int_handler, (void*)0); microblaze_enable_interrupts(); print("setup finished\n\r"); // see LogiCORE IP AXI Timer Product Guide, PG079 XTmrCtr_SetOptions(&tmr, 0, XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION); XTmrCtr_SetResetValue(&tmr, 0, 66666667); XTmrCtr_Start(&tmr, 0); print("wait for interrupts\n\r"); for(;;){} return 0; }
コメント