OpenOCDのSWDモードを使ってstm32F0に書き込めない場合の対策

JTAGKEY互換のJTAGボードを使いOpenOCDでstm32F051に書き込みをおこなっている時にDMAで連続してデータを送信するプログラムを書き込んでしまうと次からプログラムが書き込めなくなる現象に遭遇した。

最初はリセットをかけるタイミングで何とかならないかと苦心惨憺してみたもののどうにもならなくて「CPU交換しかないか」と諦めて家に帰ったが、
家でふと「DMAのバス占有率が高くなっていることが原因なら書き込みのクロックを下げてみたらどうか?」と思いついて会社に来てから試してみたらビンゴ!

書き込みクロック500KHzを100KHzに変更してみるとすんなり書けてしまった 8-)

 

OpenOCD 0.9.0の構築

stm32Fシリーズのプログラム書き込みに自社開発のJTAGボードとねむいさんが提供してくれているOpenOCDのバイナリを使っている。

今回、タッチキーのインターフェースがあるstm32F05xを使ってみようと思って回路設計を始めてみたらなんと
JTAGインターフェースが無くてSWDを使った書き込みだけが出来るようになっている 8-O

ねむいさんのブログを見てみるとJtagKey互換のボードでSWDの書き込みに対応したバージョン0.9.0と定義ファイルを提供してくれていた :-)

ダウンロードして試してみると私の使っているWindows8.1では動作しなかったがWin7上で使えばSWD書き込みが出来ることが確認できたので「とりあえず良し、そのうちねむいさんもWin8に対応してくれるだろう。」と思ったのだが..

なんとなくすっきりしないのであちこち検索して久しぶりにツールの構築にチャレンジしてみた。 H8やSHをメインターゲットにしていた時は自分でGCCを構築していたのだが最近はすっかり横着になって誰かが構築してくれたバイナリを使うことにしている(GCCの構築って開発環境のバージョンを整合させるのがとっても面倒なのです)

build OpenOCD for windows で検索してみるとCygWinでbuildする例とかUbuntuでbuildするのが簡単とか色々あって、まずはCygwinでやってみて失敗。

次にUbuntuのバージョンを色々変えながらチャレンジして何とか成功したので備忘録として書いておくことにした。
少し経つと何をどうやったのか完全に忘れますから :-)

※試行錯誤して出来たことを思い出して書いているので詳細な手順についてはあやふやなところがあります。

(OpenOCDのソース)

http://www.freddiechopin.info/download/category/10-openocd-dev/でダウンロードしたopenocd-0.9.0-dev-swd-140623233947.7z
このファイルを解凍するとopenocd-0.9.0のバイナリが入っていてソースのダウンロード方法は source/Info.txt に書いてある。

(環境)

Windows8.1のVirtualBoxにインストールした Ubuntu 14.04 ja

(手順)

1.電子工作マスターへの歩みを参考にさせて頂いて必要なパッケージをインストール

unzip
autoconf
automake
libtool
autotools-dev
git
patch
cmake
mingw-w64-dev
g++-mingw-w64
gcc-mingw-w64
gcc-mingw-w64-base
g++-mingw-w64-i686
g++-mingw-w64-x86-64
gcc-mingw-w64-i686
gcc-mingw-w64-x86-64
binutils-mingw-w64-i686
binutils-mingw-w64-x86-64
mingw-w64-tools

その他にも色々いれたような気が 8-)

2. 同じく電子マスターへの歩みを参考にlibusb0を準備
※ 何故か、コンパイラの参照先が /usr/i686-w64-mingw32/sys-root/mingw でなく /usr/i686-w64-mingw32 になっていた。
http://sourceforge.net/apps/trac/libusb-win32/wiki
より libusb-win32-bin-1.2.6.0.zip をDLして作業ディレクトリにコピー

$ unzip ./libusb-win32-bin-1.2.6.0.zip
$ rm ./libusb-win32-bin-1.2.6.0.zip

$ cd ./libusb-win32-bin-1.2.6.0/bin/x86/
$ cp ./libusb0_x86.dll ./libusb0.dll
$ gendef ./libusb0.dll
$ i686-w64-mingw32-dlltool -d ./libusb0.def -l ./libusb.a
$ sudo cp ./libusb.a /usr/i686-w64-mingw32/lib/
$ sudo cp ./libusb0.dll /usr/i686-w64-mingw32/bin/
$ sudo cp ../../include/lusb0_usb.h /usr/i686-w64-mingw32/include/usb.h
※lusb0_usb.hをusb.hにリネームしてコピーするのがポイント、usb.hというファイルはあちこちにあるので最初はそちらを使っていたらエラーで先に進まなかった。

3. libusb-1.0をビルドする
※libusb-1.0は Ubuntu 14.04に入っているという話もあるし、apt-getでインストールすることも出来るので不要かもしれない

$ git clone git://git.libusb.org/libusb.git
$ cd ./libusb/
$ autogen.sh
$ ./configure –prefix=/usr/i686-w64-mingw32/sys-root/mingw –host=i686-w64-mingw32
$ make
$ sudo make install

4.libftdiをビルドする

$ cd ~/tool_temp/
$ git clone git://developer.intra2net.com/libftdi
$ cd ./libftdi/
$ cmake -DCMAKE_TOOLCHAIN_FILE=../../param_file/Toolchain-mingw32.cmake -DCMAKE_INSTALL_PREFIX=/usr/i686-w64-mingw32/s
$ make
$ sudo make install

5.ライブラリの名前を変更

libusb.a -> lusb.a
libusb-1.0.a -> lusb-1.0.a
と変更するかシンボリックリンクを貼る

6.ソースを用意 上に書いたsource/Info.txtの内容に従ってダウンロードとパッチをあてる

Git repositoryからソースをダウンロードして用意する
$ git://git.code.sf.net/p/openocd/code targetdir
Apply following patches:パッチをあてる
$ git fetch http://openocd.zylin.com/openocd refs/changes/84/2184/5 && git checkout FETCH_HEAD

7.コンパイル
Info.txt(source/info.txtの上のディレクトリにある)を参考にしてコンパイル

$ cd targetdir
$ ../configure –host=i686-w64-mingw32
※ Info.txtには他にもオプションがたくさん記述してあるがとりあえずこれだけでOKでした
$ make
$ x86_64-w64-mingw32-strip src/openocd.exe
※デバッグ情報を削除して出来上がったプログラムのサイズを小さくする