AVR32の割込って...遅い?

最近徐々にマニュアルの周辺モジュールを読み始めているのだが、やはりAVR32って割込が遅いようだ。割込や例外が発生して、ハンドラ先頭命令が実行されるのは早いのだが、ハンドラ本体処理に至までが長いのだ。ソフトウェアにより割込グループと割込ラインを判定し、2段階構成で割込要因を確定するからであると、これまで書いたがこれはINTCモジュールに限った話でまだ先がある。
割込ラインは各モジュール毎に来るので、そのモジュール内でどのような割込要因が発生したかは判らない。モジュール内のステータス・レジスタを評価する処理が必要となり、トータルすると3段階の手間が掛かる訳だ。
具体的には、USARTならUSART0〜2毎に割込ラインがあるが、各USARTの受信バッファ・フルなのか送信バッファが空なのか、はたまた通信エラーなのかは別途ステータス・レジスタ(CSR)を見て判断しなければ判らない。しかもこれがまたビットフラグだったりする。
ビットフラグなら割込ラインを調べるときのように、clz(Count Leading Zeros)命令を使用すればよいと考えるかもしれないが、この命令を使うには問題がある。割込ラインを調べるときも同様に問題だが、優先度の高い順にビットフラグが並んでいるとは限らないのに、clz命令でmsb側からチェックするため、システム仕様から見たとき優先度が低いものを選択してしまうことがある。
USARTの場合、途切れなくデータを送受信するためにCSR(USART Channel Status Register)のTXBUFEビット(bit11)やRXBUFF(bit12)、その他をチェックする必要があるが、それよりmsb側にCTSビットがある。CTSCTS信号ラインをモニタするためのもので、セットされている可能性が高い。では、上位ビットをマスクすれば良いかというと、下位ビットにあるエラー関係のビットを優先的にチェックする必要がある。従って一般的には

  1. エラー関係以外のビットをマスク&評価して、0でないなら、各ビットからエラー原因を特定し、エラー処理に入る。
  2. 上記で0なら、送受信関係のビット以外のビットをマスク&評価して、各ビットから受信or送信を判定し処理する。
  3. いずれでもなければ、何も処理せずreteする。

ということになる。ちなみにマスク&評価するとき、and(cond4付き)命令はステータス・フラグが変化しないので、and(shift付き)かandh/andl命令を使用すべきである。



割込要因毎にハンドラ・ベクタ・テーブルを持つ一般的な組み込みMCUなら割込処理本体直前までを省けるが、AVR32ではソフトウェアによる逐次処理がたくさん必要となり、結果的に割込処理応答が遅くなるだろう。
ハンドラ・ベクタ・テーブルを持つMCUだと、割込優先度が固定化されているため、ソフト側で優先度を変更する余地は無いが、一方で割込要因と優先度の判定が不要で高速化できる。
AVR32では、ソフトで割込要因と優先度を判定するため、速度が遅い反面、柔軟であるとも言える。ハードが簡潔になりコストが安くもなる。ただ、割り込み応答が少しでも早くなるような配慮が無いところが残念だ。USARTの話に戻れば、ステータス・レジスタを外部信号モニタと割込に分割するとか、一般的な割込優先度に応じてmsbからフラグを割り当てるとかやりようはあるはずだ。clz命令の結果がそのままインデックスとして使える。
各モジュールのステータス・レジスタを眺めると、下位ビットを利用しているようだが、イミディエイトによるコンペア命令を意識しているのだろうか?それならclz命令ではなく、ctz(Count Tailing Zeros)命令が欲しかった。

USARTを例にして割込処理が遅くなる話をしたが、USARTやSPI,TWI等の転送系モジュールについては心配する必要はない。AT32UC3B0256系ではPDCA(Peripheral DMA Controller)が7つもあり、CPUに対する割込を低減できるからである。USARTなら割込要因のチェックがエラー系統のみに絞り込める。USBにはPDCAとは別のDMAが付いているようだ。
一方、割込応答が遅いということは、TC(Timer/Counter)やPWMにおいて周期を短く取れないということである。出力面ではそれほどネックにならないが、インプット・キャプチャになると、要求仕様に対応できるかよく検討する必要がある。
またTCからPDCAを起動できないのも注意が必要だ。

2009/11/29 追記
私がPDCAについて勘違いをしているようだ。
PDCA(Controllerのこと)は1つであり、実際に転送作業するPDCが各モジュールUSART1, USART0/2, SPI, SSC, TWI, PWM, ADCにそれぞれ付いているようだ。
PDCAが7つあるといってもそれぞれ対等に動作するのではなく、担当のモジュールが決まっているようだ。
まだまだマニュアルをよく読む必要がある。