Arduino
IoT
VSCode
PlatformIO
ESP32

VSCode+PlatformIOを使ったESP32のデバッグ開発環境


マイコンはブレークポイントを使ってデバッグできない?

そう思っていた時期が私にもありました。

全てのマイコンとはいいませんが、JTAG規格に対応したマイコンは、ブレークポイントを用いたデバッグが可能です。M5Stackで一層人気を博しているESP32ですが、嬉しいことにJTAGに対応しています。

つまり、ESP32はブレークポイントをはってデバッグできるんです!!


前提

以下については解説を省略します。記事を参考に構築してください。

申し訳ありませんがWindows10基準の説明です。Macでも後述のドライバの設定以外は同じはずです。


JTAGとは

JTAGはシリアルポート経由でIC内部の回路と通信するための規格です。以下の5種類の信号線を用いて、マイコンのクロックの制御や、内部状態を知ることができます。ただしTRSTはピンがない場合もあります。

信号名
用途

TDI
データ入力

TDO
データ出力

TCK
クロック

TMS
状態制御

TRST
リセット

esp32-breakout-board-pinout-My-Electronics-Lab.jpg


必要なもの

ESP32

当然デバッグするマイコンは必須です。モジュールそのままでははんだ付け等が必要になるので、ブレークアウト基盤やPCとUSBで繋げるだけで利用できる開発用基盤の購入をおすすめします。



FT2232H MiniModule

今回の主役のデバッグアダプタ(後述)です。残念ながら秋月電子での取扱はありません。RSコンポーネンツから購入できます。



USB Mini-B

何故か未だにマイコン界隈でたまに使われるMini-Bケーブル。全部microにして。。。



[オス-メス]のジャンパーワイヤー

[メス-メス]のジャンパーワイヤー

メス-メスのジャンパーワイヤーは無くてもいいですが、合ったほうが何かと便利かもしれません。


デバッグの仕組み

マイコンのデバッグは、「GDB、OpenOCD、デバッグアダプタ」の三種の神器を用いて実行されます。一般的にPCにはマイコンのデバッグのための適切な種類の電気信号を供給する機能はありません。その役割を担うハードウェアがデバッグアダプタです。その通信の規格にJTAGが使用されているものを用います。OpenOCDは、デバッグアダプタとGDBをつなぐソフトウェアです。OpenOCDはデバッグアダプタに操作用の信号を送信し、TCPポートでデバッグアダプタとの通信内容をGDBに伝えます。GDBからOpenOCDを操作するためのコマンドはtelnetを通して送信されます。

OpenOCD


デバッグアダプタの準備


FT2232H MiniModuleの配線

FT2232H MiniModuleを前提とします。その他のFT2232Hのブレークアウト基盤などを用いている方は利用マニュアルなどをご参考ください。

FT2232H MiniModuleは実はそのままUSBでPCとつなげても正しく認識されません。(ここで結構泣かされました)以下の配線をする必要があります。[メス-メス]のジャンパーワイヤー等が必要になります。


  • 電源の供給

USB電源供給の場合(基本こっち)

電源
供給先

VBUS(CN3-1)
VCC(CN3-3)

外部電源供給の場合

電源
供給先

外部5V電源
VCC(CN3-3)


  • 供給された電源を3.3Vで使用するための配線

電源
供給先

V3V3(CN2-1,3,5)
VIO(CN2-11,21及びCN3-12,22)

この状態でPCとUSBで接続してください。シリアルコントローラーが2つ認識されればOKです。

シリアル

これ以降の操作はWindows10の内容になります。Macでは実は最初からFTDI社のドライバがインストールされています。(流石です)ですが、デフォルトでインストールされているドライバがあまり良くないらしいので、下記のリンク参考にドライバのセットあアップを実行してください。Windowsでのドライバのインストールがうまくいかなかった場合も下記を参考にしてください。


ドライバの設定

FT2232Hは2チャンネルのデバッグアダプタです。1つは一般的なプログラムの書き込み等に利用されるUARTで、2つめがJTAG用のチャンネルです。このままではPCがどっちのCOMポートをUART、またはJTAGに使用すればよいかわかりません。そのため、Zadigというドライバを置き換えるソフトウェア(インストール無しで使用できます)で一方のドライバをJTAG用のドライバに置き換えます。

FT2232Hを接続した状態でZadigを起動し、「Options->List All Devices」をチェックします。すると、リスト内に「FT2232H MiniModule」、または「Dual RS232-HS」というドライバが表示されます。「Interface 0」のものを選択し、「Replace Driver」をクリックします。(画像はすでに置き換え済みなので「Reinstall Driver」になってます)

image.png

ドライバ置き換え後、FT2232Hを再接続するとUARTのみがCOMポートとして認識され、COMポートのドライバのプロパティからハードウェアIDのVIDとPIDかそれぞれ0403、6010になっていることが確認できればOKです。


デバッグアダプタとESP32の接続

以下のように配線します。


  • UARTの配線

FT2232H
信号名
ESP32

BD0(CN3-26)
RX
RXD0

BD1(CN3-25)
TX
TXD0

GND(CN3-2,4)
GND
GND


  • JTAGの配線

FT2232H
信号名
ESP32

AD1(CN2-10)
TDI
GPIO12

AD2(CN2-9)
TDO
GPIO15

AD0(CN2-7)
TCK
GPIO13

AD3(CN2-12)
TMS
GPIO14

AC2(CN2-20)
RST
EN

GND(CN2-2,4,6)
GND
GND

結構カオスになります。

image.png

この段階でシリアルポートを開いて、ESP32とのUARTでの通信ができていればセットアップが無事完了したことになります。(書き込みモード等で起動して「waiting for download」の文字が受信されればOK)


PlatformIOは凄い

これでハードウェア側の全ての準備が整いました。本来であれば、この後下記のような面倒な手順をふむことになります(未調査)


  • OpenOCDのソースをダウンロード

  • OpenOCDのバイナリをビルド

  • OpenOCD用の設定ファイルを作成(大分ややこしい)

  • OpenOCD起動

  • GDB起動

  • デバッグ開始

しかし、PlatformIOを用いればF5を押せば終わります。

まずPlatformIOでESP32の新規プロジェクトを作成します。後でplatformio.iniを修正すれば変更できるので、Frameworkはどっちでもいいです。PlatformIOの操作は冒頭のPlatformIOの環境構築を参考にしてください。


  • Board:Espressif ESP32 Dev Module

  • Framework:Arduino または ESP-IDF

platformio.iniを定義します。FrameworkにArduinoを使用しない場合は他のものを指定してください。

[env:esp32dev]

platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
upload_speed = 921600
debug_tool = minimodule

main.cppにとりあえずのテストコードを作成し、プログラムをESP32に書き込みます。(2秒周期でLEDを点滅させるプログラムです)


#include <Arduino.h>

void setup() {
Serial.begin(115200);
Serial.println("start");
pinMode(4, OUTPUT);
}

boolean on = true;
unsigned long current = 0;
void loop() {
if (millis() - current < 2000) {
return;
}
on ? digitalWrite(4, HIGH) : digitalWrite(4, LOW);
on = !on;
current = millis();
return;
}

好きなところにブレークポイントをはり、ESP32が起動している状態でF5を押してください。うまくいっていればブレークポイントで止まります。当然変数の値等もWatch式やマウスホバーで確認できます。もし、変な場所で止まる、止まっているが画面に反映されない等の状態になったら、ブレークポイントを一度削除し、再度配置して「続行」するとうまくいったりします。

image.png


エラーが出た場合

ブレークポイントで止まらない等、うまくいかない場合はJTAGのピンの接続などを確認してください。

以下のようなエラーが出た場合は、次に示す手順でOpenOCDの設定ファイルを修正してください。このエラーはFTDIの最新ドライバではFT2232Hのデバイス表示名が「FT2232H MiniModule」になっているが、PlatformIOが自動で作成するOpenOCDの設定ファイルのデバイス表示名がFTDIの古いドライバの「Dual RS232-HS」で作成されることにより発生します(多分)。

Open On-Chip Debugger 0.10.0-dev (2018-06-04-09:51)

Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 20000 kHz
esp32 interrupt mask on
force hard breakpoints
Info : tcl server disabled
Info : telnet server disabled
Error: no device found
Error: unable to open ftdi device with vid 0403, pid 6010, description ‘Dual RS232-HS’, serial ‘’ at bus location '’
.pioinit:10: Error in sourced command file:
Remote communication error. Target disconnected.: No error.



  • OpenOCD設定ファイルのドライバ表示名修正手順


    • 下記のディレクトリのバックアップを作成(念の為)

    • %HOMEPATH%/.platformio/packages/tool-openocd-esp32/share/openocd/scripts/interface

    • Zadigで表示されるドライバ表示名を書き留めます(多分「FT2232H MiniMoule」)

    • ディレクトリ配下の全ファイルに対し、エラーで表示されているドライバ表示名(「Dual RS232-HS」)をgrepでZadigで表示されたドライバ表示名(「FT2232H MiniModule」)に置換します



image.png


最後に

そもそもマイコンでデバッグ必要なほど複雑なプログラム書くの・・・?