Contents
1. 全体像とメリット
| 項目 | 内容 |
|---|---|
| OS 基盤 | Windows 11 + WSL2(Linux カーネル上で動作) |
| ディストリビューション | Ubuntu 22.04 LTS(2022 年 4 月リリース、2027 年まで長期サポート) |
| 主なツールチェーン | gcc-arm-none-eabi、make、openocd、gdb-multiarch |
| IDE/エディタ | Visual Studio Community 2022(C/C++ デスクトップ開発)・VS Code(Remote‑WSL 拡張) |
| バージョン管理 | Git for Windows |
| USB デバッグ | usbipd-win を用いた WSL2 への USB 転送 |
メリット
- Windows の GUI と Linux のビルドツールを同時に利用でき、環境切り替えが不要。
- Ubuntu の公式リポジトリはセキュリティパッチとバグフィックスが定期的に提供されるため、常に「最新」ではなく「安定」した状態で開発できる。
- VS Code の Remote‑WSL により、エディタ側から直接 Linux ツールチェーンを呼び出すことができ、生産性が向上する。
2. 前提条件と必須ソフト
| カテゴリ | 必要なもの |
|---|---|
| OS | Windows 11 (Pro/Enterprise が推奨) |
| 仮想化機能 | 「Virtual Machine Platform」および「Windows Subsystem for Linux」機能を有効化 |
| WSL2 ディストリビューション | Ubuntu 22.04 LTS(2022 年版) |
| 開発ツール | Git for Windows、Visual Studio Community 2022、VS Code |
| USB 転送ユーティリティ | usbipd-win(Windows 用 USBIP デーモン) |
注記:本稿ではすべてのインストール手順を PowerShell と Ubuntu ターミナルで実行する前提で説明します。
3. WSL2 と Ubuntu 22.04 のセットアップ
3.1 Windows 側の準備
|
1 2 3 4 5 6 7 |
# 管理者権限で実行 dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart # 再起動を促す(必要なら手動で実施) Write-Host "再起動後に続行してください。" |
3.2 Ubuntu 22.04 のインストール
|
1 2 3 4 |
# PowerShell (管理者) から直接インストール wsl --install -d Ubuntu-22.04 # インストール完了後、初回起動時にユーザー名とパスワードを設定 |
ポイント
Ubuntu 22.04 は 2022 年 4 月 にリリースされた LTS バージョンです。5 年間の標準サポート(2027 年まで)と、追加で 5 年間の ESM(Extended Security Maintenance)が提供されます。
3.3 Ubuntu 側で基本ツールを最新化
|
1 2 3 |
# 初回起動後に実行 sudo apt update && sudo apt upgrade -y |
4. 開発ツールチェーンのインストール
|
1 2 3 4 5 |
# 必要なパッケージを一括でインストール sudo apt install -y build-essential \ gcc-arm-none-eabi gdb-multiarch openocd cmake git \ libnewlib-arm-none-eabi python3-pip usbip |
gcc-arm-none-eabiは ARM Cortex‑M 系マイコン向けのクロスコンパイラです。openocdとusbipは USB デバッグアダプタを WSL2 から利用するために必須です。
インストール結果確認
|
1 2 3 |
arm-none-eabi-gcc --version # 10.3.1 以上が期待されます openocd --version # 0.12.0 以降推奨 |
5. IDE と WSL2 の連携設定
5.1 VS Code – Remote‑WSL の構成
- VS Code をインストールし、拡張機能マーケットプレイスから Remote - WSL を追加。
- 左下の緑色アイコン → “New Window using Distro” →
Ubuntu-22.04を選択。 - 新しいウィンドウが Ubuntu のファイルシステムにマッピングされるので、
code .と入力すれば同じフォルダが VS Code に表示されます。
ヒント:Remote‑WSL ではターミナルも自動的に Linux 環境になるため、パスの混在エラーを防げます。
5.2 Visual Studio Community 2022 の統合(汎用設定)
Visual Studio は Windows 側で実行されるので、WSL2 上のツールチェーンへは wsl.exe を介して呼び出す形にします。ハードコードされたディレクトリパスではなく、環境変数と wslpath コマンドを組み合わせて動的に解決できるように設定してください。
- プロジェクト → プロパティ → VC++ ディレクトリ → 実行可能ファイルディレクトリ
text
$(WslRoot)\usr\bin
$(WslRoot)は次のコマンドで取得できます(PowerShell 例)
powershell
$wslRoot = wsl.exe wslpath -u "$env:USERPROFILE\AppData\Local\Packages\CanonicalGroupLimited..."
- 外部ツール を追加し、以下のように設定
- タイトル:
WSL Make - コマンド:
wsl.exe - 引数:
make -C $(ProjectDir)
この構成なら、Visual Studio のビルドボタンだけで Ubuntu 上の make が実行されます。Windows と Linux のパスが混在しない点に注意してください。
6. USB デバイス(ST‑LINK/V2 等)を WSL2 に転送する手順
6.1 Windows 側で usbipd-win をインストール
|
1 2 3 4 |
# winget が利用できる環境の場合 winget install --id=SimonSiefke.usbipd-win -e # または MSI パッケージを公式サイトから取得して実行 |
管理者権限 が必要です。インストール後、PC を再起動してください。
6.2 デバイスの列挙とバインド
|
1 2 3 4 5 6 |
# 接続された USB デバイス一覧を表示 usbipd list # 例: BusID が "1-2" の ST‑LINK をバインド(WSL に公開) usbipd bind -b 1-2 |
6.3 WSL2 側でデバイスをアタッチ
|
1 2 3 4 5 6 |
# カーネルモジュールのロード sudo modprobe vhci_hcd # バス ID を指定して USBIP デバイスを接続 sudo usbip attach -r 127.0.0.1 -b 1-2 |
6.4 接続確認
|
1 2 3 |
ls /dev/tty* # ST‑LINK がシリアルデバイスとして見えるか確認 dmesg | tail -n 20 # カーネルメッセージにエラーが無いかチェック |
トラブルシューティング
「cannot open USB device」 エラーが出た場合は、Windows 側でデバイスが別プロセス(例:ST‑Link Utility)にロックされていないか確認し、必要ならそのアプリを終了してください。
7. ビルドフローの実装例
7.1 ディレクトリ構成
|
1 2 3 4 5 6 7 8 9 10 |
my-embedded/ ├─ .vscode/ # VS Code 用設定ファイル │ ├─ launch.json │ └─ tasks.json ├─ src/ # ソースコード │ └─ main.c ├─ include/ # ヘッダーファイル(必要に応じて) ├─ Makefile └─ stm32f429.ld # リンカスクリプト(例示用) |
7.2 完全版 Makefile
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# ------------------------------------------------- # クロスコンパイラ設定 # ------------------------------------------------- CC := arm-none-eabi-gcc OBJCOPY := arm-none-eabi-objcopy GDB := arm-none-eabi-gdb CFLAGS := -mcpu=cortex-m4 -mthumb -O2 \ -Wall -ffunction-sections -fdata-sections \ -nostdlib -nostartfiles LDFLAGS := -Tstm32f429.ld -Wl,--gc-sections # ------------------------------------------------- # ソース・オブジェクト管理 # ------------------------------------------------- SRCS := $(wildcard src/*.c) OBJS := $(SRCS:.c=.o) TARGET_ELF := build/led_blink.elf TARGET_BIN := build/led_blink.bin # ------------------------------------------------- # ビルドルール # ------------------------------------------------- .PHONY: all clean flash debug all: $(TARGET_BIN) $(TARGET_ELF): $(OBJS) @mkdir -p $(dir $@) $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(TARGET_BIN): $(TARGET_ELF) $(OBJCOPY) -O binary $< $@ # デバッグ用に GDB を起動(OpenOCD がバックエンド) debug: all $(GDB) -ex "target remote localhost:3333" \ -ex "monitor reset halt" \ -ex "load $(TARGET_ELF)" \ -ex "continue" # OpenOCD 経由で書き込み(USB デバイスが接続されている前提) flash: $(TARGET_BIN) sudo openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \ -c "program $< verify reset exit" clean: rm -rf build/*.elf build/*.bin src/*.o |
解説
-CFLAGSに-nostdlib -nostartfilesを入れることで、組込み向けの最小構成バイナリが生成されます。
-debugターゲットは VS Code のタスクから呼び出すことを想定しています。
7.3 VS Code 用デバッグ設定
.vscode/launch.json
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "version": "0.2.0", "configurations": [ { "name": "(gdb) STM32F4 Debug", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/led_blink.elf", "miDebuggerPath": "/usr/bin/arm-none-eabi-gdb", "miDebuggerServerAddress": "localhost:3333", "cwd": "${workspaceFolder}", "externalConsole": false, "preLaunchTask": "OpenOCD" } ] } |
.vscode/tasks.json
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "version": "2.0.0", "tasks": [ { "label": "OpenOCD", "type": "shell", "command": "sudo openocd -f interface/stlink.cfg -f target/stm32f4x.cfg", "isBackground": true, "problemMatcher": [] } ] } |
8. サンプルコードと実機書き込み
8.1 LED 点滅サンプル(src/main.c)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include "stm32f4xx.h" static void delay(volatile uint32_t cnt) { while (cnt--) { __NOP(); } } int main(void) { /* GPIOA クロック有効化 */ RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; /* PA5 を出力に設定(LED が接続されている典型的なピン) */ GPIOA->MODER &= ~(0x3U << (5 * 2)); GPIOA->MODER |= (0x1U << (5 * 2)); while (1) { GPIOA->ODR ^= (1U << 5); // LED トグル delay(500000); } } |
8.2 ビルド・書き込み手順
|
1 2 3 4 5 6 |
# ビルドとバイナリ生成 make all # OpenOCD 経由でマイコンへ書き込む(USB デバッグアダプタが認識されていること) make flash |
実行結果
書き込みが成功すると、対象ボード上の LED が約 0.5 秒間隔で点滅します。
9. よくある問題と対策
| 症状 | 原因例 | 解決策 |
|---|---|---|
openocd: cannot open USB device |
WSL2 がデバイスを認識していない | Windows 側で usbipd list → 正しい BusID を bind → WSL で modprobe vhci_hcd && usbip attach … |
| ビルド時に「/usr/bin/arm-none-eabi-gcc が見つからない」 | PATH が破損または apt install が失敗 |
sudo apt reinstall gcc-arm-none-eabi → 再度 which arm-none-eabi-gcc |
| VS Code のタスクが「permission denied」 | openocd を sudo で実行しないとデバイスにアクセスできない |
タスク定義の command に sudo を付与し、WSL2 側で sudo visudo → NOPASSWD: /usr/bin/openocd を許可 |
| デバッグ時に GDB が接続できない | OpenOCD のポート 3333 が別プロセスで使用中 | sudo lsof -i:3333 で占有プロセスを特定し、停止させるかポート番号を変更 |
10. まとめと次のステップ
- 環境構築:Windows 11 → WSL2 + Ubuntu 22.04 LTS → 必要パッケージ (
gcc-arm-none-eabi・openocd…) をインストール。 - IDE 連携:VS Code の Remote‑WSL と Visual Studio の
wsl.exeラッピングでシームレスに開発。 - USB デバッグ:
usbipd-win→usbipによるデバイス転送手順を踏み、OpenOCD がマイコンへアクセスできるように設定。 - ビルド・フロー:Makefile でクロスコンパイルと書き込みタスクを一元管理し、VS Code の
launch.json/tasks.jsonと連携させる。 - サンプル実行:LED 点滅コードをビルド・フラッシュすれば、即座にハードウェア上で動作確認が可能。
この手順を踏めば、Windows 環境だけで完結した「C 言語 組込み開発」の入門体験が実現できます。次は以下のテーマへ挑戦してみてください。
- RTOS(FreeRTOS) を組み込んだマルチタスク例
- 外部ライブラリ(CMSIS‑DSP, FatFS) のビルド統合
- CI/CD パイプライン(GitHub Actions + WSL2)による自動テスト
最後に:本稿は Windows 11 と Ubuntu 22.04 LTS を前提にしていますが、WSL1 や別ディストリビューションでも概ね同様の手順で構築できます。環境に合わせてパッケージ名やデバイス転送方式を調整してください。
参考リンク
- Ubuntu 22.04 LTS 公式ページ: https://releases.ubuntu.com/22.04/
- Microsoft WSL2 ドキュメント: https://learn.microsoft.com/windows/wsl/about
usbipd-winGitHub: https://github.com/dorssel/usbipd-win- OpenOCD 公式サイト: http://openocd.org/
Happy hacking! 🚀