ガレスタさんのDIY日記

電子回路、Web、組み込み、自作エフェクターを語るblog

i.MX RT1050 : XIPで起動する

題名にある通り今回はXIP機能を使って外部のHyperFlashからプログラムを実行して行く

実習環境

  • MIMX RT1050-EVK(OpenSDA firmwareは最新のものでHyperFlash版にアップデートしたもの)
  • MCUXpresso IDE(10.1.0_589)
  • MacbookPro 2012 (MacOS HighSierra)

XIP(eXecute-In-Place)

Application eXecute-In-Place (XIP) with Linux and AXFS | Random Access Memory | Computer Data Storage
より

XIP, or eXecute-In-Place when written out, isa technique of directly accessing application code and data in non-volatile flash memory rather than transferring it to physical RAM first in order for an execution to proceed. It is frequently used in the contexts of embedded computing.

とあるようにRAMに転送することなく、不揮発性フラッシュメモリから直接アクセスする技術のことを指す。

利点としてはRAM展開しないことで手順を省ける。
欠点は安直にいうと速度の面で劣るという点である。
QSPI,HyperBusを使うと結構早いので最高速アクセスではないと補足しておくがコアクロックが600Mhzとかになってくると話は別になる。
クリティカルなリアルタイムコードとかになってくると密結合メモリへの配置が必須になってくる場合もある。

i.MXRT1050のブートについて

i.MX RT1050は以下に示すように様々なブートに対応している。

  • Serial NOR Flash via FlexSPI
  • Serial NAND Flash via FlexSPI
  • Parallel NOR Flash via Smart External Memory Controller (SEMC)
  • RAWNAND Flash via SEMC
  • SD/MMC
  • SPI NOR/EEPROM

各種アドレスは下に示す通りです。

Start add End add Size Description
0x80000000 0xDFFFFFFFF 1.5GB SEMC(外部RAMコントローラ)
0x60000000 0x7F7FFFFF 504MB FlexSPI
0x20200000 0x2027FFFF 512KB On Chip RAM
0x20000000 0x2007FFFF 512KB DTCM
0x00000000 0x0007FFFF 512KB ITCM

下から三つのOn chip RAM,ITCM.DTCMはFlexRAMであり自由に容量を割振れるRAMなので各種512KBづつあるわけではないので注意
FlexRAMについてはNXPのドキュメントAN12077を参照されたい

今回は青で示したFlexSPI経由で起動する流れを取る。

BOOT MODE

BOOTMODEはピンで設定をして行く流れとなる。

BOOT_MODE[1:0](評価ボードのSW7-3,SW7-4) BOOT Type
00 Fuseから起動
01 シリアルブート(USB,UART)
10 内部ブート(内部bootROM)
11 予約済み

ここでFuse起動は内部ブートと似ているがGPIOでのboot設定は無視されてeFUSEを参考に起動する流れ(結構特殊なので基本は10でいいんじゃないかなと思います。
最終的なDIPスイッチ設定はこのようになる。

SW7-1 SW7-2 SW7-3 SW7-4 BOOT Device
0 1 1 0 HyperFlash
0 1 1 0 QSPI Flash
0 1 1 0 SD Card

HyperFlashで起動したいので0110に評価ボードのDIPスイッチ(SW7)を設定してください
これでブートの説明は以上になるがブータブルイメージの構成やIVT(image vector table)データ構造体やBOOTDATAだったりの話があるのでかなり端折っている。

プロジェクトを用意する。

前項まででブートの軽い説明とボード状のDIPスイッチをいじったので次はプロジェクトを作って行きます。
一からnewprojectしてもいいですがコードにはできるだけ触れたくない(GPIOの説明とかで脱線したくないため)のでSDKサンプルをXIP向けに変えて行きます。
import sdk sample からledチカのプログラムを選択する。
f:id:gsmcustomeffects:20180107013827p:plain
あとは流れに沿ってFinish そのあと一旦コンパイルしてビルドが通ることを確認する。

メモリコンフィグの編集

案の定RAMリンクなプロジェクトなのでEXT Flashの宣言がない・・・・・
f:id:gsmcustomeffects:20180107015927p:plain

そこでFlashを追加する。
location:0x60000000,Size:0x400000,DriverはMIMX
f:id:gsmcustomeffects:20180107020049p:plain

XIPファイルの追加

プロジェクトエクスプローラーの上の方の十字みたいなのをクリックします。
f:id:gsmcustomeffects:20180107020756p:plain

XIPを選択して追加する。
f:id:gsmcustomeffects:20180107020934p:plain

XIP_EXTERNAL_FLASHシンボルを追加する

Properties/C/C++ Build/Setting/PreprocessorからXIP_EXTERNAL_FLASHマクロを追加
f:id:gsmcustomeffects:20180107021626p:plain

restore linkage to flash(RAM向けからFlashへ)

Properties/C/C++ Build/Setting/Managed Linker Script
Link application to RAMのチェックを外す
f:id:gsmcustomeffects:20180107021942p:plain

あとはリビルドしてデバッグする。

XIP起動

このようにプログラムカウンタが0x60000000番台に来てればOKです。
f:id:gsmcustomeffects:20180107022354p:plain

できなければ下部にあるトラブルシューティングを参照してください。

まとめ

  • XIPで起動できた
  • ブートの知見を深めたので今後はRAM移動への知見を深めて行きたい。

Troubleshooting

デバッガが繋がらないときはOpenSDAのファームウエアの更新をしてください
OpenSDA Serial and Debug Adapter|NXP

それでも繋がらない場合はフラッシュの消去を行う

まずボード状のブートスイッチ(SW7)をHyperFlash以外の設定にして電源を落としてつなぎ直す

LinkserverGUI Flash Programmerを開く(上のアイコンメニューのチップみたいなやつをクリック)
f:id:gsmcustomeffects:20180107022804p:plain
Mass eraseかける。
SW7を元に戻す。

再度debugする。