SerialWireDebug¶
- Table of contents
- SerialWireDebug
この記事を書くにあたって AN4989 STM32 microcontroller debug toolbox を参考にしました。
CubeMXにおける、 System Core-SYS-Debug の設定のデフォルトは Disable です。
Disableであってもデバッグ実行はできるようですが、誤ってユーザピンを割り当ててしまうのを防ぐためにも、CubeMX上で設定を行います。
CubeMX上での設定¶
- iocファイルをダブルクリック
- System Core-SYS の Debug を
Trace Asynchronous Sw
に直します- TCK TMS SYS_JTDO-SWO のピンが割り当て済みの状態になります
Serial Wire
でなく Trace Asynchronous Sw
にするのは、SWOを使ってデバッグ出力を行いたいからです。
ソースの書き換え¶
AN4989 STM32 microcontroller debug toolbox の 7.3 Printf via SWO/SWV に、SW4STM32向けの記述があるので、それに倣います。
なお、__io_putchar()をmain.cでないソースに配置する場合は、main.hをincludeすればITM_SendChar()の型をコンパイラに教えることができます。
main.cの書き換えでなく、ソースファイルを追加してそちらに__io_putchar()などを置きたい場合は、 gitリポジトリ上のsha1 6d4a99feの差分 を参考にしてください。
main.cを書き換えてSWOからprintf()する手順¶
main.cを開き、 USER CODE BEGIN Includes
と USER CODE END Includes
の間に #include <stdio.h>
を挿入します。
以下のソースをmain.cの USER CODE BEGIN 0 と USER CODE END 0 の間に挿入します。
int
__io_putchar(int ch)
{
ITM_SendChar(ch);
return ch;
}
int
_write(int file, char *ptr, int len)
{
int i;
for (i = 0; i < len; i++)
{
__io_putchar(*ptr++);
}
return len;
}
USER CODE BEGIN WHILE近辺は以下のように直します。
/* USER CODE BEGIN WHILE */
while (1)
{
static int32_t count = 0;
HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);
printf("loop %ld\n", count++);
HAL_Delay(500);
/* USER CODE END WHILE */
MCU Eclipse上での設定¶
Debug Configurations で、 □Allocate console for semihosting and SWO
にチェックをいれるだけです。
プログラムを実行すると、Eclipse上のConsoleに以下のように表示が行われます。
SEGGER J-Link GDB Server V6.70a - Terminal output channel loop 0 loop 1 loop 2 loop 3
なお、Eclipse上でデバッグを行っていない時であれば、 SEGGER J-Link SWO Viewer
で Data from stimulus port(s
の0番を観測することでもprintf()の出力を見ることができます。
J-Link GDB ServerのSWOにつないで垂れ流すスクリプト¶
EclipseのConsoleにSWO出力を出すと、デバッガの出力とごっちゃになってわかりづらいし、かといってJ-Link SWO Viewerはいまいち。
そこで、「J-Link GDB ServerのSWOサービスポートに接続しに行って、得た文字列を標準出力に垂れ流す」 Pythonスクリプトを作りました。
swoproxy.py のダウンロードへ Rawボタンを押すと取得できます。
- 出力結果イメージ (Cygwin64のコンソール上でswoproxy.pyを実行)
vTaskList()とvPortGetHeapStats()
Cygwin64のコンソールはエスケープシーケンスを解釈してくれるので、文字色を変えて出すことも可能です。
swoproxy.py
は、Ctrl-Cを押されない限りは、GDBサーバが起動してなかろうがデバッガが停止しようが動き続けます。
つまりは、swoproxy.pyを起動しっぱなしにしておけば、Eclipseなどのデバッガ上でデバッグ実行したときにSWOからの出力文字を表示できて、コピペも楽です。
□Allocate console for semihosting and SWO
は不要です。
動作確認はCygwin64のpython3.8で行っていますが、特別なことはしていないのでほかの環境でも動くと思います。
SWOへ文字列を出すプログラムの例は、以下の手順で入手できます(NUCLEO-F429が必要です)。
- https://ashidan.myhome.cx/gitbucket/git/molelord/stm32.git をクローン
- ide_ws1/nuc-f429-blink-afrtos/Core/Src/sub.c の #define TEST_SWOPROXY_PY を1に書き換え
- ide_ws1/nuc-f429-blink-afrtos をGNU MCU Eclipseでビルドして実行
swoproxy.pyを実行するショートカット¶
ダブルクリックだけでswoproxy.pyを実行したい場合は、Cygwin64 Terminalのショートカットをコピーして、
リンク先を以下のように書き換えます(cygwinのインストールパスとかswoproxy.pyのパスは適当に変えてください。)
修正前 c:\cygwin64\bin\mintty.exe -i /Cygwin-Terminal.ico - 修正後 c:\cygwin64\bin\mintty.exe /bin/python3 /cygdrive/c/work/stm32/bin/swoproxy.py
トラブルシューティング¶
- EclipseのConsoleに文字が出ない
- Debug Configurationsで、StartupタブのEnable SWOの右の
CPU freq:
がSTM32CubeMX上のHCLK設定と一致しているか確認します。
- Debug Configurationsで、StartupタブのEnable SWOの右の
累計表示回数:328
Updated by mole lord 4 months ago · 11 revisions