VSCode + PlatformIOでWio BG770Aを開発する:platformio.iniの設定が何をしているか解説

これまでWio BG770AでSORACOMや1NCEに接続をする検証を行ってきました。 SORACOMのエンジニアの方が書いたZennの記事を参考にPlatformIO + VSCodeの環境を構築したところ、Wio BG770Aへの書き込みまでスムーズにできました。

ただ、platformio.iniに書いた設定が何を意味しているかは理解できていないまま進めていたので、一度理解を深めるためにPlatformIOの設定について調査しました。

この記事では、PlatformIOの設定の意味とVSCode + PlatformIOが便利な点を紹介します。

IoTデバイスのコードもVSCodeで書きたい

IoT開発ではデバイスのコードだけでなく、クラウドインフラ(AWS CDKやTerraform)のコードも同じリポジトリで管理したいケースがあります。 例えば、センサーで取得したデータをAWS上で保存、分析したい時に、AWS IoT CoreとAmazon Timestream(時系列データベースサービス)をセットアップしたい時にはCDKでインフラ管理ができると便利です。

Arduino IDEのような専用IDEだと、IoTデバイスの開発はArduino IDE、クラウドインフラコードの開発はVSCodeのように開発環境が分かれてしまう点がイマイチでした。

また、最近だとClaude CodeやCodexなどのコーディングエージェントは開発に欠かせませんが、この手のツールはターミナルで動かすことが前提です。 VSCodeにはエディタに統合されたターミナルがあり、他の環境に移るのはさらに腰が重く感じていました。

これを実現するのがPlatformIOです。 VSCode拡張機能としてインストールするだけで、IoTデバイスのビルド・書き込み・シリアルモニタがVSCode上から操作できるようになります。

PlatformIOとは

PlatformIOは、PlatformIO Labs社によって開発された組み込み開発向けのオープンソースエコシステムです。2014年頃にPython製のCLIツールとして登場しました。

PlatformIO Homeの画面
PlatformIO Home画面

Arduino IDEの課題(依存管理の煩雑さ・環境再現性のなさ・CI対応の弱さ)を解決し、「組み込み開発をソフトウェア開発の水準に引き上げる」ことを目的として作られています。

特徴は、複数のチップファミリーやフレームワークを統一された環境で扱えることです。Arduino・ESP-IDF・Mbed・MicroPythonなど、異なるフレームワークを同じVSCode拡張から使えます。対応ボードは1,200以上あります。

ただし対応状況はボードによって異なります。ESP32やArduino(AVR)のような主要プラットフォームは公式レジストリに登録されていますが、Wio BG770AのようなニッチなデバイスはメーカーがGitHubにplatformを公開して対応しています。 Arduino IDEであればメーカーサポートがほぼ確実なのに対して、PlatformIOはデバイスによります。

Arduino IDEPlatformIO + VSCode
メーカーサポートほぼ確実デバイスによる
補完・ジャンプ弱い強い
ターミナル統合なしあり
他コードとの共存難しいしやすい

platformio.iniの設定が何をしているか

PlatformIOのプロジェクトでは、platformio.iniで環境を定義します。

以下のWio BG770A開発で使っているplatformio.iniを参考にして、各設定を順に説明します。

[env:seeed_wio_bg770a]
platform = https://github.com/SeeedJP/platform-nordicnrf52
platform_packages =
    framework-arduinoadafruitnrf52 @ https://github.com/SeeedJP/Adafruit_nRF52_Arduino.git
framework = arduino
board = seeed_wio_bg770a
build_flags =
    -DBOARD_VERSION_1_0 ; Board version 1.0
    -DCFG_LOGGER=3      ; 3:None, 2:Segger RTT, 1:Serial1, 0:Serial
lib_archive = no ; https://github.com/platformio/platform-nordicnrf52/issues/119
lib_deps =
    seeedjp/WioCellular
monitor_speed = 115200

platform・board・framework の関係

この3つが、ビルド環境の中核です。

platform = https://github.com/SeeedJP/platform-nordicnrf52
framework = arduino
board = seeed_wio_bg770a

それぞれの役割は以下の通りです。

設定役割
platformチップファミリー向けのツールチェーン一式(コンパイラ・リンカ等)
boardそのチップを搭載した特定ボードの定義(ピン配置・メモリ・クロック等)
frameworkチップの違いを吸収し、digitalWrite()Serialなどの共通APIでコードを書けるようにする層

Wio BG770AはNordic nRF52840を搭載しているため、platformはnordicnrf52系になります。 ただし公式レジストリではなく、SeeedJPがGitHubに公開しているforkをURL直指定しています。

forkの主な変更点は、Wio BG770A用のboard定義の追加です。board定義にはピン配置・フラッシュ/RAMサイズ・クロック周波数などが記述されており、PlatformIOがこのボード向けにビルドするために必要な情報です。公式のnordicnrf52リポジトリにはWio BG770Aの定義が含まれていないため、SeeedJPがforkして追加しています

補足として、PlatformIOがビルドするのはnRF52840上で動くArduinoコードのみです。BG770A(LTEモデム側)はUART経由でATコマンドを受け取るだけで、PlatformIOのビルド対象外です。

platform_packages

platform_packages =
    framework-arduinoadafruitnrf52 @ https://github.com/SeeedJP/Adafruit_nRF52_Arduino.git

platformの内部パッケージを上書きする設定です。パッケージ名 @ 取得元という構文で、「このパッケージをレジストリではなくここから取得する」という意味です。lib_depsでのバージョン指定(library@^1.0.0)と同じ@ですが、こちらはURLを指定しています。

ここではArduinoコア(setup()loop()などのArduino APIをnRF52上で動かすライブラリ)をSeeedJPのforkに差し替えています。

このArduinoコアはAdafruitが開発・メンテしているもので、nRF52向けArduinoコアとして広く使われている実装の一つです。SeeedJPはこれをforkしてWio BG770A固有のボード設定を追加しています。そのため、公式のAdafruit版ではなくSeeedJP版を指定する必要があります。

build_flags

build_flags =
    -DBOARD_VERSION_1_0
    -DCFG_LOGGER=3

コンパイラに渡すフラグです。-Dはプリプロセッサマクロの定義で、C/C++コード内で#ifdef BOARD_VERSION_1_0のように参照できます。

CFG_LOGGER=3は使用しているArduinoコア(Adafruit/Seeed系)が出すログ(起動メッセージ・アサート・クラッシュレポートなど)の出力先を設定するもので、3はログなしを意味します。デバッグ時は1(Serial1)や2(Segger RTT)に変更して使います。Arduino標準のマクロではなく、このArduinoコア実装に依存する設定です。

ユーザーコードのSerial.printf()はこの設定の影響を受けないため、CFG_LOGGER=3でもシリアルモニタでの出力は通常通り動作します。

lib_archive

lib_archive = no

ライブラリのコンパイル済みオブジェクトを.aファイル(静的ライブラリ)にまとめるかどうかの設定です。有効にするとビルドが高速化します。ライブラリのソースコードはプロジェクトのコードが変わっても変化しないため、一度.aにまとめておけば次回以降はリンクするだけで済むためです。

通常はデフォルト(有効)のままで問題ありませんが、nordicnRF52プラットフォームの既知の不具合でこの処理にバグがあり正常にビルドできないケースがあります。noにすることで毎回コンパイルする方式に戻し、回避しています。

lib_deps

lib_deps =
    seeedjp/WioCellular

使用するライブラリをここに書きます。npmのdependenciesと同じ概念で、pioコマンド実行時に自動でダウンロード・インストールされます。seeedjp/WioCellularPlatformIOのレジストリに登録されているSeeedJPのライブラリです。

npmなどのパッケージマネージャはインストール時にバージョンが自動で固定されますが、PlatformIOはデフォルトではされません。バージョン未指定の場合の挙動は以下の通りです。

状況挙動
同じ環境で再ビルド.pioキャッシュが使われ固定される
別環境・CI最新版が解決される可能性がある

環境が変わると依存バージョンが変わる可能性があるため、再現性のためにバージョン固定が必要です。固定したい場合は以下のように書きます。

lib_deps =
    seeedjp/WioCellular@^0.3.13  ; semver
    seeedjp/WioCellular@0.3.13  ; 完全固定

monitor_speed

monitor_speed = 115200

シリアルモニタ(PC側)のボーレートです。デバイス側のコードで設定するボーレートと一致させる必要があります。

void setup() {
    Serial.begin(115200);  // この値とmonitor_speedを合わせる
}

値が異なると文字化けします。

よく使う操作

VSCodeの左下にあるPlatformIOのボタンから主な操作ができます。

VSCode左下のPlatformIOアイコン(Build/Upload/Serial Monitor)
VSCode左下のPlatformIOアイコン。左からBuild・Upload・Serial Monitor
ボタン動作
Uploadビルドしてデバイスに書き込む
Serial Monitorシリアルモニタを開く(monitor_speedで設定したボーレートを使用)

ターミナルからpioコマンドで操作することもできます。Terminalアイコンをクリックすればすぐに使えます。

pio run           # ビルド
pio run -t upload # ビルド + 書き込み
pio device monitor # シリアルモニタ

バージョン固定について

lib_depsはsemverで固定できますが、platformはGitHub URLの直指定のため、コミットハッシュを指定しないと最新コミットが使われます。

; コミットハッシュで固定する例
platform = https://github.com/SeeedJP/platform-nordicnrf52#abc1234

npmのような自動lockfile生成の仕組みはないため、platformio.iniに明示的に書くのが固定の方法になります。

; 完全に固定する場合
platform = https://github.com/SeeedJP/platform-nordicnrf52#abc1234
platform_packages =
    framework-arduinoadafruitnrf52 @ https://github.com/SeeedJP/Adafruit_nRF52_Arduino.git#def5678
lib_deps =
    seeedjp/WioCellular@1.0.0

本番運用やチーム開発では固定を検討する価値があります。

まとめ

この記事では、VSCode + PlatformIOを選んだ理由と、Wio BG770A開発で使うplatformio.iniの各設定を紹介しました。

platformio.iniの設定は最初は意味がわかりにくいですが、platformがツールチェーン、boardが特定ボードの定義、frameworkがチップの違いを吸収して共通APIでコードを書けるようにする層、という関係を理解しておくと読みやすくなります。

実際にWio BG770AでPlatformIOを使って、ATコマンドを動かした時の記事はこちらです。 ATコマンドを受け付けるコード(スケッチ)をUploadして、Serial Monitor経由でATコマンドを打ってと今回紹介した機能が活躍しています。

関連記事