Project

General

Profile

Actions

SerialWireDebug

この記事を書くにあたって AN4989 STM32 microcontroller debug toolbox を参考にしました。

CubeMXにおける、 System Core-SYS-Debug の設定のデフォルトは Disable です。
Disableであってもデバッグ実行はできるようですが、誤ってユーザピンを割り当ててしまうのを防ぐためにも、CubeMX上で設定を行います。

CubeMX上での設定

  1. iocファイルをダブルクリック
  2. 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 IncludesUSER 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 ViewerData 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が必要です)。

  1. https://ashidan.myhome.cx/gitbucket/git/molelord/stm32.git をクローン
  2. ide_ws1/nuc-f429-blink-afrtos/Core/Src/sub.c の #define TEST_SWOPROXY_PY を1に書き換え
  3. 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設定と一致しているか確認します。


累計表示回数:163

Updated by mole lord about 1 month ago · 11 revisions