AVR32のMPUドライバの例題を使ってみる(その1)

「Memory Protection Unit」のことであって、世間一般の「Micro Proccessing Unit」のことではない(私は初め間違えた)。MPUは、MMU(Memory Management Unit」の簡略版の位置付けで、仮想記憶まではサポートしていない。またMMU同様、CPUに近いモジュールのため詳細は、製品マニュアルではなく、アーキテクチャ・マニュアルの方に掲載されている。仮想メモリが使える訳でもなく、ちょっとした組み込みではあまり使う意義を感じないが、不要なアクセスを検知してデバッグが進むなり、実製品で暴走を検出してフェイル・セーフ処理ができるならいいかなと考えている。
だが本来アクセス可能な場所を防御してしまい、要らぬバグを埋め込む可能性もある。自作するとバグを作り込む可能性もあるし、余計な時間も掛けたくない。
そこでAT32UC3 Series Software FrameworkのMPUドライバを試してみたい。メーカのドライバだと、芋づる式にいろいろ取り込む必要が出てくるかもしれないが、MPUだから初期化と例外処理くらいなので依存性は低いだろう。
実ボード/デバイスは、いつも通りEVK1101AT32UC3B0256
AVR32 Studio自身がMPUドライバと例題(EXAMPLE)を持っているのでこれを利用する。



MPUの概要(「5.2 Understanding the MPU」から)。

  • 8つのプロテクション・リージョンを持ち、
  • リージョンの開始アドレスとサイズで指定し、
  • 異なる特権レベルを設定する。
  • 異なるアクセス・パーミッション/キャッシュ有無/バッファ・レジスタを持つ。
  • リージョンは4kB〜4GBのサイズであり、必ず2のべき乗である。
  • すべてのリージョンは開始アドレスを持ち、リージョン・サイズに応じてアライメントされている。もしリージョンが8kBなら、bit13未満がすべて0である。
  • 1つのリージョンは、16のサブ・リージョンを持ち、
  • サブ・リージョンのサイズは、リージョンを16分割した256B〜256MBである。
  • MPUにより設定したメモリ・リージョンにアクセスしたとき、ハードウェアは、その中でヒットしたサブ・リージョンを決定する。この決定に使用される情報は、サブ・リージョンのアクセス許可がレジスタ群MPUAPRA/MPUBRA/MPUCRAかMPUAPRB/MPUBRB/MPUCRBで与えられている(訳注:レジスタMPUPSRnで選択)。
  • どのリージョンにもアクセスがヒットしないなら、アクセスは中断され、例外が発生する。



AT32UC3 Series Software Frameworkのダウンロードはここから。今回使用したのは「AVR32 UC3 Software Framework 1.5.0」である。

ドキュメントは、AVR32 Studioの「Help」→「Help Contents」でヘルプを開き、「AT32UC3B Software Framework」→「Drivers」→「CPU」→「Memory Protection Unit」と辿ればよい。いちおうフッタにあるバージョンを確認すること。現在のFramework最新版は「1.5.5」だ。

MPUドライバの例題プロジェクトを作成する。

  1. AVR32 Studioのメニュー「File」→「New」→「Example」を選択。
  2. まずは「Wizards」に"EVK1101"と入力し、候補を絞り込む。
  3. "EVK1101 - DRIVERS - CPU MPU example"を選択し、Nextボタンを押す。
  4. 適当なプロジェクト名を「Project name」に設定、残りはお好みで、Finishボタンを押す。

出来上がったプロジェクトのsrcフォルダ以下を見ると、思った以上に余計なものが取り込まれている。例題が要求するのか、MPUドライバが要求するのか、見分ける必要がある。

ソースファイル名 mpu.cからの依存性 説明
crt0.x × 通常のC言語スタートアップ・ルーチン
gpio.c × mpu_example.cから利用。LED点灯に使用されている。led.cを使えばいいのに。
intc.c × 汎用的な割込処理
led.c × LEDボード・ドライバ。例題で使用。
mpu.c MPUドライバ本体。関数呼び出し無し。
mpu_example.c この例題のmain処理。関数handle_exception(例外処理本体)もここにある。
mpu_exception.x exception.cの変更版(exception.xは使用されない)。64〜69行目が0x100未満のハンドラ、71〜79行目が0x100(supervisor call)のハンドラの二種類が登録されている。いずれも関数handle_exceptionを呼び出す。
pm.c × mpu_example.cの中でクロック源を外部クリスタルに切り替えるため、利用している(必要なのか?)。
pm_conf_clocks.c × pm.cの使用法を簡素化するものだが、どこからも使用されていない...
print_funcs.c × print関数群。USARTドライバ上位のデバッグ・モジュール
trampoline.x × リセット・ハンドラ
usart.c × USARTドライバ。例題で使用。

依存性はほとんど無いといっていいだろう。mpu_example.cはmpu.cの使用方法を示すものだし、mpu_exception.xは例外処理本体であり、アプリ毎に変わるだろう。
つまりMPUドライバは単独利用できると言える。



「AVR32のMPUドライバの例題を使ってみる(その2)」へ続く。