STM32にJTAG経由でDFUを書き込む

20121108追:
内容がものすごく古てもう実用に耐えない内容なのでこちらを参照してください。
STM32に限らず普遍的な内容を網羅してあります。








急に冷え込みましたね…えっくし
あの子は今寒さに凍えて体を冷やしていないだろうか…?
…温めてやれないのでしんぱいです。




ARM系のCPUでJTAG経由のフラッシュプログラミング方法なんて
巷にものすごく詳しく解説付きであふれてるので、ねむいさん的には
皆さんに全く参考にならない方法を紹介していきたいと思います。

20120517追:
レガシーポートを使用する方法はもうお勧めできません!


●レガシーなLPT経由の方法
私はM570RUのユーザーです。こいつにはLPTなんてレガシーなもの存在
しません。じゃぁどうやってやんだよ!というとExpressCard接続のLPT拡張ユニット
をつかってLPTポートを"物理的に"設けます。昔ながらのIOポート直叩きができます♥

認識されるとこんな感じ。しかし!エクスプレスカード=PCIExpress接続の拡張
LPTなので物理アドレスがいつもの0x378とかじゃなく0x3CD8とかへんてこりんな場所に
置かれます。もちろん0x378にアドレスの変更なんてできませんでしたorz
(物理アドレスもらえるだけマシだが…)

というわけで使えるアプリケーションは限られます。H-JTAGというJTAGサーバー
を提供するソフトは0x3CD8でも設定可能なのでこれが使えます。
LPT接続用のJTAGインターフェースの回路図はこちら。Wiggler互換です。
なんでJTAGのコネクタをわざわざ10Pinから20Pinに変換してるのかというと、
AVRJTAGICE/JTAGICE mk2とALTERAのJTAGインターフェースがこの10Pinの配列で、
ねむいさん的にはこれを基準としてすべての制作物を合わせているからです。
ARMしか使わない人は元から20Pinでいくか各自のやりやすい配置で行きましょう。

H-JTAGの基本設定はこんな 感じに してください。
実はWiggler互換じゃなくてもLPTにつながりゃ何でも行ける。
Coretx-M3専用のTAPコントローラの設定は必ず行うこと。
そして難なく認識
書き込み消去もほとんどストレスなくサクサク行けます。


話変わりますが、なひたふ氏のMITOUJTAG評価版0.31&トラ技特別版は
上記の拡張LPTは一切使用不可でした。0x378,0x3BC,0x278の物理アドレス
しかサポートしてないみたいです。残念。(まぁ評価版だし…)
ちなみにlinuxのioperm()関数とかもサポートするアドレスの範囲が
0x3ffまでなのでそれ使ってる直叩き出来るアプリも全滅。全アドレスに
使えるiopl()関数に適宜書き替えてやる必要性があります。



●USB(JTAGkey互換回路)経由の方法
アマチュアのARM開発ではこちらが今現在最もポピュラーな方法ですね〜。
私のM570RUでもこれならスマートかつ無問題です。
(なぜかM570RUは物理COMポートがある。Linuxのデバッグ出力用だろうか?)。

先にも紹介しましたJTAGkey互換回路はかみき氏のものを流用させてもらって
います。扱える電源電圧範囲が1.65V〜5Vとだだっ広いです。
+5Vトレラントな2電源レベルシフタのおかげなのですが、JTAGkey単体の評価や
レベルシフタの実力は別件で測ってますのでまた後ほどにでも。

また、かみき氏の回路にAT93C66Aの外付けEEPROM回路をさらに追加して、
Amontec JTAG keyと全く同じVIDとPIDにしています。EEPROMの設定を含めた
ドライバファイルはこちらに
MProg書き込んでください。


STM32基板との接続も最もポピュラーな構成を流用しています。
STM32(というかARM全般)--JTAGkey互換(FT2232レイヤ)--OpenOCD(server)という
つなげ方です。

20120517追:
OpenOCDを使用した内蔵フラッシュの書き込みはこちらを参照にしてください。




前振り長くなりましたが、DFU(DeviceFirmWare)をJTAGkey互換回路で
STM32に書いてみます。,今回のおソースはこちら最新のSTM32-USBファーム
ウエアライブラリ
とDFUのデモソフトウエアを適用してます。わかっているとは
思いますけど試される時は自己責任でよろしくお願いします。
開始アドレスは0x08000000固定です。makefike内で0x08003000開始も設定
できますけど当然動きません。気を付けてください。

新しいDFUをJTAG経由で書きこんで見ます。成功したときのログは
以下のようになります。STM32はJTAGデバイスが2つ見えます。


> "C:¥Devz¥AVR¥WinAVR¥utils¥bin¥make.exe" program
openocd-ftd2xx -f interface/jtagkey.cfg -f target/stm32_flash.cfg -c "flasher main.elf" -c "resume" -c shutdown
Open On-Chip Debugger 0.2.0-in-development (2009-05-09-21:00) svn:1606M
BUGS? Read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS

500 kHz
Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (Manufacturer: 0x23b, Part: 0xba00, Version: 0x3)
Info : JTAG Tap/device matched
Info : JTAG tap: stm32.bs tap/device found: 0x16410041 (Manufacturer: 0x020, Part: 0x6410, Version: 0x1)
Info : JTAG Tap/device matched
Warn : no telnet port specified, using default port 4444
Warn : no gdb port specified, using default port 3333
Warn : no tcl port specified, using default port 6666
Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (Manufacturer: 0x23b, Part: 0xba00, Version: 0x3)
Info : JTAG Tap/device matched
Info : JTAG tap: stm32.bs tap/device found: 0x16410041 (Manufacturer: 0x020, Part: 0x6410, Version: 0x1)
Info : JTAG Tap/device matched
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000ed8
Info : device id = 0x20016410
Info : flash size = 128kbytes
stm32x mass erase complete
Info : Padding image section 0 with 0 bytes
Warn : not enough working area available(requested 16384, free 16336)
wrote 8508 byte from file main.elf in 0.640630s (12.969411 kb/s)
verified 8508 bytes in 0.437502s
Info : JTAG tap: stm32.cpu tap/device found: 0x3ba00477 (Manufacturer: 0x23b, Part: 0xba00, Version: 0x3)
Info : JTAG Tap/device matched
Info : JTAG tap: stm32.bs tap/device found: 0x16410041 (Manufacturer: 0x020, Part: 0x6410, Version: 0x1)
Info : JTAG Tap/device matched

> Process Exit Code: 0
> Time Taken: 00:05


DFUが正しく書きこまれていれば、DFUseを起動するとこの画面が見えるはずです。

これでJTAGさえあればDFU書き潰して0x08000000でスタートするプログラム
書きこんでも大丈夫ですね。…と言いたいところですが!
STM32のコアクロックが停止する__WFI命令等を実行しっぱなしの
プログラムを不用意に書きこんでしまうと起動->__WFIでクロック停止->JTAG
インターフェースも仲良くおだんまりとなってJTAG経由のアクセスが
一切できなくなってしまいます!

これを回復するには先日紹介したシステムメモリからのブートでシリアル
経由でフラッシュの消去を一旦行うか、リセットボタン連打しながらJTAG経由で
うまく引っかかるまでひたすら消去動作を行い続ける方法があります
(ファミコンの裏ワザみたいだ)。私としては後者前者の方法を強く強くお勧めします。

Go to top of page