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

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



●OpenOCDで使いたい!

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

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


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


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



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


それと最近よく頂くようになった質問で圧倒的に多いのが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はパッチ済なので問題なく動作します♥

ちょっと難ありの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