またまたi.MXRT関連の記事になります。巷ではRT人気のようですので、どんどんRTの記事を増やしていきたいと思います。
今回は、システムのファイームウェアアップデートについてです。
現在のシステムを稼働しておきながら、新しいファームウェアをダウンロードしてきて、そのまま新しいファームウェアにパッチっと切り替える要求ってかなりあるんですよね。
でも、これってマイコンに特別な機能がないと、ファームウェアアップデートってかなり面倒臭いし、複雑だったりします。
マイコンのファームウェア(アプリケーション)は、特定のアドレスに配置してフラッシュメモリに書き込みます。
新しいファームウェアも同様のアドレスに配置するようにビルドするため、別のアドレス(下位のアドレス領域)に書き込んでも動作しません。この理由は、プログラムした変数や関数、データは、特定のアドレスに配置してビルドしているので、そのアドレスと異なるアドレスに書き込んでも動作しないわけです。
この記事では、上位アドレスと下位アドレス領域という言葉が出てきます。フラッシュメモリの領域を2つに分けて、アドレスの大きい側を上位側、アドレスの小さい側を下位側アドレス空間とそれぞれ呼びます。
ここから途中読み飛ばしてファームウェアアップデートの方法だけ早く読みたい人は、次の見出し「やりたいこと」までジャンプできます。
コンテンツ
ファームウェアアップデートの方法
下位アドレス領域には現行のシステムが稼働しているので、消去したり書き込んだりすることはできないんです。ま、当然ですね。
消してしまえば当然動かなくなるし、上書きすれば元のプログラムが残らないし。。。
上位のアドレスに新アプリケーション(ファームウェア)を書き込んでもそのままではアドレスが異なるので動作しないわけです。
だから、一旦現行のシステム(ファームウェア)を停止させ、ファームウェアアップデート用のコードをRAMから(または別領域のROMやフラッシュ領域から)実行して、旧システムを削除したのちに新システムに書き換えるということが必要になってきます。
ん〜〜これでは、新しいファームウェアの書き込み時に失敗してしまうと、もう前のファームウェアが消去してしまっていると元に戻れません。
だから、新システムを残しておいて、すんなりと新しいファームウェアにパチっと切り替えたいというニーズがあるわけです。仮に新ファームウェアに問題があった場合でも、前のファームウェアに戻ることができます。
マイコンには、MMU(メモリ・マネジメント・ユニット)が搭載されていないので、実行されるアプリケーションプログラムが配置されるアドレスは、マイコンに集積されているフラッシュメモリの物理アドレスと一致しています。
一方、WindowsやLinuxなどのシステムでは、MMUをサポートしたプロセッサを使っていてマルチタスクが可能になっています。複数のアプリケーション用にそれぞれの仮想メモリ空間(ページ)を持っていて、それらアプリケーションは”見かけ”上、同じアドレス領域で管理・実行されているんです。
MMUが物理メモリ空間を仮想メモリ(ページ)として管理していて、その仮想メモリ空間を複数持ち、それぞれの仮想メモリ上でアプリケーションを並列化して実行しているんです。
だから、LInuxやWindowsは、アプリケーションの並列実行や切り替えなどは簡単でこの仮想メモリ(ページ)を切り替えるだけで済みます。
マイコンの場合は、この仮想メモリ空間を管理するMMUがないので、実際に実行されるアプリケーションのアドレスと物理的メモリのアドレスは同じなんです。だから、複数のアプリケーションを並列に実行したり、同じアドレス空間に複数のアプリケーションを配置するなんてことも出来ないわけです。
でも、もし上位フラッシュメモリ領域と、もう一方の下位アドレスのフラッシュメモリ領域を簡単にパチっと切り替えて、上下領域のフラッシュメモリのアドレスを入れ替えることができれば、簡単にファームウェアアップデートができるわけです。
これができると、次のようなことが簡単にできるようになります。
新ファームウェアをビルドする際に、上位アドレス領域(例えばアドレス0x0~)に配置するようにビルドします。上位アドレス領域にはシステムが起動していて、下位アドレス領域にファームウェアアップデートコード(新システム)のイメージをダウンロードします。
このままだと、下位アドレス領域にダウンロードした新ファームウェアは動作しません。
ダウンロードが完了したら、あとは、アドレススワップ(上下のアドレスの切り替え)して、新しいシステムへ切り替えることが容易に行える訳です。
たとえばi.MXRT1020やi.MXRT1015などはサポートされていません。
では、早速、このアドレスマッピング機能の説明をしていきます。
やりたいこと
2つのアプリケーション(新旧のファームウェア)を切り替える
使用するハードウェアとソフトウェア
i.MX RT1060-EVK
SDK_v2.8.2_imxrt1060 (2020年8月23日現在)
参考になる情報(英語)
i.MX RT1060 アプリケーションノート
AN12255 How to Use Flash Remapping Functionこのアプリケーションノートのソフトウェア
AN12255SWアドレスリマッピングの仕組み
RT1060のアドレスリマッピング機能は、FlexSPIインターフェースに組み込まれているアドレスのオフセット機能により実現する仕組みになっています。

この図に示すように左側がアドレスリマップ前、右側がリマップ後です。リマップ機能は単純にアドレスリマップのスタートアドレスから指定したアドレス分だけズラす機能です。
このオフセット機能を使ってファームウェアのアップデート方法を説明します。
条件
以下のような条件で説明していきます。
ここでは以下のような領域およびイメージサイズを想定
フラッシュメモリサイズ:任意
領域1:0x6000_0000 ~ 0x6010_0000(1MB)
領域2:0x6010_0000 ~ 0x6020_0000(1MB)
オフセット:0x10_0000(1MB)
尚、ここでは、領域1および領域2のサイズ、イメージサイズは<1MBとしているが、外付けフラッシュROMサイズは任意に変更可能で、またそのときの領域をそれぞれ512kBなどとすることが可能。
ファームウェアアップデートの方法
現行システム(ファームウェア)が領域1に格納・実行されている場合

- ファームウェアアップローダをRAMへ展開し、RAMから実行(ジャンプ)
- 領域2を消去(イレース)
- 領域2に新ファームウェアを書き込み
- IOMUXC_GPRレジスタを設定し、アドレスを領域2にオフセットする
IOMUXC_GPR_GPR30 = 0x6000_0000
IOMUXC_GPR_GPR31 = 0x6010_0000
IOMUXC_GPR_GPR32 = 0x0010_0000 - PORリセットし、領域2からシステムが起動
この一連の処理は、RAM内に展開してRAMへ実行を移します。
現行システム(ファームウェア)が領域2に格納・実行されている場合

このケースは、一度ファームウェアをアップデートして領域2から実行されているケースで、さらに新しいファームウェアをアップデートする場合に、領域1の古いファームウェアと新ファームウェアを入れ替えて新ファームウェアを稼働するケースです。
- ファームウェアアップローダをRAMへ展開し、RAMから実行(ジャンプ)
- IOMUXC_GPRレジスタをリセット
IOMUXC_GPR_GPR30 = 0
IOMUXC_GPR_GPR31 = 0
IOMUXC_GPR_GPR32 = 0 - 領域1を消去(イレース)
- 領域1に新ファームウェアを書き込み
- PORリセット、領域1からシステムが起動する
以上でファームウェアのアップデートが完了します。
どうですか? 超~~簡単ですよね。
最後に
今回はi.MX RT106xを使用して説明しました。これと似たような機能でLPC55xxでもアドレスオフセット機能をサポートしているので、同様のことができます。