MMUを活用して、システムの性能向上と安全性を保つ
「システムが暴走してRESETしなければいけなくなった」という経験は誰にでもあるかと思いますが、組み込みシステムでは、そのリスクを限りなく0にする必要があります。WDTなど周辺機能がサポートしてくれることもありますが、その時点で中核となるソフトウェアが停止してしまっている状況は、誰にとってもメリットは少ないものです。
唯一のメリットは、システムにRESETがかけられるということになるでしょうか。もっと事前に分かればいいのに・・・。そういう状況はよくあるものです。今回の講座では、そういった状況に陥る前に、設計段階でできることを解説します。
今回の主役は、「MMU(Memory Management Unit)」です。MMUは、実際のメモリ空間(物理アドレス)と論理的なメモリ空間(仮想アドレス)の置き換えをサポートすることと、キャッシュを使えるようにしてくれることが、主な役割です。MMUの具体的な設定は、こちらが参考になります。
組み込みシステムでさらなる性能向上を目指す際には、是非キャッシュを有効活用したいところです。そのためには、今回説明するMMUの設定が必要になってくるのです。
キャッシュ
キャッシュはCPUとメモリの間に入っている高速なメモリブロックです。パソコンで使われるようなCPUにはほとんど搭載されています。組み込みシステムに使われるプロセッサも例外ではなく、容量の差はあるものの、キャッシュを搭載しているデバイスがほとんどです。
キャッシュのメリットは、その高速性能にあります。キャッシュメモリ内に収まる程度のプログラムであれば、CPUおよびデバイスの性能が100%発揮されます。
しかし、キャッシュには収まらないほどの大きなデータを扱ったり、ネットワークから送られてくるパケット処理が多かったりすると、キャッシュを有効にしてもその恩恵は少なくなります。ですが、キャッシュが無効のままでは本来の性能も発揮されず、期待していたパフォーマンスを引き出せません。
せっかくマイコンからプロセッサにアップグレードしたのに、性能差が少ししか向上しなかった・・・という残念なコメントはいただけません。そうならないためにも、キャッシュを搭載しているCPUを使ったシステムであれば、迷うことなくキャッシュを有効にしましょう。
MMUの設定
さて、ここで問題になるのは、キャッシュを有効にする時は、MMUを有効にしないといけないということです。MMUを有効にすると、アプリケーションプログラムは物理アドレスに直接アクセスすることができず、論理アドレスを使わないといけません。
さらに、論理アドレスにするということは、データシートに記載してあるレジスタのメモリマップをそのまま読み替えることができなくなります。
「じゃ、物理アドレスと論理アドレスが同じならいいんじゃないの?」
そうなんです。同じにすればいいんですが、今回使用しているSOLIDには、アドレスサニタイザという機能を有効にするために、あえて論理アドレス=物理アドレスにしない方法を取っています。これはLinuxなどでは一般的な手法です。だからLinuxや大きなシステムでは、デバイスドライバが必要になります。
そこで、今回使用する Cortex-A9コアのMMUを設定するには、「CP15というレジスタを介して、アドレス変換のためのディスクリプターに、属性とかアドレスを設定して・・・」というアセンブラコードを初期化処理の際に、記述しなければいけないのです。
かなりの難関が待ち構えているように思えますが…
安心してください。
ワタクシが解決する手段をお教えします。
SOLID-IDEの機能のひとつである「メモリマップデザイナー」です。
メモリマップデザイナー
メモリマップデザイナーは、SOLID-IDE上から使用可能なMMUのメモリマップをGUIで設定できるツールです。メモリマップデザイナーでは、物理アドレス、論理アドレス、メモリサイズ、メモリのタイプをGUIで設定可能です。
メモリマップデザイナーはCPUの初期設定時に使用されるのですが、メモリマップ用のAPIが用意されているため、アプリケーションが動いてからでもAPIで設定状況やキャッシュの操作など、きめ細かな制御が可能になります。
また、物理アドレスと論理アドレスが一覧できるため、デバッグ時に物理アクセスに対するアクセスを行いたい時など、論理アドレスの対応が一目でわかるので、期待通りのレジスタアクセスが可能です。MMUが有効になっても、期待通りの動きが確認できるのは、とても安心ですね。
SOLIDでは、RTOS向けの開発プラットフォームなので、リアルタイム性の確保が難しくなるスワッピングを要するような多重空間を使用しないよう、単一空間へのアサインをしています。
もう一つメリットがあります。
MMUを有効にしていると、アプリケーションが何らかの原因でスタックオーバーフローを起こしたり、何らかのメモリ障害を引き起こした際、その時点で停止することが可能になります。そのため、装置全体が暴走して止められなくなる前に、問題がある箇所でプログラムを停止させ調査することが可能です。
SOLIDでは、RZ/A1Hに搭載された10MBのRAMを、こういった機能に一部活用しています。またこれらのプロテクション機能の他に、アプリケーションのタスクがメモリ障害を引き起こしそうになると、今後後述するアドレスサニタイザ機能で、問題が発生する前にキャッチすることができるようになります。
IoTに関連する製品開発が増えてきた昨今、外部からのセキュリティもさることながら、内部から保護することも重要なのではないかと考えます。その一つが、メモリのプロテクション機能であるMPU(Memory Protection Unit)です。この機能も機種依存はあるものの、MMUで設定する項目に似ていますので、一度わかれば簡単です。ぜひ、合わせて覚えておきたいところです。これらを使いこなして、安全な組み込みシステム開発を進めていきましょう。
静的解析ツール
SOLID-IDEのコンパイラは、静的解析ツールをサポートしています。静的解析は、コードをコンパイルした時に、エラーを引き起こしかねないコードを事前にチェックできる大変便利な機能です。
コンパイル結果でワーニングやエラーが出た時は、修正したくなるものですが、コード入力中は案外気付かないものです。SOLID-IDEの静的解析ツールは、コンパイラベースなので解析時間も短く、メニューから簡単にその結果を表示し、素早く該当箇所にアクセスすることができます。
静的解析ツールもMMUも、デバイスが持っている機能とツールによる機能を十分活用し、より安全でセキュアな組み込みシステムアプリケーションを構築しましょう。
参考リンク
SOLID Starter Kit for RZ/A1H
今回使用するSOLID Starter Kit for RZ/A1Hは、評価ボード、デバッガ、IDEなどが、すぐに使えるAll in One Packageになっています。
“SOLID”は、コンパイラ、RTOS、デバッガ、IDE全てが含まれ、またそれぞれが専用設計された、京都マイクロコンピュータの組み込み向けソフトウェア開発プラットフォーム。ITRONベースでありながら、本格的なプログラムローダーや、バグの実行時自動検出機能などを搭載します。
最新情報をメーカーサイトで見る
Amazon.co.jpで買う
こちらも是非
“もっと見る” Cortex-A+RTOS編
ローダーを使いこなして、分割開発の悩みを解決
組み込みシステムにおけるローダーとは、電源が入り、RESET信号が解除されて動き出す最初のプログラムです。ローダーの役割は、プログラムをメモリ上に読み込むためにメモリコントローラの初期化を行い、プログラムが保存されているフラッシュメモリからSRAMやDRAMなどのメモリに展開して実行するまでの動作を行います。
デバッグの効率化とRTOSタスク実装
組み込みアプリ開発において、リアルタイムOS(RTOS)を使うメリットをこれまでに十分説明してきました。今回は、いよいよタスクの実装です。組み込みアプリを構築する上で、最も重要な部分です。使用する「SOLID-OS」は、Toppers/ASP3をベースにしたμITRON準拠のRTOSです。
デバイスドライバの役割
組み込みシステムのアプリケーションを作っている場合、CPUの機能だけを使うことはほぼないと言っていいでしょう。通常、ハードウェアの操作を行うために用意するソフトウェアを「デバイスドライバ」と呼んでおり、パソコンなどでも頻繁に利用されています。