STM32F7を使ってみる5 -AXIMとITCM-

STM32F7の内蔵フラッシュメモリは以下に示す2系統のインターフェースで命令
コードを読み出し実行することが可能です。

The AXI-Master (AXIM) interface

TCM Interface

Embedded Workbenchマニアのページさんの記事を参考にして私なりに両者の
性能の違いを確かめてみました。また、各モードで上手く使いこなすための
コツも紹介します。


●AXIM経由のフラッシュ
こちらはCubeF7の各種サンプルプログラムでデフォルトで使用されているスタン
ダードなものです。フラッシュメモリのアドレスは0x08000000に配置されており
過去のSTM32シリーズと同様の感覚で使用できます。
フェッチされた命令はCortex-M7コア内のI-Cacheを有効にしていればフラッシュ
のアクセス速度の遅さを補うことができますのでフラッシュの素のアクセス速度
の遅さを気にせず過去のSTM32シリーズとほぼ同様に使用することができます。


そんなわけで早速表示です。SDRAMのタイミングを正しい値に修正したこと以外は
前回お見せした対策その1と同じ構成です。


●ITCM経由のフラッシュ
ITCMバスにはF2/F4シリーズでおなじみのARTアクセラレータが乗っかっています。
I-Cacheは経由しませんがアクセラレータのおかげでフラッシュの素の(ry
ちなみにITCM経由のフラッシュアクセスの場合、アドレスは0x00200000に配置され
ている事になります。ITCM経由で動かしたい場合はリンカスクリプトの開始アドレスを
0x00200000にしましょう。


なんとこちらの方が高速です!Embedded Workbenchマニアのページさんでも述べられ
ているとおり
AXIM経由の場合はフラッシュの命令の他に様々なペリフェラルが行き
かっているので命令はITCMに押しやるのが本来取るべきスジなのでしょう。


●ITCMるコツ
上記の結果だけ見るとAXIMのメリットないじゃんてお思いの方が多いと思います。
残念ながらITCMも結構ピーキーな性質でスムーズに開発を行うために知っておかな
ければならないいくつかのコツがあります。

1.ITCMのアドレスではDMA出来ない
 RMを読む限りではバスがDMAコントローラのどこにもつながってないのでこの
 アドレスではDMAが一切出来ないと思います。DMA元にconstを決め打ちする
 ような転送ではHardFaultになって失敗するでしょう。
 もちろんITCMバスにぶら下がっているITCM-RAMもDMA不可能です。
 このへんF4のCCMと同じ位置づけですね。
2.フラッシュは0x08000000に焼く
 ITCMから見えるフラッシュのアドレスは0x00200000ですがそのアドレスには
 フラッシュメモリの実体はなく、過去のSTM32シリーズと同じ0x08000000に
 あります。0x00200000に無理やり書こうとしても弾かれます。
 
 ↑こんな風にエラー出て駄目です。
 したがってOpenOCDではhexやelf形式のフラッシュ書き込みは100%失敗しますので
 binファイルを0x08000000に向かって書き込むようにしましょう。
 
 makefile上ではこんな感じです。9/Sにリリースする新版のいつものではフラッシュに
 ITCMを選択すると必ずbin形式で書き込むようにmakefileをいじって置きますので
 ねむいさんと同じ開発スタイルの人は特に気にせず快適に書き込み&デバッグが
 できると思います★

 おまけです。
 
 ↑AXIMで動かしてる時のデバッグ画面。
 
 ↑ITCMで動かしているときのデバッグ画面。PCの値に注目。

 F7シリーズはBOOT0の状態で起動できるアドレスの番地が可変になりましたが、
 デフォルトではフラッシュメモリからブートする場合、ITCMインターフェースの先頭
 0x00200000から開始になっています。AXIMでもきちんとスタートアップを記述
 していれば0x08000000の番地にすぐに飛んでくれるので問題ありません。



・・・徐々に、そして確実にSTM32F7の真の力が明らかになってきています。
今までの私の使ってきたワンチップマイコンの概念のままでは到底その力を引き出す
ことはできないでしょう。しかし私はそれに臆さずどんどん新しい概念に切り込んで
いきたいと思います!!

Comments

はじめまして。
興味深く拝見しております。
当方、AtmelのCoretex-M7 SAMS70をミュージックシンセに組み上げようとしております。
以下、不躾な質問で申し訳ありません。
キャッシュのことなのですが、
CMSISにSCB_CleanInvalidateDCache_by_Addrという関数がありますが、KeilのHPにあります。
これは特定の領域をキャッシュ無効にできるというものなのでしょうか?
シンセサイザーの場合、CPUは、波形データを吐きだす(書き込む)ばかりですので、
キャッシュ無効でもいいのか?あるいは、もっといい方法があるのか探ってみたいです。
DMAはSRAMに書かれた512ロングワードのデータを44.1KHzのサンプリング周期でI2Sに転送していきます。
バッファはピンポンバッファになっていて、11.6mS周期のDMA転送のたびに切り替えるようにします。
コンパイラーはKeil MDK μVisionFree版です。

p.igmon様はじめまして、ねむいです。

ATMEL系はAVRとXMEGAしか全く知らないのですがコアとしては
一緒のはずなので分かる範囲でお答えします。

SCB_CleanInvalidateDCache_by_AddrはD-Cacheの一ライン
(Cortex-M7では32バイト単位)ごとにinvalidateしてcleanする
関数です。invalidateはキャッシュそのものを無効化するのでは
なく"内容"を無効化します。

DMAする際にはちゃんとメモリのサイズやアライメントを考慮
していないとこれを行っていても関係ない領域まで破壊される
ので細心の注意を払ってください。

一方で速度の低下を受け入れてD-Cacheそのものを特定のメモリ
領域で無効化したい場合はMPUから無効にする領域を設定します。
ただし設定できるメモリ領域の範囲はそれほど細かく指定できない
のである程度妥協が必要です。

私としましてはキャッシュの影響を受けないDTCMをDMA用に確保する
ことを考えます。特にATMEL系はDTCMのサイズをユーザーレベルで
変えられますのでつぶしが利くはずです。

TCMに転送バッファを置くのが良さそうなこと、ご指摘ありがとうございます。
CPUが届くのはまだ先のようですが、Atmelのほうですが、TCMメモリのサンプルプログラムがあり、
これらをコンパイルして、メモリMAPを確認してみます。

Post a Comment








Go to top of page