この記事はhttps://adventar.org/calendars/10226 5日目の記事です。
どうもどうもTanaportです。
昨日の記事は、T-MPIさんの「学生大会2024 ~3日じゃマウスはあまり進化しないかもしれない話~」でした。貨物くんは大会でも弊サークル内でも異色の見た目で大好きです。センサ基板がヤバそうは痛感しています…。来年以降はサークル全体で撤廃しましょう。でも、センサの知識が残念すぎるのでどこかでブログにまとめます。
それでは本編に入ります。まずはST-LINKについて少しだけ説明してみます。
ST-LINKとは??
今回の話題であるSTLinkとは、STM32マイコン用のデバッガおよびプログラマです。JTAG、SWD、SWIMといった結線方式でPCとマイコンとで通信ができます。STLinkはバージョンで機能が異なり、ST-LINK/V2ではOpenOCDを使用可能に、V2-1では仮想シリアルポート機能とUSBマスストレージ機能が使用可能に、最新のV3ではV2以上に最大通信速度が上昇しました。
OpenOCDとは、なんぞやと思われると思うので少し説明します。OpenOCDとは「Open On-Chip Debugger」の略で、マイコンにおいてJTAG/SWD等のデバッグ端子の規格を使ったオープンソースのデバッガです。
OpenOCDの説明で出てきたJTAG/SWDとは、マイコンと通信を行うための通信インターフェースです。JTAGは信号線が4本で、SWDは2本です。信号線が2本で済むSWDという規格は、マイコンでJTAG用に4ピンも通信に使われてはひとたまりもないので、JTAGの後に規格が定められました。なるべくピン数を少なく結線したいので、今回はSWDでの接続方法を説明しています。
仮想シリアルポート機能とは、PCと通信仕様を合わせればUSB経由で通信ができるということです。USBマスストレージ機能とはUSBでPCと接続すれば、記憶媒体としてPCが認識してくれるということです。雑な理解なので雑な説明でも許して…。
最新のST-LINK V3の通信速度は480 Mbpsで、stm32のUARTのデフォルト通信速度115200 bpsの約4000倍の通信速度です。STLinkで書き込みを行うと、数秒で書き込みが終わります。
弊サークルの伝統的マウス達は、UARTで書き込みを行っており、STLinkを用いる人は少ないです。UARTで書き込みを行うと1分以上かかり、ただただ時間の無駄なので絶対導入したほうが良いです!!!
それでは、VScode上でST-LINKを使って書き込み、printfする方法を記述していきます。ネットの海から仕入れた情報をまとめているだけなので、分からない箇所は、一番下の参考にしたリンク群を参照してください~。
STM32 CubeMXでの設定

CubeMXで、System CoreのSYSからDebug欄を「Serial Wire」にします。すると、勝手にどこかしらの2ピンが「SYS_JTCK-SWCLK」「SYS_JTMS_SWDIO」とアサインされます。この2ピンをST-LINKと接続すればデバッグ、及び書き込みが行えます。
しかし、このままではマイコンからPC向きの通信線がないのでUARTを開放しない限り、printfができません。ST-LINKのみでprintfをしたい場合は、Debug欄を「Trace Asynchronous Sw」にします。すると、勝手にどこかの1ピンが「SYS_JTDO-SWO」とアサインされます。これでマイコンからPC向きの通信線が開放されました。
簡単ですね。これでCube MXでのピン設定は終了です。続いて、プロジェクトマネージャーの設定に移ります。
今回はVScodeでの開発環境を構築したいので、Toolchain/IDEを「Makefile」にします。そしてGenerateします。Cmakeでのやり方は調べてください。今回はmakefileを使用します。

以上でCube MXで必要な設定は終了です。
ソフトウエアのダウンロード
VScodeでST-LINKを使用し、かつコンパイルを行うには、デバッグ用のOpenOCDとSTM32用のツールチェイン、makeコマンドを使用するためのGNU Toolが必要です。以下にダウンロード用のリンクを貼り付けておきます。
- https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
- https://openocd.org/
- https://gnuwin32.sourceforge.net/packages/make.htm
私の環境では、arm-gnu-toolchainは13.2、openOCDは0.12.0、makeは3.81をダウンロードしました。

ダウンロードしたフォルダを解凍して、C直下にToolsというファイルを作成します。Tools内には以下のようにファイルを格納します。
- C:/Tools/arm-gnu-toolchain/…
- C:/Tools/make-3.81-bin/…
- C:/Tools/OpenOCD/OpenOCD-20230621-0.12.0/…
以上でソフトウエアのダウンロードは終了です。
VScodeの設定
Cube MXで生成したプロジェクトのファイルをVScodeで読み込みます。

すると、.vscodeというフォルダが出現するので、フォルダ内に写真のsetting.jsonを除き、3つのファイルを作成します。VScodeに先ほどインストールしたツールを読み込んでもらうために、各種設定を行います。
c_cpp_properties.jsonには以下のように記述します。ここはVScodeのインテリジェンス機能を使うために設定しているだけなので、不要な人は飛ばしてください(不要なことはないと思うけど)。私はSTM32F411を使用しているので、”defines”内はSTM32F411xxにしていますが、ここは使用しているマイコンに合わせてください。
{
"configurations": [
{
"name": "STM32",
"includePath": [
"${workspaceFolder}/**",
"C:\\Tools\\arm-gnu-toolchain\\lib\\gcc\\arm-none-eabi\\13.2.1\\include"
],
"defines": [
"USE_HAL_DRIVER",
"STM32F411xx",
"__weak=__attribute__((weak))"
],
"compilerPath": "C:\\Tools\\arm-gnu-toolchain\\bin\\arm-none-eabi-gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
launch.jsonには以下のように記述します。configFilesは使っているマイコンの型番に合わせてC:/Tools/OpenOCD/OpenOCD-20230621-0.12.0/share/openocd/scripts/target内から選択してください。cpuFrequencyはCube MXのClock ConfigurationのHCLKと合わせます。serverpathはOpenOCDのバージョンに合わせたディレクトリ名に変更してください。
{
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"cwd": "${workspaceRoot}",
"executable": "./build/${workspaceFolderBasename}.elf",
"request": "launch",
"preLaunchTask": "Build project",
"type": "cortex-debug",
"servertype": "openocd",
"configFiles": [
"interface/stlink.cfg",
"target/stm32f4x.cfg"
],
"postLaunchCommands": [
"monitor reset init",
"monitor itm port 0 on"
],
"svdFile": "STM32F4x1.svd",
"device": "stm32f4x",
"swoConfig": {
"cpuFrequency": 100000000,
"source": "probe",
"swoFrequency": 1000000,
"enabled": true,
"decoders": [
{
"port": 0,
"label": "ITM",
"type": "console"
}
]
},
"armToolchainPath": "C:\\Tools\\arm-gnu-toolchain\\bin\\",
"serverpath": "C:\\Tools\\OpenOCD\\OpenOCD-20230621-0.12.0\\bin\\openocd.exe"
}
]
}
tasks.jsonには以下のように記述します。
{
"version": "2.0.0",
"type": "shell",
"echoCommand": true,
"tasks": [
{
"label": "Build project",
"command": "make",
"args": [
"all",
"GCC_PATH=C:\\Tools\\arm-gnu-toolchain\\bin"
],
"options": {
"env": {
"PATH": "C:\\Tools\\make-3.81-bin\\bin"
}
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Clean project",
"command": "powershell -Command Remove-Item",
"args": [
"${workspaceFolder}\\build",
"-Recurse"
],
"problemMatcher": [
"$gcc"
],
"group": "build"
}
]
}
printfを使用するために、main.cのどこかに以下も記述します。
int _write(int file, char *ptr, int len)
{
int DataIdx;
for(DataIdx=0; DataIdx<len; DataIdx++)
{
ITM_SendChar(*ptr++);
}
return len;
}
以上でVScodeの設定は終了です。
これで、ビルドができ、F5ボタンでデバッグモードに入ればSWOからのprintf出力が見れます。
最後に
長くなりましたが、以上がVScode上でSTlinkを使って書き込み、printfもしている話でした。ピン3つで書き込み、デバッグ、printfができるのでぜひ導入してみてください。WMMCでこれから自作マウスを作る人は是非参考にしてみてください。
明日はJamesさんの「第39回全日本学生マイクロマウス大会を終えて」です。お楽しみに。
コメント