macのvscode+cliでm5stackのファームを開発できる環境を作る

m5stackのプログラムを1つ書くことになった。Arudino IDEはエディタとしては使いづらいのでvscodeでコードを書けるようにしたい。 ここではvscodearduino ideの設定を作るまでの過程を残していく。

前提条件

以下の環境を前提にしている

  • macOS Caatalina 10.15.17
  • Aruduino IDE 1.8.10
  • vscode 1.51.1
  • M5Stack Basic

Arduino IDEでM5Stackの開発ができるようにする

vscodeで開発をできる状態を作る前にまずはArduino IDEで開発をできるようにする必要がある。 詳細は公式の情報を見てセットアップをしてほしい。 https://docs.m5stack.com/#/en/arduino/arduino_development

成功するとArduino IDEのシリアルポートの項目に/dev/cu.SLAB_USBtoUARTという項目が現れ、 ボードにM5Stack-Core-ESP32が選択できるようになる。

f:id:masarusanjp:20201124182904p:plain
ボードとシリアルの設定をした後のarduino ideの状態

この状態でArduino IDE上で→ボタンを押すとコンパイルと転送行われM5Stackへの書き込みが成功すればOK

VSCodeArduino開発が行えるようにする

Arduino拡張機能のインストール

vscodeを開き、Arduinoの拡張をインストールする。Arudinoの拡張はMicrosoftが出しています。 Arduinoで検索すると複数の拡張が出てくるがMicrosoftのものを選択しインストールします。

f:id:masarusanjp:20201126115810p:plain
Arduino拡張機能

Arduino拡張機能の設定

メニューの[Code] > [Preferences] > [Settings]の順にクリックし、設定画面を開く。 右上隅にある[Open Settings (JSON)]アイコンを選択肢、JSONで設定を編集できるようにする。

f:id:masarusanjp:20201126115900p:plain
Arduino拡張機能の設定

次の行を追加する。

"arduino.path": "/Applications”,

arduinoのパスとC拡張のインテリセンスエンジンのモードを変えている。 2020.12.9に変更。 arduinoのパスを設定するのみ。 インテリセンスエンジンをTag Parserにする必要があるとの記事がいくつかあったが、私の環境ではTag Parserにするとインテリセンスが正常に動かなくなってしまっていた。

プロジェクトを作成しボードとシリアルポートの設定を行う

適当なディレクトリをvscodeで開き、ディレクトリ名と同じ名前でinoファイルを作成する。同じ名前にする必要があるのは後述するarduino-cliに対応させるため。

f:id:masarusanjp:20201126120019p:plain
VSCodeでプロジェクトを作成

次に、[Command + Shift + P] でコマンドパレットを開き、Boardと入力。Arduino: Board Configを開き、Selected BoardM5Stack-Core-ESP32にする。 同様にコマンドパレットからSelect Serial Portを選択し/dev/tty.SLAB_USBtoUARTを選択する。 フッターが以下のような表示になる。またフッターの該当の箇所をクリックしても設定を行うことができる。

f:id:masarusanjp:20201126120054p:plain

2020.12.9に追記。

.vscode/c_cpp_properties.jsonincludePathdefinesに手を加える。

includePath

            "includePath": [
                "${workspaceRoot}",
                "${env:HOME}/Library/Arduino15/packages/esp32/tools/**",
                "${env:HOME}/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/**",
                "${env:HOME}/Documents/Arduino/libraries/**"
            ],

defines

            "defines": [
                "ESP32",
                "USBCON"
            ],

includePathにはworkspaceRootを付け足したのと、おそらくあったであろう"/Applications/Arduino.app/Contents/Java/libraries/**"を削除している。 削除しているのはesp32で定義されているクラスとArduino.app以下で定義されているクラスが競合しているため。 ついでにHOMEのパスが絶対パスで書かれていたのを${env:HOME}に変えているが通常は不要そうである。

definesESP32を追加する。M5Stack.hESP32がdefineされていないと定義が有効にならないため。 これをやらなくても済む方法があるような気がするが。。 このようなdefine,他に必要なものはあるのかな?ということで$HOME/Library/Arduino15/packages/esp32/hardware/esp32/$version/platform.txtを確認したが、ESP32が追加されていれば大丈夫そうであった。 ちなみにbuild.extra_flags=-DESP32 -DCORE_DEBUG_LEVEL={build.code_debug} {build.defines}というところに書かれていて、CORE_DEBUG_LEVELは気にしなくて良さそうだし、build.definesは空っぽだったので問題はなさそう。

M5Stackへの書き込みを行う

右上隅の[Arduino: Upload]アイコンを選択するとコンパイルが行われ、M5Stackへの書き込みが行われる。

f:id:masarusanjp:20201126120204p:plain

コマンドラインから書き込みを行う

前項まででvscodeで開発を行う環境を整えられた。 これに加えて、いくつかのプリプロセッサデバッグ時のみ有効にする等の制御を行うためにコマンドラインからビルドを行いたい。 そのためにarduino-cliというツールを使う。 https://arduino.github.io/arduino-cli/latest/

arduino-cliのインストール

$ brew install arduino-cli

arduino-cliによるコンパイルとアップロード

コンパイルは以下のコマンドで行える。

arduino-cli compile -b esp32:esp32:m5stack-core-esp32 your-directory-name

-bで書き込み対象のボードのfqbnを書く。このfqbnは.vscode/arduino.json > boardに書かれている内容を使っている。arduino-cliを使っても取れると思うのだが、うまく取得できなかったので、追って調査する。 もう1つの注意点はプロジェクトのディレクトリ名とinoファイル名の名前を一致させる必要があること。 コンパイルに成功すると、buildディレクトリ以下に成果物が出力される。

アップロードは以下のコマンド。

arduino-cli upload -b esp32:esp32:m5stack-core-esp32 -p /dev/cu.SLAB_USBtoUART

compileが成功し、build以下に成果物があればアップロードがされる。

これらを以下のようにMakefileにまとめた。

ARDUINO := arduino-cli
BOARD := esp32:esp32:m5stack-core-esp32
PORT := /dev/cu.SLAB_USBtoUART
PROJECT := $(shell basename "$$PWD")
BOARD_IN_PATH := $(subst :,.,$(BOARD))
PROJECT_DIR := $(abspath .)
DEFINES := -DDEBUG
BUILD_PROPERTIES = "build.defines=$(DEFINES)"

.PHONY: compile
compile:
$(ARDUINO) compile -b $(BOARD) 
--build-properties $(BUILD_PROPERTIES) 
$(PROJECT_DIR)

.PHONY: upload
upload:
$(ARDUINO) upload -b $(BOARD) -p $(PORT) -t $(PROJECT_DIR)

.PHONY: clean
clean:
rm -rf $(PROJECT_DIR)/build

.PHONY: all
all: compile upload clean

.DEFAULT_GOAL := all

これでコマンドラインからcompile and installができるようになった