Windows10対応軽量シンプルな環境でARMマイコンをInsightとOpenOCDを使ってデバッグする(2020年度版)

20230711追記!!!
GCC12でビルドされたelfファイルは下記のinsightを使った
方法ではスムーズにデバッグできません!!
現在GDB+CodeLiteによる新しい時代に即したデバッグ
手順を作成しておりますので完成まで今しばらく、
いましばらくお待ちくださいませ!!!11!!




OpenOCD for Windows is HERE!
↑ねむいさんは自前ビルドのOpenOCDバイナリ公開してます。
 解説はこのバイナリを基にすすめますので4649!



この記事は前回からの続きです。前回のものよりちょっと内容が難しくなってます。
前回の内容を基に環境を構築していることが前提で話を進めさせていただきます。
今回はOpenOCDを使用し実際にARMマイコンにJTAG/SWD経由でフラッシュ書き込み
そしてデバッグを行うところまでいきます。
もちろん今回も軽量動作,NO-Eclipse,NO-Cygwinです。

※今回の記事も時代に合わせて適宜加筆修正していきます。


●必要なもの
 1.ARMマイコンが実装されたターゲットボード
  凡例として、STM32F4シリーズであるSTM32F4Discoveryを使用します。
  私が配布しているSTM32F4向けのFatFs移植例は、デフォルトのターゲットボードが
  STM32F4Discovery、デバッガハードウエアがSTLink/V2となっています。
  Nucleo系板や2015年以降発売のDiscovery系板はSTLink/V2-1に変ってます。
  
↑とりあえず何も編集しなくてもよくなってます。

 2.JTAG/SWDデバッガハードウエア
  上記のCortex-M4はデバッグユニットとしてJTAGとSWDという接続方式の両方を
  サポートしています。ARM7TDMIはJTAGインターフェースのみでした。

  現在、ホビーユーザーが手軽に利用できるものとしてFT2232系を使ったJTAG
  デバイスが主流です。
  以後の解説はそれを利用したJTAGKey2互換の"JTAGKey2 Compatible"
  を使用しJTAG接続にて解説していきます。
  JTAGKey2 Comatibleを自作される方はこちらの解説を参考に。

  SWD接続についてはCMSIS-DAPが現在の主流となっています。
  NxP系の評価ボードにはmbed版としてデフォルトで搭載されているので
  もはやおなじみだと思います。
  その他の品種ではVersaloonや上記のJTAGKey2CompatibleでもSWD接続可能
  なっています。
  
  2023年現在はCortex-M系マイコンが主流となり、SWD接続がデファクト・
  スタンダードなっております。
  

 3.OpenOCD
  OpenOCDはターゲットMCU(ARMマイコン)と後述するgdb/insightの仲介役を
  果たすフラッシュ書き込み機能を持ったサーバープログラムです。
  ねむいさん謹製のビルド済みバイナリを用意しておりますので、
  OpenOCDのWindowsバイナリはこちらからダウンロードしてください。

  注意すべきはデバッガハードウエアに対するドライバで、上記リンクに
  あるOpenOCDバイナリは下記のデバイスとドライバをサポートしています。
  *JTAGKey2をはじめとしたFT2232系デバイス:(WinUSB)
  *Versaloon:(WinUSB)
  *STLink/v2:(STMicro純正/WinUSB)
  *TI-ICDI(Stellaris Launchpad):(TI純正/WinUSB)
  *J-Link(WinUSB)
  *J-Link On LPCLink2(WinUSB)
  *CMSIS-DAP(HIDとしてドライバレスだがmbed版はVCPドライバ必須)
  *STLink/V2-1(VCPドライバ必須)


  各ドライバのインストールは以前は、PID/VID調べてINFファイルを作って
  …と非常にめんどくさかったのですが、現在はWinUSB向けのGUIな汎用
  インストーラのzadigを使用することによりインストールが大幅に簡略化され、
  手軽になりましたのでzadigでインストールを行ってください。
  公式のサイトにはインストール手順も英文で懇切丁寧に書かれていますが
  見る必要も無いくらい簡単にWinUSBが導入可能です。

  注:このOpenOCDは32bit版ですが64bit版Windows環境でも問題なく動作します。
     64bit版OpenOCDと比べて速度的な面で大差はないです。

  ARMは新旧の情報がweb上のいたるところで倒錯しすぎて何が正しい組み合わせか
  分からないと思います。Windows環境でOpenOCDを使われる方は私のぶろぐを
  しっかり見ていただければ途方に暮れることだけは避けられるかと思います。


 4.Insight(gdb-gui)
  InsightはgdbのGUI版です。また、純粋なフロントエンドではなく内部にGDB
  そのものが取り込まれているので別途gdb.exeを用意する必要はありません。
  当ぶろぐではこれを使用しソースコードレベルのデバッグを行います。
  これも詳細は後述しますがバイナリが配布されていますのでビルドする必要は
  ありません。



●下準備
 1.OpenOCDの準備
  かつてWindows環境にてMSYS/MinGWを用いた手順を公開しておりましたが、
  OpnOCD0.8.0以降はビルドするまでの手順が大幅に煩雑になり慣れてない
  人にはビルドがほぼ不可能になってしまいましたので公開を廃止しました。
  代わりとしましてビルド済のWindowsバイナリを公開しております。
  ご利用ください。インストール箇所は前回のビルド環境構築手順に倣い、  
  C:/devz/arm/ocdにあるものとします。


 2.Insightの準備
  SourceForgeにあるNetXのページのかなり下のほうにある
  "arm-none-eabi-insight-7.4.50.20111222-cvs-mingw32-netx.0.7z"を
  ダウンロードし、任意のフォルダに展開してください。
  こちらもC:/devz/arm/insight/binにあるものとします。


●ターゲットデバイスにプログラムをダウンロード
  前回の手順を参考にSTM32F4-Discovery用のmain.elfが作成されたものとします。
  デバッグ時は最適化オプションを必ず"-O0"にしてビルドしてください。

 1.makeファイルの編集
  前回も解説しましたが、makefileにあるOpenOCDとInsightがインストール
  されているパスを指定してください。
  
  Insightの引数は下図下段の要領で"--eval-command"で渡すように記述します。
  Insight起動後のTargetの設定は一切不要です。引数の内訳は以下の通り
   --eval-command="target remote localhost:3333"
    -> TCP3333番ポートに接続
   --eval-command="tbreak main"         
    -> 接続後main関数の先頭で一時停止
   -nx                      
    -> .gdbinitを作成しない&内容無視
  

 2.PN2の設定
  PN2の"TOOL"から呼び出すことが出来るように前回と同じ要領で引数つきで登録
  てください。登録するのは"program"と"debug"です。

 3.書き込み
  "TOOL"から"make program"を呼び出し、OpenOCDからSTM32のフラッシュ
  書き込みスクリプトを呼び出しターゲットデバイスに"main.elf"を
  ダウンロードします。
  OpenOCDのcfgファイルのパスの指定が間違っているとエラーが出ますので
  各自の環境に合わせてパスを修正してください。
  

 4.フラッシュ書き込み用のコマンドについて補足
  makefile内では以下のように記述されています。
  1.OpenOCDをJTAG・SWDデバイスのcfgファイル・ターゲットMCUのcfg
   ファイルを"-f"コマンドで指定して起動する。
  2.同時に-cのコマンドでターゲットMCUのcfgに記述されているproc(関数)
   を呼び出す。
  3.procに記載されている順にコマンドが実行されフラッシュ書き込みを行う。

  上記一連の動作にてgdbやtelnetからの回りくどい操作は一切要せず、簡単に
  フラッシュの書き込み動作が可能です。


●ターゲットデバイスをInsightを使用しデバッグ
 1.makeファイルの編集
  正しくプログラムが書き込まれたことを確認したら次はデバッグです。
  makeでOpenOCDとInsightを同時起動するためにちょっと工夫を凝らしています。
  先に定義したディレクトリパスやコマンドを下記のように配置して、
  クリック一発で呼び出しできるようにします。
  

 2.OpenOCD・Insightの起動と接続
  "TOOL"から"make debug"を呼び出すと、OpenOCDがターゲットMCUに接続、
  その後Insightが起動します。
  さらにOpenOCDとInsightのTCP接続まで一気に進み画像のようになれば成功です。
  

  ここで注意ですがWin10ではInsightのメニューにあるTarget Settings関連を
  いじるとInsightが固まってしまい動作不能になるため絶対に
  触らないでください!


  この状態で"Continue"を押すとmain関数の最初の行、一時的にmain()に張った
  ブレークポイント(main()の最初の行)に飛びます。このブレークポイントは
  一時的なものですぐに消えるのでリソースの無駄にもなりません。
  
  
  ここまできたらあとはInsight上でステップインとかステップアウトとか
  ブレークポイント張って停止させたりレジスタとかメモリとか(条件付で)
  I/Oレジスタの値読み出したり自由自在です!

  また、デバッグ時の重大な注意ですが、Win10ではInsightのレジスタ
  ウインドウを開くと100%落ちてしまいますので面倒くさいですがコマンド
  ウインドウから"monitor reg"でMCUの各レジスタを参照するようにしてください。
  

 3.デバッグの終了
  終了する時はTools->Stop Toolsで終了させたいところですがが、PN2では
  ひとつのプログラムしか終了できず、Insightだけが終了してOpenOCDが
  終了してくれません。
  私は下記の要領で強制的にタスクを殺すwindowsのtaskkillコマンドを使った
  バッチファイルを作成してこれを呼び出して"確実に"終了させています。
  ↓この呪文をバッチファイルにしてwindowsフォルダに突っ込んで
   おきましょう。
  taskkill /F /IM openocd.exe
  taskkill /F /IM arm-none-eabi-insight.exe
  

Go to top of page