CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

割込み処理(2)

ブート部分、ベクタテーブル、アプリケーション全てを1本のアセンブラで記述すればこのような面倒くさいことしなくてもよいのですが、いちおうCで開発した場合の走行環境はあったほうがよいでこういうことになっています。

 

サンプルプログラムとしてタイマ割込みによるLEDチカチカを作ってみました。

まず、ADSP-2101に内蔵されたタイマは以下のような構成になっています。カウントレジスタTCOUNT(16)、周期レジスタTPERIOD(16),プリスケーラTSCALE(8)の3本のレジスタが見えます。

f:id:O3I:20210801084143j:plain

 

これらのレジスタへの書き込みや割込み環境のセットアップはランタイムライブラリに組み込み関数として用意されていてCでの記述はとても簡単でできてしまいます。

ここではタイマをTCOUNT=TPERIOD=51199、TSCALE=191に設定しているので、原振CLKOUT=9.8304MHzは(TPERIOD+1)*(TSCALE+1)=9,830,400分周され、ちょうど1Hzでタイマ割込みが発生します。

interrupt()関数は割込みサービス本体timer_handler()関数へのポインタを引数に持ちベクタを設定し、そのtimer_handler()は大域変数cntをインクリメントさせているだけです

f:id:O3I:20210801084156j:plain

メインルーチンではcntの値を常時LEDに出力する永久ループとしていますが、これを実行させるとLEDが1秒おきにインクリメントするので割込み処理が正常に動いていることが確認できました。割込みハンドラには返値も引数も不要なのでvoid func(void)でよいはずですがinterrupt()関数のプロトタイプ宣言が何故か

void (*interrupt(int, void (*func)(int)))(int);

になっていてint型の引数を持たないとwarningが出るので一応ダミーを付けています