2015年9月5日土曜日

AVR コンパイルメモ -makefile を使わない-

Xcode つかってて、なんかbuildとかがうまく行かないこととか出てきた。使い方が悪いんやけど。。。
正直あんまりmakefileの中身とか理解できてないし、fuse bitの書き換えで、AVR何個か死んだし。
これ以上死んでもらうと困る・・・

ということで、makefileが何してるのかとかもちょっとだけ触れてみようと、makefileを使わずに、というか、Xcodeも使わずに、その辺のエディタを使って編集、ターミナルでたたいてbuild的なことをすることにした。

AVR : ATmega168p
CPU : 8MHz(内蔵)
プログラマ : AVR ISP MK2

まず、main.cからオブジェクトファイルを生成。main.oが作られる。
avr-gcc -Os -Wall -DF_CPU=8000000 -mmcu=atmega168p -c main.c -o main.o

次に、オブジェクトファイルmain.oから実行ファイル形式のmain.elfを生成。
avr-gcc -Os -Wall -DF_CPU=8000000 -mmcu=atmega168p -o main.elf main.o

(次に、既にあれば、main.hex ファイルを削除)
rm -f main.hex

次に、main.elfファイルからmain.hexファイルを生成。
avr-objcopy -j .text -j .data -O ihex main.elf main.hex

これで、AVRに書き込むためのファイル(main.hex)を用意できる。
プログラムのサイズを確認する場合は、次のように書く。
avr-size --format=avr --mcu=atmega168p main.elf

ちなみに、CrossPackAVRのmakefileがやってるのと一緒。

次に、書き込み。
AVRとつないでー、なんかその辺は適当に。
つなぎ終わって、電源入れたら、次のように書く。
avrdude -c avrisp2 -P usb -p atmega168p -U flash:w:main.hex:i

これで書き込まれる。今回、内蔵発振子を使って8MHzで駆動させるから、fuse bitも変更しないと行けない。 AVR calculator でググって、サイトでfuse bitを求めて、次のように書く。
avrdude -c avrisp2 -P usb -p atmega168p -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xf9:m

ちなみに、デフォルトでは、プリスケーラが1/8になってて、1MHz駆動になってるらしい。fuse bitの中にそれを解除する所があるから、変更が必要。

これで終了。
ターミナルつかってると、なんかやってる感じでるよね。

2015年6月15日月曜日

AVR makefile変更 複数ファイルにソースを分割 memo

AVR:ATmega168p  を使用。
開発環境:Xcode version6.2
main.c だけにプログラムを書いてたけど、長くなってきていやになったので、複数ファイルに分けることにした。
main.c、servo.c、servo.h
の3つ。(とりあえずサーボの関数だけ他の所に移そうと思った。)
まず、サイドバー?のプロジェクト直下のfirmwareを右クリック、servo.cを作成する。
同時に、servo.hも作成するか聞かれたので、作っとく。
main.cで
#include "servo.h"
を追加。
servo.hで、必要な関数(servo.cに書くやつ)の名前と引数を追加。
servo.cで、
#include "servo.h"
を追加し、必要な関数、引数を記述。
ここまでは普通。
参照:「c言語 ファイル 分割 関数」とかでググれば出てくる。
http://c-lang.sevendays-study.com/day7.html
http://bituse.info/c/21
http://homepage3.nifty.com/mmgames/c_guide/20-02.html

ビルドしてみる。
"Command + b"をぽち。
エラー発生!はい?
collect2: error: ld returned 1 exit status make: *** [main.elf] Error 1
とか
Unidentified reference ・・・
とか出てくる。
で、servo.c に書いた関数がずらっと並んで、こんなのねーよと怒られる。

makefile を書き換える必要があるらしい。
これは、main.c、servo.c、servo.hがちゃんとリンクされていないから出るっぽい。
しかし、makefileほとんどいじったことないし、いじったからといって解消されるとも限らない。
で、いろんなページみて、解消出来なくて、紆余曲折あって、結論から言うと、file targets が怪しいと。
初期状態では、

# file targets:
main.elf: $(OBJECTS)
$(COMPILE) -o main.elf $(OBJECTS)

となってる。
これに、servo.cをくっつける。

# file targets:
main.elf: $(OBJECTS)
$(COMPILE) -o main.elf $(OBJECTS) servo.c

これで、これだけで、一応コンパイルは通った。
それまでにいろいろ適当に書いてはビルドしてを繰り返して、時間をかけたから、シンプルで若干ショック。
基本的過ぎて、誰も書いてない。(探し方が悪いだけ)
もしかしたら、コンパイル通ったのはたまたまかも知れんけど。

ちなみに、途中、他にもいろいろよくわからんエラーが出たわけやけど、
makefileでの設定?のさいしょ(上で言う"$(COMPILE)"の前)は必ずTabで、spaceはダメらしい。
Tabに見えても実はspace 8個とかになってたら、なんかエラー出る。
上とは違うエラーメッセージやけど。調べてみると吉。

あー。。。。