AVR 浮動小数点 (float) 演算
浮動小数点演算を使ったとき、-lm を付けないとバイナリサイズが巨大化する問題がある。-lm をつけない場合、デフォルトの (libgccの?) 浮動小数点関数がリンクされるけど、avr 用には高効率なものが libm に実装されている。libgcc だと 3k -> libm だと 1k ぐらいのインパクトがあるので必ず libm を使うようにしたい。
とはいえ、ちゃんと理解してないと libm にリンクされない……
結論からいうと以下じゃないとだめだった。
$(COMPILE) -o main.elf $(OBJECTS) -lm
以下のようだとうまくいかない。
$(COMPILE) -lm -o main.elf $(OBJECTS) $(COMPILE) -o main.elf -lm $(OBJECTS)
というのも、リンカは、引数を順番に読みこんで、読み込み中のファイルに今までで未定義のシンボルがあったとき、それを解決する、という挙動をするらしい (なんとなく逆に、先に定義して解決していくもんだと思ってた)。
なので、先に -lm を指定しても、その時点では未定義のシンボルが何もないので何の意味もない。
gcc のオプションに -v (verbose) を渡すと、最終的に ld (collect2) に渡される引数がわかる。
うまくいく場合は main.o -lm -lgcc -lc -lgcc というふうになってる。main.o で使ってるシンボルが -lm で解決されて、あとまだ足りないのは -lgcc とかで解決される。-lgcc が2回出てくるのは、-lc が -lgcc を使ってるからかな。よくわかんない。
関連エントリー
- mruby を Raspberry Pi 上で bare metal で動かすまで bare metal という言葉を最近知って、おもしろそうだなあと思ったので Raspberry Pi 上で試してみた。bare metal...
- Mac で simavr + avr-gdb を使い AVR プログラムを PC 上でデバッグする Mac の場合 AVR Studio を使えないので、いろいろ不便である。しかし一応開発環境がととのった。結構ググったけど、このようにして開...
- 任意固定小数点→浮動小数点変換スニペット I2Cセンサーとかを扱うと固定小数点表現によく出会う。が、固定小数点のままだと計算がめんどうなので、とりあえず浮動小数点に変換しときたいとい...
- OS X で avr-gcc 5.3.0 をビルドする AVR のビルドツールといえば Arduino.app 1.6.5 に含まれているのでそれ使うのが一番楽だけど、この avr-gcc は 4...
- 組込みでこそ C++ C++ はながいこと食わず嫌いだった。とにかく「難しい」というイメージだけ先行していた。 しかし、あくまで better C として使う限り...