やりたい事
CubeMXでmakefileプロジェクトとして生成
↓
VSCode上で編集
↓
VSCode上でコンパイル
↓
VSCode上でマイコンに書き込み
↓
VSCode上でデバッグ
これらをWindows上で実現します。
今回は環境変数やレジストリを編集しないような方法で環境を構築します。
今回の記事ではデバッガにST-linkではなくJ-linkを使用しています。
こちらに書かれている方法でnucleoやDiscoveryなどの評価ボードに内蔵されているST-linkをJ-link化することができます。
J-linkの動作に必要なソフトはこちらからダウンロードしてインストールしておいてください。
ST-linkを使用する場合はOpenOCDなどのツールを使用します。
初回のみ必要な作業(使用するツール等のインストール)
※VSCode・CubeMX・ST-linkのドライバ・J-linkのドライバ等のインストール方法については省略します。
インストールといっても今回は環境変数を変更しないため、以下のツールを適当なフォルダに展開するだけです。
ツール
- GNU ARM Embedded Toolchain
- OpenOCD (ST-linkを使用する場合 J-linkを使用する場合は不要)
- Make for Windows
- LibIntl for Windows
- LibIconv for Windows
こいつらをC:\tools
などの任意のフォルダ以下に展開にします。
下3つのツールはWindowsでmakeコマンドを使えるようにするためのものです。
(今回はmakeだけ使えればよいのでmake単体をインストールしました。GNU Toolsが既にインストールされている場合はそちらを使用することもできます。)
最新版のバージョンはこの記事を書いているときと変わるかもしれませんが、その場合は適宜パスを最新版に合わせて読み替えてください。
場所(例)
C:\tools\gcc-arm-none-eabi-9-2019-q4-major-win32\bin
C:\tools\OpenOCD\0.10.0-12-20190422-2015\bin
C:\tools\make-3.81-bin\bin
C:\tools\make-3.81-bin\bin\libintl3.dll
-
C:\tools\make-3.81-bin\bin\libiconv2.dll
拡張機能
VSCodeに以下の拡張機能をインストールします。
- C/C++
- Cortex-Debug
プロジェクトごとに必要な設定
次に新しいプロジェクトを作成するたびに設定する内容について説明します。
CubeMXの設定
CubeMXのProject Managerのタブの中にあるToolchain / IDE
の部分をMakefile
に変更します。
それ以外は通常のSTM32のプロジェクトを作るときと同様に設定し、最後にGENERATE CODE
を押します。
USER CODE BEGIN
とUSER CODE END
の間にコードを書けば、自分が書いたコードに影響せずにCubeMX上で変更した内容がコードに反映されるという機能はVSCodeでも使用することができます。
VSCodeの設定
CubeMXで生成したプロジェクトのあるフォルダをVSCodeで開きます。
初期状態ではInc
やSrc
などのフォルダ、makefile
や***.ioc
などのファイルが生成されていると思います。
VSCodeでは開いたフォルダがプロジェクトとして認識され、開いたフォルダの中にある.vscode
というフォルダにプロジェクトの設定が保存されます。
STM32の開発を行うための設定も.vscode
内に記述していくので、.vscode
というフォルダが無ければ作成します。
.vscode\tasks.json (ビルドタスクの設定)
.vscode
内にtasks.json
というファイルを作成し、以下の内容を記述して保存します。
ここではVSCodeのビルドタスクの設定をします。
Build project
というタスクでプロジェクトのコンパイルができるように設定をしています。
Clean project
というタスクではコンパイルによって生成されたアイテムを全て削除するように設定をしています。
※以下補足
GCC_PATH
にはGNU ARM Embedded Toolchainのパスを指定します。
options
のenv
ではこのタスク内でWindowsの環境変数に一時的に追加するパスの設定をしています。今回はmakeコマンドを使いたいのでMake for Windows
をインストールしたパスを指定します。(Windowsの設定で環境変数を編集しmakeにパスを通した場合はこの設定は不要です。)
CubeMXで生成されたmakefieは初期設定ではBuild
というフォルダ内にコンパイルしたデータを吐き出すような設定になっています。
{
"version": "2.0.0",
"type": "shell",
"echoCommand": true,
"tasks": [
{
"label": "Build project",
"command": "make",
"args": [
"all",
"GCC_PATH=C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\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"
}
]
}
.vscode\launch.json (デバッグの設定)
.vscode
内にlaunch.json
というファイルを作成し、以下の内容を記述して保存します。
ここではVSCodeのデバッグの設定をします。
以下はST-linkとOpenOCDを用いてNucleo F4ボードのデバッグをする場合の設定の一例です。
preLaunchTask
にはtasks.json
で設定したプロジェクトのコンパイルを実行するタスクを指定します。
armToolchainPath
にはGNU ARM Embedded Toolchainのパスを指定します。
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": [
"board/st_nucleo_f4.cfg"
],
"armToolchainPath": "C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\bin\\",
"serverpath": "C:\\tools\\OpenOCD\\0.10.0-12-20190422-2015\\bin\\openocd.exe"
}
]
}
STM32F4単体の場合
configFiles
の部分を以下のように変更します。
STM32F0シリーズやF2シリーズなどを使用する場合もマイコンの型番に合わせてこの部分を変更します。
"configFiles": [
"interface/stlink-v2-1.cfg",
"target/stm32f4.cfg"
],
J-linkを使用する場合
J-linkを使用する場合は以下のような設定をします。
device
で使用するマイコンの設定をします。
{
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"cwd": "${workspaceRoot}",
"executable": "${workspaceFolder}\\build\\${workspaceFolderBasename}.elf",
"request": "launch",
"type": "cortex-debug",
"preLaunchTask": "Build project",
"armToolchainPath": "C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\bin\\",
"serverpath": "C:\\Program Files (x86)\\SEGGER\\JLink\\JLinkGDBServerCL.exe",
"servertype": "jlink",
"device": "STM32F446RE",
"interface": "swd"
}
]
}
ソースファイルの追加 (Makefileの編集)
CubeIDEのようなIDEと違い、VSCodeではソースファイルを追加しても自動でコンパイル対象に追加される仕組みは無いので、手動で設定をする必要があります。
ソースファイルを追加したらMakefile
のsource
と書かれた場所に以下の例を参考に追加したファイルの設定を追加します。
次の行に続く場合は\
を最後につけ忘れないようにしましょう。
$(wildcard Core/Src/*.c) \
のように特定のフォルダ以下のファイルを全て一気に追加することもできます。
(前略 だいたい35行目くらいにsourceの項目があるはず)
######################################
# source
######################################
# C sources
C_SOURCES = \
自分で追加したソースファイル1.c \
自分で追加したソースファイル2.c \
自分で追加したソースファイル3.c \
Core/Src/main.c \
Core/Src/stm32f4xx_it.c \
Core/Src/stm32f4xx_hal_msp.c \
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \
(以下省略)
ビルドの実行
ビルドの実行はCtrl
+Shift
+B
を押してビルドタスクを選択して実行します。
デバッグの実行
デバッグの実行はF5
を押して実行します。
正しく設定ができていればマイコンへの書き込みが行われ、ブレークポイントなどの機能を使うこともできるはずです。
便利な機能
使用率の表示
RAMやROMの使用率を表示するには以下の設定をしておくと便利。
Makefile
内のLDFLAGS
の末尾に,-print-memory-usage
を追加する。
# libraries
LDFLAGS = $(MCU) -specs=nano.specs <中略> ,-print-memory-usage
printfでfloatの表示
printf
でfloat
を使う場合は次の設定を行う。
Makefile
内のLDFLAGS
に -u_printf_float
を追加する。
# libraries
LDFLAGS = $(MCU) -specs=nano.specs -u_printf_float -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections,-print-memory-usage
.vscode\c_cpp_properties.json
必須ではないが設定しておくとintellisenseが機能するようになるので便利。
{
"configurations": [
{
"name": "STM32",
"includePath": [
"${workspaceFolder}/**",
"C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\arm-none-eabi\\include**",
"C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\lib\\gcc\\arm-none-eabi\\9.2.1\\include"
],
"defines": [
"USE_HAL_DRIVER",
"STM32F446xx",
"__weak=__attribute__((weak))"
],
"compilerPath": "C:\\tools\\gcc-arm-none-eabi-9-2019-q4-major-win32\\bin\\arm-none-eabi-gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}