Arduinoの出力バイナリを眺める会
月曜にはWioTerminalとMaix Amigoが届いちゃうので、それぞれのArduino環境でビルドされるバイナリを眺めてSDK作りの参考にしたい。
... 実はESP32とRaspberryPi Picoも届くんだけど、これらはちゃんとした(CMakeベースの)C SDKがあるのでSDKのコンテンツを眺めるだけで十分な情報が得られる。Arduinoはビルドを抽象化しているのでビルドされるバイナリの実物を見ないと安心できない。
WioTerminal
スケッチのバイナリを取得するには、 "スケッチ" → "コンパイルしたバイナリを出力" 。WioTerminalの場合は直接.binを書き込んでいるようだ。
$ file Blink.ino.wio_terminal.bin
Blink.ino.wio_terminal.bin: data
... HEXと違って.bin、つまり生バイナリではどのアドレスに書いているか判らないので直接 TEMP
見るか。。
oku@stripe /cygdrive/c/Users/oku/AppData/Local/Temp/arduino_build_302759
$ ls
Blink.ino.bin* Blink.ino.hex* build.options.json* includes.cache* preproc/
Blink.ino.elf* Blink.ino.map* core/ libraries/ sketch/
マップファイルをアップロードしてみた。
容量削減のため、ArduinoCoreを含めた全体がソースコードからビルドされていて、dead code strip用に1関数1セクションになっていることがわかる。この辺の指定は、ArduinoCoreがわにある。
compiler.c.flags=-mcpu={build.mcu} -mthumb
-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections
-fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD
-D__SKETCH_NAME__="""{build.project_name}"""
...
compiler.ldflags=-mcpu={build.mcu} -mthumb -Wl,--cref
-Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all
-Wl,--warn-common -Wl,--warn-section-align -u _printf_float -u _scanf_float
-Wl,--wrap,_write -u __wrap__write
WioTerminalのためには更に追加のCFLAGS、LDFLAGSがあり、特にメモリ上のレイアウトを指定するldscriptはそこで指定されている。
flash_with_bootloader.ld
と flash_without_bootloader.ld
の2つがあるが、後者は使われていないようだ。
oku@stripe ~/repos/ArduinoCore-samd/variants/wio_terminal/linker_scripts/gcc
$ git diff --no-index flash_with_bootloader.ld flash_without_bootloader.ld
diff --git a/flash_with_bootloader.ld b/flash_without_bootloader.ld
index c582eb9..513edcc 100644
--- a/flash_with_bootloader.ld
+++ b/flash_without_bootloader.ld
@@ -25,7 +25,7 @@
*/
MEMORY
{
- FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */
+ FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000
}
@@ -58,6 +58,7 @@ MEMORY
* __StackLimit
* __StackTop
* __stack
+ * __ram_end__
*/
ENTRY(Reset_Handler)
@@ -67,9 +68,6 @@ SECTIONS
{
__text_start__ = .;
- KEEP(*(.sketch_boot))
-
- . = ALIGN(0x4000);
KEEP(*(.isr_vector))
*(.text*)
@@ -200,13 +198,13 @@ SECTIONS
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
- { __StackStart = .;
+ {
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
- __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+ __StackTop = ORIGIN(RAM) + LENGTH(RAM) ;
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
Bootloaderとしてflash先頭16KiBを使用していて、セクション .sketch_boot
が使われている。↑ の .map
ファイルを見ればわかるように、このセクションの内容は実際のビルドでは空になっているので、特に気にする必要は無い。
書き込みプロセス
Bossa 1.8を使っている。
seeed_wio_terminal.upload.tool=bossac18
seeed_wio_terminal.upload.protocol=sam-ba
tools.bossac18.path={runtime.tools.bossac-1.8.0-48-gb176eee.path}
tools.bossac18.cmd=bossac
tools.bossac18.upload.params.verbose=-i -d
tools.bossac18.upload.params.quiet=
tools.bossac18.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U -i --offset={upload.offset} -w -v "{build.path}/{build.project_name}.bin" -R
BossaはARM sam-baのFOSS代替で、GitHubにある。
AVR(= 本家Arduino)
本家Arduinoのビルド仕様は arduino-cli
以下にドキュメントされている。
Maixduino
CDN版とそうでないものの2つある、が、違いはないようだ。。
古すぎてMaix Amigoをサポートしてない。。まず適当に ↑ のjsonでボードをインストールした後、 Arduino
ディレクトリにサブディレクトリ hardware/Maixduino
を掘ってチェックアウトすることでGitリポジトリをボードとして使用できる:
oku@stripe /cygdrive/c/Users/oku/Documents/Arduino/hardware/Maixduino
$ git clone https://github.com/sipeed/Maixduino k210
(READMEの手順は間違っているのでうまくいかない。)
... しかもMapファイルが出てこないな。。まぁ適当にパッチして出力させた。
diff --git a/platform.txt b/platform.txt
index 03fe6d8..622cab5 100644
--- a/platform.txt
+++ b/platform.txt
@@ -28,7 +28,7 @@ compiler.c.flags=-c {compiler.debug.flags} {compiler.both.flags} {compiler.prepr
compiler.cpp.flags=-c {compiler.debug.flags} {compiler.both.flags} "-I{runtime.platform.path}/libraries/SPI/src" {compiler.preproc.flags} -std=gnu++17 -g -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=unused-const-variable
-compiler.ld.flags=-mcmodel=medany -mabi=lp64f -march=rv64imafc -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fno-zero-initialized-in-bss -Os -ggdb -nostartfiles -static -Wl,--gc-sections -Wl,-static -Wl,--whole-archive -Wl,--no-whole-archive -Wl,-EL -Wl,--no-relax -T {build.ldscript}
+compiler.ld.flags=-mcmodel=medany -mabi=lp64f -march=rv64imafc -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fno-zero-initialized-in-bss -Os -ggdb -nostartfiles -static -Wl,--gc-sections -Wl,-static -Wl,--whole-archive -Wl,--no-whole-archive -Wl,-EL -Wl,--no-relax -T {build.ldscript} "-Wl,-Map,{build.path}/{build.project_name}.map"
compiler.S.flags=-c {compiler.debug.flags} {compiler.both.flags} {compiler.preproc.flags} -g -x assembler-with-cpp -D __riscv64
書き込みプロセス
- https://github.com/sipeed/Maixduino/blob/b9c5f43fea67222d912b6c0df447f7b83d4f0245/boards.txt#L33-L35
open-ec
( https://github.com/rgwan/open-ec ) モードの kflash(内製の書き込みツール)。