AVR

提供: ArchWiki
ナビゲーションに移動 検索に移動

AVR は Microchip Technology 社 (以前は Atmel 社でしたが買収されました)によって開発されているマイクロコントローラ (MCU) の一種です。 AVR は Arduino プロジェクトに代表される様に、とりわけホビーや教育用途で広まっています。このページでは、これらのMCUの8ビットシリーズを扱います。

ツールチェイン

ツールチェインと GNU コンパイラのために avr-gccインストールして下さい。

プログラマー (書込器)

AVR チップへ作成したプログラムを書き込むためには、プログラマーと、それを行うソフトウェアが必要です。有名なプログラマーには USBaspAVRISP mkIIAtmel-ICESTK500があります。 LPT ポートで動く単純な DIY プログラマーである AVR-PG2B などもあります。 avrdude は、これらも含めて多くのプログラマーをサポートします。

udev の問題

AVRISP mkII や USBasp プログラマーを使う場合には、 avrisp-udevAURusbasp-udevAUR をインストールすることも考えて下さい。 avrdude を root 特権なしで動かすことが出来ます。

使い方

AVR チップのために C 言語のプログラムをコンパイルするには、 avr-gcc が使えます。ここでは例として、 ATmega8A を 8 MHz で動かすことを考えます。目的の MCU と動作周波数を指定する必要があります:

$ avr-gcc -DF_CPU=8000000UL -mmcu=atmega8a -std=gnu99 main.c -o main.elf

avrdude は、直接 ELF ファイルを読む事ができますが、 次の様に Intel HEX 形式に変換することもできます:

$ avr-objcopy -O ihex -j .text -j .data main.elf main.hex

書き込むファイルが出来たら、 書き込み先の flash ROM を指定して、 avrdude を実行します。ここでは AVRISP mkII を例に取って、安全のため書き込み周波数を 125 kHz に小さくして書き込みます:

$ avrdude -p atmega8 -c avrispmkII -B 125kHz -U flash:w:main.hex

これで完了です。 他には、 avrdude は EEPROM や fuse への書き込みもサポートします。例えば、low fuse と high fuse それぞれに 0x9F と 0xD1 を書き込むには、次のようにします:

$ avrdude -p atmega8 -c avrispmkII -B 125kHz -U lfuse:w:0x9F:m -U hfuse:w:0xD1:m

ISP プログラミングの時には、 MCU の動作周波数の 1/8 を越えないように気を付けてください。多くの新しいチップでは 1 MHz の設定で販売されているので、 125 kHz の書き込み速度にするのがよいでしょう。

ヒントとテクニック

最適化

AVR は小さな flash ROM サイズと非力な CPU で構成されているので、 ROM サイズの縮小や性能の向上のために最適化も考慮すると良いでしょう。 GCC の最適化レベルの指定 -Os や他の機能 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums を使う事がよく知られた方法です。必要のないライブラリへの参照を除くためやガベージコレクションを使うためには、 -ffunction-sections -fdata-sections -Wl,--gc-sections があります。

Makefile のサンプル

大きなプロジェクトを管理することは面倒で、 Makefile による管理は非常に有効です。 AVRfreaks を元にしたサンプルを、ここで紹介します。

CC = avr-gcc
OBJCOPY = avr-objcopy
SIZE = avr-size
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f

MCU = atmega8a
F_CPU = 8000000

LFUSE = 0x9f
HFUSE = 0xd1

TARGET = firmware
SRC = main.c lcd.c twi.c
OBJ = $(SRC:.c=.o)
LST = $(SRC:.c=.lst)

FORMAT = ihex

OPTLEVEL = s

CDEFS = 

CFLAGS = -DF_CPU=$(F_CPU)UL
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPTLEVEL)
CFLAGS += -mmcu=$(MCU)
CFLAGS += -std=gnu99
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -Wall -Wstrict-prototypes
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)

LDFLAGS = -Wl,--gc-sections
LDFLAGS += -Wl,--print-gc-sections

AVRDUDE_MCU = atmega8
AVRDUDE_PROGRAMMER = avrispmkII
AVRDUDE_SPEED = -B 1MHz

AVRDUDE_FLAGS = -p $(AVRDUDE_MCU)
AVRDUDE_FLAGS += -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_SPEED)

MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_FLASH = Preparing HEX file:

all: gccversion $(TARGET).elf $(TARGET).hex size

.SECONDARY: $(TARGET).elf
.PRECIOUS: $(OBJ)

%.hex: %.elf
        @echo
        @echo $(MSG_FLASH) $@
        $(OBJCOPY) -O $(FORMAT) -j .text -j .data $< $@

%.elf: $(OBJ)
        @echo
        @echo $(MSG_LINKING) $@
        $(CC) -mmcu=$(MCU) $(LDFLAGS) $^ --output $(@F)

%.o : %.c
        @echo $(MSG_COMPILING) $<
        $(CC) $(CFLAGS) -c $< -o $(@F)

gccversion:
        @$(CC) --version

size: $(TARGET).elf
        @echo
        $(SIZE) -C --mcu=$(AVRDUDE_MCU) $(TARGET).elf

analyze: $(TARGET).elf
        $(NM) -S --size-sort -t decimal $(TARGET).elf

isp: $(TARGET).hex
        $(AVRDUDE) $(AVRDUDE_FLAGS) -U flash:w:$(TARGET).hex

fuses:
        $(AVRDUDE) $(AVRDUDE_FLAGS) -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m

release: fuses isp

clean:
        $(REMOVE) $(TARGET).hex $(TARGET).elf $(OBJ) $(LST) *~

制御レジスタ値の計算

プロジェクト開発速度の向上のために、 avrcalcAUR ユーティリティが使えます。これはタイマーや周波数などの制御レジスタのパラメータの計算に役立ちます。

参照