avr-gccの基本的なmakefile


7

arduino用のCプログラムをコンパイルするためのmakefileを作成したいと思います。私はmakeにある程度慣れていますが、avr-gccでこれを使用したことはありません。以下のコマンドをメイクファイルに入れる最も簡単な方法は何ですか?

$ avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o led.o led.c
$ avr-gcc -mmcu=atmega328p led.o -o led
$ avr-objcopy -O ihex -R .eeprom led led.hex
$ avrdude -F -V -c arduino -p ATMEGA328P -P /dev/ttyACM0 -b 115200 -U flash:w:led.hex

これはArduinoフォーラムなので、とコンパイルし-I/usr/share/arduino/hardware/arduino/cores/arduino -I/usr/share/arduino/hardware/arduino/variants/standardてリンクする方が政治的に正しいでしょうlibcore.a。:-)
エドガーボネット、2015年

回答:


5

Makeや他の形式のGCCでの作業と同じです。それに応じてCC変数とCFLAGS変数を設定するだけで、通常どおりに機能します。

たとえば、私はこれをノックアップしました:

CC=avr-gcc
OBJCOPY=avr-objcopy

CFLAGS=-Os -DF_CPU=16000000UL -mmcu=atmega328p
PORT=/dev/ttyACM0

led.hex: led.elf
    ${OBJCOPY} -O ihex -R .eeprom led.elf led.hex

led.elf: led.o
    ${CC} -o led.elf led.o

install: led.hex
    avrdude -F -V -c arduino -p ATMEGA328P -P ${PORT} -b 115200 -U flash:w:led.hex

つまり、自動Cコンパイルは、avr-gccとCFLAGSで指定されたフラグを使用して行われます。デフォルトでは、OBJCOPYを使用して16進数ファイルを作成します。これはavrファイルに設定されており、ファイルled.elfに依存しています。このファイルを取得するには、オブジェクトファイルled.oをリンクするled.elfターゲットを実行します。 CCで設定されたものを使用するデフォルトのライブラリ。そのためにはled.oが必要であり、CCで指定されたプログラムとCFLAGSのフラグを自動的に使用してそれを行います。次に、オプションmake installでを実行avrdudeして、hexファイルをチップにインストールします。

さらに汎用的にして、他のプロジェクトにコピーして、必要な最小限の変更を加えることができます。

BIN=led
OBJS=led.o test.o

CC=avr-gcc
OBJCOPY=avr-objcopy
CFLAGS=-Os -DF_CPU=16000000UL -mmcu=atmega328p
PORT=/dev/ttyACM0

${BIN}.hex: ${BIN}.elf
    ${OBJCOPY} -O ihex -R .eeprom $< $@

${BIN}.elf: ${OBJS}
    ${CC} -o $@ $^

install: ${BIN}.hex
    avrdude -F -V -c arduino -p ATMEGA328P -P ${PORT} -b 115200 -U flash:w:$<

clean:
    rm -f ${BIN}.elf ${BIN}.hex ${OBJS}

それは「自動変数」と単純な名前置換を使用します。 BINバイナリファイルの「ベース」がOBJS含まれ、オブジェクトファイルのリストが含まれます。$ @は現在のターゲットの名前、$ <は最初の前提条件の名前、$ ^はすべての前提条件のリストです。ただ、変更BINOBJSスーツに。おまけとして、make cleanコンパイルされたファイルを削除してソースをそのままにしておくために投入しました。


投稿されたメイクファイルには、先頭近くに別の行が必要です。それは言う: '.PHONY:install clean'
user3629249

@ user3629249なぜですか?投稿されたメイクファイルは完全に機能します。前提条件として呼び出されたターゲットにのみ.PHONYが必要であり、手動で呼び出されたターゲットではありません。
マジェンコ

1
@Majenko実際にはファイル名ではないものに対して偽のターゲットを作成することは良い習慣です。と呼ばれるファイルinstallまたはと呼ばれるファイルclean(シェルスクリプト、たぶん?)を作成した場合make、それらはそうであると考え、Up to date何もしない場合があります。
wchargin

@WCharginもしあなたがそのようなやりくりなことをするなら、あなたはそれが機能しないに値する。あなたのシェルスクリプトはそうclean.shinstall.shなければなりません、そしてあなたがそれらを持っている必要があるなら。
マジェンコ

2

受け入れられた答えは、あらゆる種類のデバッグツールにおいて貴重な教訓を与えてくれたので素晴らしいです(avr-objdump -Dは親友になりました)。つまり、次の行:

${OBJCOPY} -O ihex -R .eeprom $< $@

アーキテクチャフラグがありません。

$ {OBJCOPY} -mmcu = atmega328p -O ihex -R .eeprom $ <$ @

-mmcuアーキテクチャフラグがない場合、avr-gccは8515アーキテクチャ用にコンパイルしている(間違いなく)と推測し、初期化の初期命令なし、つまり「メイン」関数などを呼び出す命令なしで.elfファイルを生成します。

これにより、「main」関数のみの単純なプログラム(点滅など)は完全に機能するため、動作が混乱しますが、「main」の前または後に別の関数を定義すると、その関数が実行され、「main」を呼び出さないか、再起動します。いつもなど

また、正しいMCUタイプとアップロードされたプログラムの検証を回避するのは特に好きではないので、-Fと-Vを使用せず、代わりに-vを使用することをお勧めします。

したがって、改善された答えは次のようになります。

PKG=led
BIN=${PKG}
OBJS=${PKG}.o
MCU=atmega328p

CC=avr-gcc
OBJCOPY=avr-objcopy
CFLAGS=-Os -DF_CPU=16000000UL -mmcu=${MCU} -Wall
PORT=/dev/ttyACM0

${BIN}.hex: ${BIN}.elf
        ${OBJCOPY} -O ihex $< $@

${BIN}.elf: ${OBJS}
        ${CC} -mmcu=${MCU} -o $@ $^

install: ${BIN}.hex
        avrdude -v -c arduino -p ${MCU} -P ${PORT} -b 115200 -U flash:w:$<

clean:
        rm -f ${BIN}.elf ${BIN}.hex ${OBJS}

-mmcuアーキテクチャフラグがない場合、avr-gccは8515アーキテクチャ用にコンパイルしていると推測します」実際にはavr2です。「最大8 KiBのプログラムメモリを備えた「クラシック」デバイス。」
エドガーボネット2017

Atmelのリファレンスatmel.com/webdoc/avrlibcreferencemanual/を参照していましたが、それらは間違っていますか?
RobertŠpendl2017

たぶん、それらはAT90S8515 MCUを意味し、その置き換え(ATmega8515)とは異なり、avr2アーキテクチャを持っています。リンク先のページは、「8515」が曖昧ではなかった時期に書かれた可能性があります。また、avr2アーキテクチャを共有する多くのMCUの1つにすぎないため、「アーキテクチャ」とは呼ばれていません。
エドガーボネット2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.