December 04, 2007Super Sylphide 進捗状況(14) -- McBSP(SPI)におけるCPU割込とEDMAの協調製作中のオートパイロットシステムsuper Sylphideですが、DSP上で動作するプログラムのブラッシュアップを進めています。その中でDSPにかかるCPU割り込みが予想外に多く、処理負荷を上げていることがプロファイラによって判明しました。これは以前の記事『DSP/BIOSを利用した割込みMcBSP(SPI Slave)』にもあるとおり、SPIモードで利用しているMcBSPにおいて、4bytesつまり32bits受信するたびにCPUに割込みをかけて受信後の処理をしていたためです。そこで今回はCPU割り込み+CPUに負荷をかけることなくメモリの転送が行えるEnhanced DMA(EDMA)を協調させることによってCPU負荷軽減を目指してみました。 ここで、なぜEDMA単体ではなくCPU割込みと協調なのか、と疑問を持たれる方がいらっしゃるかもしれません。SPIやI2CといったCPUから見れば非常に低速なペリフェラルに対して適用されるDMAは、複数バイトをブロック処理するために使われることが多く、電源ONから電源OFFまでDMAは起動しっぱなし、CPU本体はDMAの起動、停止をいちいち行わない、というのが普通であると思います。特にターゲットとしているDSPのTMS320C6713に搭載されたEDMAは単体でピンポンバッファ(ダブルバッファといったほうが一般的でしょうか)を構成できるので、CPUがEDMAの起動、停止を動作中に変更する必要は全くありません。 ところが残念ながら以前の記事でも書いたとおり、McBSPをSPI互換モード(クロックストップモード)で動作させると、ハードウェアでは複数バイトで意味を構成するフレーム転送がサポートされません。そこでフレームの頭だしをソフトウェアで行うために、CPU割込みが必要となってきます。CPU割込みによって頭だしが行えたらCPU割込みを停止、EDMAを起動して1フレーム分溜まるまでEDMAを動作、EDMAによる1フレーム受信完了後、EDMA終了割込みによってCPU割込みを復活という動作によって解決を図りました。図で示すと、以下のような動作になっています。 このアイデアを実装すると公開中のソースコードのようになりました。この記事を書いている時点でのCVSの管理番号はmain.cpp.1.34です。 最後に、このコードを書くにあたって2点ほど苦労しました。参考になる方がいらっしゃるかもしれませんので記録をつけておこうと思います。 一つはEDMA先がL2キャッシュが効いているCS0上のSDRAMであるため、EDMAを起動する以前にCACHE_wbInvL2()やCACHE_wbL2()によってキャッシュの掃除をしておく必要がありました。これを忘れると、SDRAMに受信内容が書き込まれていなかったり、送信内容が古いままになってしまいます。 もう一つはEDMAとMcBSPの初期化手順です。spra488『TMS320C6000 McBSP Initialization』に厳密な規定があり、これを守らないとEDMAがうまくかかりません。ここには先述のより一般的な使用方法であるEDMAが電源ONからOFFまで起動しっぱなし、というサンプルコードがあり、今回のコーディングはこのサンプルコードをもとに行いました。 ※その後、I/O拡張基板の設計をしました。 コメント
いったん頭だしができた後も継続的にCPU割り込みを使う理由が分かりません。4バイト固定ならDMAで4バイトずつ転送すればいいと思うのですが。 >酔漢さん コメントする
|
スポンサード リンク
|