この記事で知りたいこと
Arduinoのライブラリでよく見るボード依存でコンパイル時にコード内容を分岐させる。
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560)
// ARDUINO UNOかARDUINO MEGA2560をボード選択した時にコンパイルされる部分
#endif
#if defined(ARDUINO_AVR_LEONARDO)
// ARDUINO Leonardoをボード選択した時にコンパイルされる部分
#endif
void setup() {
}
void loop() {
}
みたいな書き方が便利なのでIDE上のボード選択に依存してコンパイル内容が変わる機能を
自分のコードにも入れてみたい。
でも、そもそもARDUINO_AVR_UNO
みたいなやつ、どんな文字列が定義されるのかわからない。
特にArduino公式のボードでない場合は既存のライブラリの記述から探すのも難しい。
この記事ではこの文字列の正体を探す。
検証環境
- Windows10
- Arduino IDE 1.8.13
結論
各Arduinoボードのコンパイル時に必要なパラメータを格納した
boards.txt
の中の
{ボード名}.build.board={ボード名}
の値を探してきて、右辺値を
ARDUINO_
の後ろにくっつける
ARDUINO_{ボード名}
こんな感じ
ちなみにコンパイル時にコンパイラに渡す文字列から生成してるみたいで、いくらソースコードの中を探しても見当たらないみたいです。
例えば
Arduino UNO の場合
ボード周りのライブラリがインストールされているフォルダを探し、
C:\Users\{$USERNAME}\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.4
の
(↑AppDataは隠しフォルダ)
boards.txt
の中に
uno.build.board=AVR_UNO
という記述があるので、このAVR_UNO
を使って
ARDUINO_AVR_UNO
というマクロ定義文字列を処理の分岐に使用する。
Seeeduino XIAO の場合
ボード周りのライブラリがインストールされているフォルダを探し、
C:\Users\{$USERNAME}\AppData\Local\Arduino15\packages\Seeeduino\hardware\samd\1.8.1
の
(↑AppDataは隠しフォルダ)
boards.txt
の中に
seeed_XIAO_m0.build.board=SEEED_XIAO_M0
という記述があるので、このSEEED_XIAO_M0
を使って
ARDUINO_SEEED_XIAO_M0
というマクロ定義文字列を処理の分岐に使用する。
検証コードの例
マクロ定義文字列があってるかどうか確かめるだけなので、実際にボードに書き込む必要はありません。
下記コードをスケッチに張り付けてIDEの「検証」ボタンを押します。
(#pragma message
はArduino IDEが使っているコンパイラavr-gccの機能です)
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560)
#pragma message "\n >> ARDUINO_AVR_UNO or ARDUINO_AVR_MEGA2560 is defined."
#endif
#if defined(ARDUINO_AVR_LEONARDO)
#pragma message "\n >> ARDUINO_AVR_LEONARDO is defined."
#endif
#if defined(ARDUINO_SEEED_XIAO_M0)
#pragma message "\n >> ARDUINO_SEEED_XIAO_M0 is defined."
#endif
#if defined(ARDUINO_RASPBERRY_PI_PICO)
#pragma message "\n >> ARDUINO_RASPBERRY_PI_PICO is defined."
#endif
void setup() {
}
void loop() {
}
ボードを「Leonardo」選択状態でコンパイルしたときのIDEのコンパイラメッセージ
C:\Users\{$USERNAME}\Documents\Arduino\sketch_aug08a\sketch_aug08a.ino:6:19: note: #pragma message:
>> ARDUINO_AVR_LEONARDO is defined.
#pragma message "\n >> ARDUINO_AVR_LEONARDO is defined."
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
最大28672バイトのフラッシュメモリのうち、スケッチが3462バイト(12%)を使っています。
最大2560バイトのRAMのうち、グローバル変数が149バイト(5%)を使っていて、ローカル変数で2411バイト使うことができます。
あとはマクロの機能で
#ifdef ARDUINO_HOGE
#ifndef ARDUINO_FUGA
#if define(ARDUINO_FOO)
とかそのあたりをうまく使ってコンパイラに判断させましょう。
その他
この話の情報ソース
Arduino IDEの1.5.3 BETAのリリースノート
ARDUINO 1.5.3 BETA - 2013.08.30
[ide]
~~
Pass board type from boards.txt (https://github.com/arduino/Arduino/issues/308)
このリリースノートの記述とGithubのissueが公式ソースってことになるんでしょうか。
仕様についてはもうちょっと情報まとめておいてほしいですけど・・・。
参考ライブラリ
今回の調査の過程で見つけたんですが、自分でboards.txt
を探さなくても分岐処理用のヘッダファイルを公開してくれている方もいるようです。
https://github.com/houtbrion/detectArduinoHardware
(最近はArduino IDE互換のボードが増えすぎてるので網羅とはいってないようですが)
その他
間違い等ありましたらご指摘ください。