LPC4330を使ってみる2 -OpenOCDでSPIFI-SPIROMに書き込む-

先日秋月さんからもLPC4330-XplorerLPC1830-Xplorerが販売されたわけですが、
ななんとデバッガハードウエアのULINK-MEもついて6200円ですって!本体+DHLの
送料合わせて1万ちかく払って半分壊れたのよこされた私はなんだったのか!?あと
たった2週間ちょっとまてばULINK-MEゲッツ出来たじゃないか!と悔やんでも仕方が
ないのでホビイストとしては手元にあるものを100%活用していこうと思います。特に大将
からご指名受けてしまい放り投げることもできないのですがFatFs実装はあつをさん
おねがいいたします(パタ


さて、LPC4330-Xplorer上ではSPIFIというインターフェースでマルチチャネルI/O対応
のSPI-ROMとLPC4330とが繋がっています。
LPC4330は起動オプションによりこのSPIFI-SPIROMから直接起動&プログラム実行&
リニアな参照ができるというなかなかニクい機能があるわけですが、内蔵フラッシュを
持たないLPC43xx・LPC18xxはどうにかしてこいつにプログラムを書き込まなければ
なりません。有効と思われる方法は以下の2通り。
1.付属のULINK-MEを繋げてKEILのIDEを使ってプログラムをSPIFI-SPIROMに書き込む。
 ↑ULINK-MEもってないので却下。
2.DFUブートローダー経由でSPIFI-SPIROMに書き込む
 ↑情報が出そろってませんがいずれ試します…。
  RAM上には流せられるのは確認しました。


OpenOCDは実はSPIFI-SPIROMの書き込みにすでに対応していましたもちろん公式
にはコミットはされていないので自分でパッチ当て+再ビルド必須ですが、私の試行した
限りではいい結果を得られたので上述の確実な2通りに"もう一つ"追加したいと思います。

20120927追:
公式のコミットにも上がりました!


今回はこのOpenOCDを使った方法をご紹介します。


●その前にGCCでコマンドラインビルド可能なLチカるプログラムをこさえる
前回の時点ですでにOpenOCDにつなげて最初に書き込まれていたSPIROMの内容
のバックアップは取っていましたが自分でこさえたのをやっぱり書き込みたいよねと
いうことでいつもののLPC4330版を見据えたベース作りを行います。

LPC4330のSRAM+SPIFIの構成は以下の図のようになっています。

LPC4330コアの最大周波数204MHzでアクセスできるLocalSRAMは合計で200kByte
ありますがご覧のとおりアドレスは連続になってはおらず、128kByte・72kByte分で
ぶつ切りとされています(AHBRAMは構成的に64kByte分すべて連続アクセス可能です)。

SPIFIから実行した場合,104(MHz)/2(Byte)の読み取り速度のボトルネックがあります
ので見かけの動作速度は超大雑把に見積もって30MHz以下になっちゃいますが、ひと
まず一番単純な構成でプログラムも組み易いEXECUTE FROM SPIFIなメモリプラン
を構成しLチカプロジェクトを組みました。

…やっぱLocalSRAMはSH2Aみたく1MByteくらいほしかったなーと感じますね。これ
100PinのチップですからSRAMもSDRAMも外に引き出すのがまた面倒ですし。実際に
204MHzの動作速度を生かしつつ何か作ろうと思ったらプログラムは128kByte以内に
必ず納めてフォントやテーブルなどの比較的低速でもよい大容量データは全部SPIFI
にうっちゃる等の工夫が要求されるでしょう。

SPFI-SPIROM上動作版のリンカスクリプトの冒頭はこんな感じになってます。


●OpenOCDで繋げて書き込む
現在のOpenOCD0.7.0では公式のソースにSPI-ROMとNxP固有のSPIFIドライバのパッチ
をあてて再ビルドする必要があります。私のぶろぐ上で提供しているOpenOCDのWin32bit
版バイナリ
はこのパッチを適用しています。(下述の書き込みスクリプトも同梱してます)

今回使用するデバッガハードウエアはJTAGKey2Cloneとします。後述しますがLPC4330
のエラッタにより外部リセットの直接操作が非常に重要となるのでリセット(SRST)が使える
ブツが必須です。
それとお気の毒ですがULINK-MEはOpenOCDにハードウエアレベルで対応していない
ので、一切使えません(ファームを書き換えた初代ULINKだけ可能です)!


さて、いよいよSPIFI-SPIROMにプログラムを書き込みます。SPIROMの消去を含む操作を
するためにはFlashのプロテクト解除を必ず行う必要がありました。これを省くと書き込み時に
エラーを返されて失敗します。

↑20130814追:少し前のコミットで修正されました。

↓書き込み時のメッセージは以下のようになります。
 書き込み直後にSRSTを直接操作して外部リセットを2度かけています。
> "C:¥Devz¥Coreutils¥bin¥make.exe" program
openocd -s C:/Devz/ARM/OCD/tcl -f interface/ftdi/jtagkey2.cfg -f target/lpc4330_xplorer_spifi.cfg -c "mt_flash_bin main.bin 0x14000000"
Open On-Chip Debugger 0.7.0-dev-00001-ga4830e7-dirty (2012-09-24-10:03)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
cortex_m3 reset_config sysresetreq
trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain
adapter speed: 2000 kHz
Info : clock speed 2000 kHz
Info : JTAG tap: lpc4330.m4 tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : JTAG tap: lpc4330.m0 tap/device found: 0x0ba01477 (mfg: 0x23b, part: 0xba01, ver: 0x0)
Info : lpc4330.m4: hardware has 6 breakpoints, 4 watchpoints
Info : lpc4330.m0: hardware has 2 breakpoints, 1 watchpoints
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x21000000 pc: 0x10000428 msp: 0x10091fe8
background polling: on
TAP: lpc4330.m4 (enabled)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x21000000 pc: 0x10000428 msp: 0x10091fe8
Info : Found flash device 'sp s25fl032' (ID 0x00150201)
cleared protection for sectors 0 through 63 on flash bank 0
auto erase enabled
wrote 65536 bytes from file main.bin in 1.062507s (60.235 KiB/s)
shutdown command invoked
Polling target failed, GDB will be halted. Polling again in 100ms


なんでわざわざSRSTを直接いじっているかというとLPC4330-Xplorerに乗っかってる
チップのリビジョンは内蔵されたSPIFI-ROMドライバがPOR後の外部リセットした後の初期化
で必ずコケて次の外部リセットで正常に動くというイミフなerrataに起因してます。
こいつのせいで今までうまくいった正攻法が全く通じずワークアラウンド満載な
書き込みスクリプトにせざるを得ませんでした。
まぁ結果的に安定したからOKということにしましょう。因みSRSTを繋げてなくてもSWD
接続のversaloonやSTLink/V2で書くことはできますが、この場合いちいち主電源を入り
切りする必要が生じ面倒です。

また、デバッグ中に変なステートに落ち込んでJTAGのアクセスが一切不能に陥ることも
あります。この場合はディップスイッチでブート方法を別の経路にして電源を入れ直すと
ひとまずJTAGで繋がるようになるので落ち着いてSPIFI-SPIROMの内容を全消去して
ください(その後はブート方法をもとに戻すのを忘れずに)。


●OpenOCD+Insightでデバッグ

最後の仕上げにOpenOCD+Insightでソースコードデバッグできる環境も作りました。
こちらもワークアラウンド満載でgdbにattachしたときにsoft_reset_haltをかけてプログ
ラムの先頭で停止するようなトラップを仕掛けてます。

SPIFI-SPIROM上のプログラムを直接参照できるのでとてもありがたいですね♥
もちろんいつものIOViewでGPIOのビットの状態も一目でわかります♥
ちなみにGPIOの初期設定の時にInputBufferを有効にしておかないとピンの状態が一切
読めませんのでご注意ください!(普通のプログラムでも引っかかりやすいポイントです)


●SPIFI-SPIROMからブートしてSRAM上で実行してみる

SPIFIから実行すると大幅にパフォーマンスが下がってしまうので実際に使えるレベル
で試用するならばLocalSRAMからプログラムを実行する必要があります。SRAMの構成上
プログラムと初期設定値があるデータと合わせて128kByte以内に収めないといけない
制約が出来てしまいます。したがって大容量のフォントorデータテーブル等はSPIFI
におきっぱにしておくべきです。

今回はPCと連携せずにスタンドアロンで起動し、SRAM上で実行できる環境を拵えます。
原理としてはきわめて原始的なブートローダをSPIFIに仕込む形になりますが、大まかに
いうと以下の流れで行います。

1.SPIFIのアドレス(0x14000000)からブート

2.Reset_Handlerに飛ぶ(けどアドレスはまだSPIFI上の0x1400****)

3.".text"〜".data"の領域までLocalSRAM(0x1000000)にコピー

4.PCをSRAM上に指定してジャンプ

5.BSS領域をゼロクリア・各種クロック・I/O設定

6.main()に飛ぶ



"4."の部分がミソなわけですが実際のアセンブラのコードを見てもらうと…

一見無意味なことしてるように見えますがその場(SPIFI上)でジャンプすると着地点が
LocalSRAM上になりそのままSRAM上で何事もなくプログラムを継続できる仕組みに
なるわけです。
もうお気づきの方いると思いますが大昔AT91R40807でやってたことと全く同じですね。

また、上記のからくりを実行するためにはbin形式でSPIFI-SPIROMに書いてやる必要が
あります。LMA/VMAの情報を保持しているelf・ihex形式だと失敗しますのでご注意を。



ということでLPC4330-Xplorerもこちらこちらに準拠したビルド・デバッグ環境をこしらえ
ました。あとはどんどん上位層のプログラムを作りこんでいくだけです!


20121003追:
GCCビルド可能なLED点滅(シングルコア動作)プログラム公開します。

Comments

記事を参考にいただいております。
今後も楽しみにしております。
(当方もLPC-4330 Exploreを買おうと思って
待ってた所でした。
当面は、LPC-Linkから使うことになりそうですが。)
nuttxを乗っけて開発を続けることになりそうです。

関西人様、ねむいです。こんにちは。

私事でバタバタしてるうちにSTマイクロさんからも新機種の情報が
上がっています。年内リリースが噂されていたSTM32F4シリーズの2MB
フラッシュ版ですがなんと(RGB-I/Fな)LCDやSDRAMのインターフェース
も追加されるようです。
www.stm32.eu/node/237

ということでもう少し練って公開するつもりでしたが、LPC4330-Xplorer
向けのGCCビルド可能なLED点滅プログラムをおきぱに公開しておきました。
まだヘテロジーニアスな使い方はしておらず、M4コアだけで動作させて
います。

本当にありがとうございます。

当方は、Cortex-M0で音声サンプリングして
Cortex-M4FでFFTを行う予定です

  • 関西人
  • 2012/10/03 8:48 PM

ねむいです。こんにちは。

公開したプログラムですが、LocalSRAM上で実行する際に
ビルド時の最適化レベルが-O2以上だとPLL1の設定時に
こけることが分かったので発振安定待ちの簡易ウエイトを
置いて対策しました。

はじめまして。酔漢です。

カスタムcfgファイルを公開いただきありがとうございます。私のOpenOCDは0.6.1ですのでSPIFLASHドライバ関連のコメントアウトが必要でしたが、おかげであっさり動きました。

それにしても、SPIIFのエラッタでリセット直後にフォールトが起きるなど、想像もしませんでした。今後ともよろしくお願いします。

酔漢様はじめまして、ねむいです。
こちらこそ色々おせわになっております。

LPC4330用の修正したcfgファイルはOpenOCDのバイナリと共に
おきぱに公開しましたので他の方も手軽に使えると思います。
spifiブート時の外部リセット問題も一度対策が分かれば
怖いものなしです。

204MHzで動作するデュアルコアMCUが身近になるのはとても
熱いですね(物理的な意味で)!

Post a Comment








Go to top of page