Discovery系基板を中心とした小ネタいろいろ

2013年7月現在、STM32とそれが搭載されたデバッガハードウエア付きの
超廉価なDiscovery系ボードはホビイストや学生さんにも今回は十分行き
渡っていると思います。今回はそれらを中心とした開発上の小ネタ…
…といっても結構重要なのをご紹介します。
故中島らも氏みたいに過去に書いたことをまた書いてるような箇所が
ありますが大事なことなので2度どころか何度も言います!!!!



●OpenOCDで使いたい!

太古の昔、STLink系のハードウエアはプロプラゆえに当ぶろぐでは
燃えないゴミとして扱われていましたがSTマイクロさんのご厚意により
V1,V2共にAPIが提供されてOpenOCDからも使用可能となりました。

尤も、対応最初期はLibUSB0.1系のAPIからでしか使用できず、メーカ製の
ドライバ
が(WinUSBが)使用できないのでちょっと不便な代物でした。
その後のlibusb1.0系の移行よってそれも解消され、現状商用andフリー共に
最も融通が利くデバッガハードウエアと言えます(但しSTLink/V1系は
MSCで繋がるので今でもちょっとめんどいです)。


STM32F3Discoveryを例にとると、基板上にビルドインされたSTLink/V2に
よってSWD接続にてターゲットのSTM32F303VCTに接続されています。
おきぱで公開しているOpenOCDバイナリにはねむいさん特製の書き込み
スクリプト込のcfgファイルも同梱しています。


上記のcfgファイル内ではさらにcfgファイルの入れ子構造になっていて
OpenOCD公式が配布しているcfgの内容が差し替わった時もこちらの変更は
ノータッチで継続使用可能なように管理しています。



具体的にこれを書き込みやデバッグにどう使うかは私のSTM32F3の
プロジェクト
を用いて、こちらこちらを参考にしてください。
STM32F3の場合はmakefile内でデフォでSTLink/V2を使う設定にしているので
初めての人でも非常に簡単にできます。
20230828追:
STM32F334-NUCLEO向けのプロジェクトを参照してください
20230828追:


それと最近よく頂くようになった質問で圧倒的に多いのがSTLink/V2でOpenOCD
との接続が上手くいかない繋がらないといった非常に曖昧なものなのですが…
ほぼ100%結線ミスが原因です。
特に気づきづらいのがDiscovery系の基板を使ってオンボード上のターゲット
MPUではなく外部のマイコンに書き込もうとした時なのですが、V2.J15以上の
ファームだとターゲットのVCCの電圧も監視しているため、Vtgtを繋げていないと
エラーでこけます。

しかも多くのDiscovery系基板ではVtgtを取り込む抵抗が未実装のため、
それに気づかずVtgt繋げてるのに上手くできない!といった事態になります。

↑STM32F3Discoveryでは上記の部分に100ohmを乗っけてバイパスする。
 同じこと以前も言いましたが大事なことなので何度でも言います
ついでに


↑STM32F3discoveryではSWOまで未接続なので画像の箇所をはんだブリッジ。
 これやっとかないと後述のSWVが使えません。

●STマイクロの公式ツールを使いたい!

現在STマイクロさんからSTLink-UtilityなるSTLink用のGUIツールが提供されています。
上で触れましたがOpenOCDがSTマイクロ公式のドライバでも使用可能になったので、
ドライバの差し替え無しにSTLink-Utilityも使用ができます!

フラッシュ書き込み・レジスタの参照など基本的な操作の他に3.0.0以降では
強力なシリアルワイヤビューアも使用可能です(後述)。

一部のサイトではLibUSB0.1系でやってたころの私が公開していた情報を基に公式の
ドライバを使わずzadigでインストールする指示をされている方もいます。
STLink/V2に限ってはそれは今ではもう無意味です。逆にそれをやってしまうと
STマイクロのSTLink-Utilityが使用不可能になりますのでご注意を。
なんでこんなことわざわざ何度も言ってるかというと情報が同期していない
せいで"動かないうまくできない"という質問が私の所にダイレクツに飛んでくるからです…。



●セミホスティング考
セミホスティングとは思いくそかみ砕いていうとデバッガを通じてホストPCに
printf関数等の標準出力を吐き出させることができる仕組みです。
詳しい説明はARMのサイトにて。
かみきさんのサイトでも分かりやすい説明が記されております。

LPCXpressoを使用されている方はUARTを介さずprintfを実行する方式として
ご存知かと思います。しかしそれらのメーカーお仕着せのIDEを使わない環境でも
OpenOCDとGDBを組み合わせたり上記のSTLink-Utilityにより再現が可能です。
Cortex-M3系のマイコンでは2通りの方法があります。

1.OpenOCDから…
 OpenOCDではすでにセミホスティングに対応しています。そしてプログラムも
 当然ながらセミホスティング用にビルドする必要があります。
 現在Launchpad-ARMGCCのみで動作を確認しておりますが設定方法は
 私のプロジェクト上では以下の要素を。

 * makefile内
 
 "--specs=rdimon.specs -lrdimon"をCFLAGSに追加。それに伴いLFLAGSから
 "-nostartfiles"を削除(セミホスティング用のcrt.oを使う)。

 
 STM32F3,F4で使用する際はnewlib-nanoの制限によりCCM領域にスタックを
 おいているとセミホスティングが正しく働かないので普通のnewlibの
 ライブラリに切り替えてビルドしてください。

 * ソースコード内
 
 "initialise_monitor_handles()"を標準関数を実行する前に必ず実行。

 * デバッガソフトウエアとの連結
 当たり前ですが上記の設定でビルドして出たバイナリを書き込んでもそのままでは
 何も起きません。OpenOCDで接続してデバッガとホストPCとが通信できる状態に
 ならないとだめで、OpenOCD接続時に-c"arm semihosting enable"を追加する
 必要があります。

 
 "arm semihosting enable"はセミホスティングを使わないときも実害はないので
 つけっぱなしでもかないませんのでmakefileには反映しています。さて、すべて
 準備がそろった状態でrunさせるとOpenOCDのアウトプットにprintfの文字列が
 表示されます。


 * LPCXPressoみたいに小規模マイコンでできるのか?
 
 たとえばフラッシュのサイズが32kbしかないLPC1114でもLaunchpadの
 "newlib-nano"と組み合わせることによってなんとバイナリサイズ7kb以下で
 printfが可能です!
 小規模ゆえに同一RAM領域にスタックとヒープが存在するのでnanoの方でも
 セミホスティング可能というわけです。(浮動小数点付も22kb以下で可能)
 標準関数組み込んだらバイナリサイズが一気に肥大した〜!
 …なんて話は今は昔。


2.STLink-Utilityを使って…
 これはCortex-Mの仕様上CortexM3/4専用技ですがSWVを利用してprintfを
 実行します。原理はprintfの出力先をリダイレクトするのと全く同じです。

 ねむいさんの公開してるプロジェクトでは…
 
 syscalls_if.h内のputch()のdefineをITM_SendChar(x)にするだけで終わり
 です。しかも1.の方法と違って垂れ流し方式なのでデバッガと常時接続
 しないと先に進まないといった障害もありません。

 
 STLink-Utility3.0.0以降でSWVが使用可能です。
 
 クロック設定はsysclock(ねむいさんのサンプルでは72MHz)に合わせて
 ください。ここでハードウエアリセットを掛けるとprintfの文字列が
 表示されます。



●STLink/V2がUSB3.0のホストでOpenOCDが繋がらないんですけぉ!11!!

私が公開しているOpenOCDバイナリのビルドポリシーをLibusbの0.1から1.0系に
変えて少しした(現在は1.0系ライブラリとしてlibusbx1.0.16を使っています)あたりから
STLink/v2やFT2232系のデバイスがUSB3.0で繋がらなくなった!でもUSB2.0ポート
からならいけたという報告を頻繁にいただくようになり、私も調査を開始しました。
…が、ねむいさんのUSB3.0の環境ではそんな不具合全く出ない。

手持ちや後輩が持ってた拡張カードとかいろいろ試したところ特定のUSB3.0ホスト
で且つlibusb1.0系で繋いでくるデバイスの動作がすべておかしくなるのをやっと
突き止めました。
そのUSB3.0ホストとはAsmediaのASM1042!
libusbxを利用するすべてのデバッガハードウエアに波及しやがるのでOpenOCDは
おろかUrJTAGやAvrdudeやFlashromもだめですorz.

libusbxのビルドをログ出力対応にして追跡していったところ、DeviceIoContolの
関数で"IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX"を投げて
"成功"が帰ってきてるのにストアされるはずの値がすべて0に
なっており非接続状態と判断されてコケてるのが判明しました。
ねむいさんの知能ではlibusbxのコードをいじっても全く解決する
手立てが見つからず途方に暮れていましたが、libusb0.1系APIからの
接続やWinUSBを使っているSTLink-Utilityでは全く問題がなかったため
まさかと思ってASM1042のドライバのバージョンをいろいろ変えて
確かめているとなんと動きましたorz.
以下のファームとドライバのVerで安定動作しました(WindowsXPにて確認)。
 Firmware:Version 120816-02-02-06D (V3)
      Pour Windows Xp/Vista/7/8 32/64bits
 Driver :Version 1.14.4.0 Pour Windows Xp/Vista/7 32/64bits
上記のファイルはStation-Driverから取得可能です。

最近出回り始めたASROCKやASUS製のマザボでASM1042がよく使用されているので、
該当されるUSB3.0ホストを使っていてうまくOpenOCDが動かない方は一度上記の
組み合わせを試してみてください。

また、救済手段としてSTLink/V2をlibusb1.0系のAPIで繋ぎに行くビルド
設定にしたOpenOCDバイナリも用意しております。ドライバの差し替えが諸事情で
困難な方はこちらを差し替えてご使用ください。
OpenOCDが0.9.0になるまで公開しておきます。

20131225追:
解決しました。こちらをご覧ください。現在OpenOCD,FlashROM,Avrdude,UrJTAGの
各バイナリにバンドルしているlibusb-1.0.dllはパッチ済なので問題なく動作します♥
20131225追:

ちょっと難ありのASM1042ですが書き込みのパフォーマンスはぴか一で
μPD720202をも凌ぎます!
さらなるドライバの改良が望まれるUSB3.0ホストですね。
wrote 34816 bytes from file main.elf in 2.359314s (14.411 KiB/s)
verified 34004 bytes in 0.265619s (125.018 KiB/s)

↑uPD720202の時のSTM32F3にSTLink/V2つかって書き込み/ベリファイ速度
wrote 34816 bytes from file main.elf in 1.734330s (19.604 KiB/s)
verified 34004 bytes in 0.109372s (303.615 KiB/s)

↑ASM1042の時のSTM32F3にSTLink/V2つかって書き込み速度/ベリファイ速度


●ねむいさんとこのFatFsのSDIOで繋げるほうのSTM32F2とかF4のサンプル使った時
 SDカードに4GB超えてデータ書き込もうとするとデータが破壊されるんだが…


ごめんなさいごめんなさい!!!!
SDIOで読み書きする際のアドレスを指定する引数のデータ幅64bitに拡張して更新
しました。これでSDHCの仕様限界の32GBまで大丈夫です…SPI版はすでに対応済
なのでご安心を。
 
あ、しまった。
画像には見えてませんがdiskio_sdio.cもちゃんと64bit対応してます。


●Versaloon化してしまったSTLink/V2の正規のファームウエアを復活させる
おそロシア

しかも復活後もフツーにファームウエアのアップデートもできますし…
これで失敗も怖くない!?

●Connect Under Reset
STM32をつかっているときwfiやwfeを含むコードを実行するとデバッグユニットへのクロックも
停止してJTAG/SWDで繋がらなくなるのは常識中の常識ですが2013年になった
現在ではさすがに"普通に使っていただけなのに急に書き込み出来なくなった!!1!"
というおまぬけな質問される方はいなくなりました。

実際に回避する方法はJTAG/SWDにつなぎに行く瞬間にSRSTを手動で連打するという
極めて原始的な方法をお伝えしておりましたがOpenOCD0.8.0ではすでにその操作を
実行できる機構が追加されています。
具体的にはcfg内のresetの設定を以下のようにするだけです。
reset_config srst_only srst_nogate connect_assert_srst
これはConnect Under Resetというもので実はSTLink_Utilityにも同じく実装
されています。
私の配布しているOpenOCDバイナリに同梱されているcfgファイルにはコメントアウトの
形で追加していますので適宜コメントを解除して活用してください。

よく頂いていた同種のご質問に"低消費電力モードとかにするとデバッグ
できない!1!!!"という内容もありましたが、大抵はCortex-M3に存在する
Core Debug Resistersのうちの一つ
DHCSR(Debug Halting Control and Status Register)に0x07ぶち込んだら
解決する話しであるということも併記しておきます。

具体的にどうすればいいかというとCMSIS3.xx以降をお使いの方は下記の
コードをWFI();もしくはWFE();実行前に挿入してください。
ただしコアの消費電流はデバッグユニットが働く分増加しますのでご留意を。

CoreDebug->DHCSR |= 0x7;

これはDHCSRレジスタにC_STEP,C_HALT,C_DBGENビットを立てることを
意味します。
同時に立てても効果はでますがC_HALT,C_DBGENビットが立っていない
状態でC_STEP単独で立てることができないことに注意してください。
深いことは考えずにSleep系命令を含むファームのデバック時には実行前に
しっかりCoreDebug->DHCSR |= 0x7;を唱えておきましょう。

これとConnect Under Resetを組み合わせるとWFI();やWFE();を含む
コードでも安定してデバッグが可能となります。

Go to top of page