FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

HiFive1のでのArduinoプログラム コンパイル結果の解析

Arduinoのプログラムをコンパイルするとき、最初にターゲットボードを指定して、対応するGCCなどをインストールした。 GCCを利用しているはずなので、コンパイル結果やオブジェクトなどがどこかに生成されているはずだ。 調査してみると、以下のArduino IDEの設定をすることでコンパイル結果などの情報を出力することが可能らしい。

d.hatena.ne.jp

  1. Arduino IDE の [ファイル]>[環境設定] で、preference.txt の場所を確認する。

f:id:msyksphinz:20170311160523p:plain

  1. preference.txtを編集する。以下を追加した。
build.path=/home/masayuki/Arduino/
build.verbose=true

これでBlink.inoをコンパイルするとさまざまな情報が出力されるようになった。 実際に、Blink.inoをコンパイルすると、以下のようなビルドログが生成された。

/home/msyksphinz/work/software/arduino-1.8.1/arduino-builder -dump-prefs -logger=machine -hardware /home/msyksphinz/work/software/arduino-1.8.1/hardware -hardware /home/msyksphinz/.arduino15/packages -tools /home/msyksphinz/work/softwa-1.8.1/tools-builder -tools /home/msyksphinz/work/software/arduino-1.8.1/hardware/tools/avr -tools /home/msyksphinz/.arduino15/packages -built-in-libraries /home/msyksphinz/work/software/arduino-1.8.1/libraries -libraries /home/msyksphinz/Arduino/libraries -fqbn=sifive:riscv:hifive1:toolsloc=default,clksrc=hfxtal -ide-version=10801 -build-path /home/msyksphinz/Arduino -warnings=none -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.riscv32-unknown-elf-gcc.path=/home/msyksphinz/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f -prefs=runtime.tools.openocd.path=/home/msyksphinz/.arduino15/packages/sifive/tools/openocd/9bab0782d313679bb0bfb634e6e87c757b8d5503 -verbose /home/msyksphinz/Blink/Blink.ino
/home/msyksphinz/work/software/arduino-1.8.1/arduino-builder -compile -logger=machine -hardware /home/msyksphinz/work/software/arduino-1.8.1/hardware -hardware /home/msyksphinz/.arduino15/packages -tools /home/msyksphinz/work/software/arduino-1.8.1/tools-builder -tools /home/msyksphinz/work/software/arduino-1.8.1/hardware/tools/avr -tools /home/msyksphinz/.arduino15/packages -built-in-libraries /home/msyksphinz/work/software/arduino-1.8.1/libraries -libraries /home/msyksphinz/Arduino/libraries -fqbn=sifive:riscv:hifive1:toolsloc=default,clksrc=hfxtal -ide-version=10801 -build-path /home/msyksphinz/Arduino -warnings=none -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.riscv32-unknown-elf-gcc.path=/home/msyksphinz/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f -prefs=runtime.tools.openocd.path=/home/msyksphinz/.arduino15/packages/sifive/tools/openocd/9bab0782d313679bb0bfb634e6e87c757b8d5503 -verbose /home/msyksphinz/Blink/Blink.ino

このとき、/home/msyksphinz/Arduino/sketch/Blink.ino.cppが生成されていた。 確かに、ArduinoのプログラムはC/C++と非常に似通っているが、どこが異なるのだろう。

  • diff sketch/Blink.ino.cpp ~/work/software/arduino-1.8.1/examples/01.Basics/Blink/Blink.ino
1,3d0
< #include <Arduino.h>
< #line 1 "/home/masayuki/Blink/Blink.ino"
< #line 1 "/home/masayuki/Blink/Blink.ino"
28,32d24
< #line 25 "/home/masayuki/Blink/Blink.ino"
< void setup();
< #line 31 "/home/masayuki/Blink/Blink.ino"
< void loop();
< #line 25 "/home/masayuki/Blink/Blink.ino"
45d36
<

あんまり違わない。というかこれはcppを通過させただけのようにも見える。

そして、生成されたプログラムはすべてriscv64-unknown-elf-gccを使ってコンパイルされていた。

スケッチをコンパイルしています...
"/home/msyksphinz/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f/bin/riscv32-unknown-elf-g++" -c -O2 -march=rv32imac -fpeel-loops -ffreestanding -ffunction-sections -fdata-sections -fpermissive -Wall -fno-rtti -fno-exceptions -I/home/msyksphinz/.arduino15/packages/sifive/hardware/riscv/1.0.2/system/include -I/home/msyksphinz/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/include -I/home/msyksphinz/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/env -I/home/msyksphinz/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/drivers -I/home/msyksphinz/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/env/freedom-e300-hifive1 -include sys/cdefs.h -g -DARDUINO=10801 -DF_CPU=16000000LL -DFREEDOM_E300_HIFIVE1  "-I/home/msyksphinz/.arduino15/packages/sifive/hardware/riscv/1.0.2/cores/arduino" "-I/home/msyksphinz/.arduino15/packages/sifive/hardware/riscv/1.0.2/variants/standard" "/home/msyksphinz/Arduino/sketch/Blink.ino.cpp" -o "/home/msyksphinz/Arduino/sketch/Blink.ino.cpp.o"
...
Linking everything together...
"/home/msyksphinz/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f/bin/riscv32-unknown-elf-g++" -T /home/msyksphinz/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/env/freedom-e300-hifive1/link.lds -nostartfiles -Wl,-N -Wl,--gc-sections -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=sbrk  "/home/msyksphinz/Arduino/sketch/Blink.ino.cpp.o" -nostdlib -Wl,--start-group "/home/msyksphinz/Arduino/core/core.a" -lm -lstdc++ -lc -lgloss -Wl,--end-group -lgcc -o "/home/msyksphinz/Arduino/Blink.ino.elf"
"/home/msyksphinz/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f/bin/riscv32-unknown-elf-objcopy" -R .rel.dyn -O binary "/home/msyksphinz/Arduino/Blink.ino.elf" "/home/msyksphinz/Arduino/Blin.ino.bin"
"/home/msyksphinz/.arduino15/packages/sifive/tools/riscv32-unknown-elf-gcc/3f7b3696217548bc31aeccf9a0c89bdfa4e16a8f/bin/riscv32-unknown-elf-objcopy" -R .rel.dyn -O srec "/home/msyksphinz/Arduino/Blink.ino.elf" "/home/msyksphinz/Arduino/Blink.ino.hex"
最大8388608バイトのフラッシュメモリのうち、スケッチが6932バイト(0%)を使っています。

Arduino/Blink.ino.elf をobjdumpすれば、大体中身が分かる。さらに、/home/msyksphinz/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/env/freedom-e300-hifive1/link.ldsに格納されているリンカスクリプトを見れば、HiFive1のメモリアドレスマップも大体分かるわけだ。

riscv64-unknown-elf-objdump -D Blink.ino.elf  | less
20400000 <_start>:
20400000:       5fc01197                auipc   gp,0x5fc01
20400004:       c2818193                addi    gp,gp,-984 # 80000c28 <_gp>
20400008:       5fc04117                auipc   sp,0x5fc04
2040000c:       ff810113                addi    sp,sp,-8 # 80004000 <_sp>
20400010:       00001517                auipc   a0,0x1
20400014:       eac50513                addi    a0,a0,-340 # 20400ebc <__fini_array_end>
20400018:       5fc00597                auipc   a1,0x5fc00
2040001c:       fe858593                addi    a1,a1,-24 # 80000000 <_data>
20400020:       5fc00617                auipc   a2,0x5fc00
20400024:       41460613                addi    a2,a2,1044 # 80000434 <__bss_start>
20400028:       00c5fa63                bleu    a2,a1,2040003c <_start+0x3c>
2040002c:       00052283                lw      t0,0(a0)
...