内蔵RC発振器の8MHz仕様のボードと16MHzのX'talを実装したボードがある。内臓RC発振器はその精度が悪い(±10%)ため,optibootのデフォルトのbaudrate 115200ではうまく通信出来ない。
このため,内蔵RC発振器を使うボードでは,baudrateが57600を使うようにする。
また,オンボードLEDやポートの使い方が違うのでそれにも対応する。
version 4.4
optiboot 4.4はArduino IDEにソースコードがバンドルされているので,それを使用した。
bootloaderにあるoptibootディレクトリに各ボード用のビルド済みoptiboot version4.4とソースコードが用意されている。
optiboot 4.4では,ATmega168P/ATmega328に対応していない。これはArduinoの公式ボードではこれらのCPUは使われていないからと思われる。
ATmega168P/ATmega328とbaudrate 57600に対応するためソースコードを以下のように編集した。
optiboot.cの178行目あたりを編集。
/* set the UART baud rate defaults */
#ifndef BAUD_RATE
#if F_CPU >= 8000000L
#define BAUD_RATE 115200L // Highest rate Avrdude win32 will support
#elsif F_CPU >= 1000000L
#define BAUD_RATE 9600L // 19200 also supported, but with significant error
#elsif F_CPU >= 128000L
#define BAUD_RATE 4800L // Good for 128kHz internal RC
#else
#define BAUD_RATE 1200L // Good even at 32768Hz
#endif
#endif
↓
/* set the UART baud rate defaults */
#ifndef BAUD_RATE
#if F_CPU = 8000000L
#define BAUD_RATE 57600L // for internal RC osc.
#elsif F_CPU > 8000000L
#define BAUD_RATE 115200L // Highest rate Avrdude win32 will support
#elsif F_CPU >= 1000000L
#define BAUD_RATE 9600L // 19200 also supported, but with significant error
#elsif F_CPU >= 128000L
#define BAUD_RATE 4800L // Good for 128kHz internal RC
#else
#define BAUD_RATE 1200L // Good even at 32768Hz
#endif
#endif
optiboot.cの231行目あたりを以下のように編集。
#if defined(__AVR_ATmega168__)
↓
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__)
pin_defs.hの1行目を以下のように編集。
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
↓
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
pin_defs.hの18行目に以下を追加。
#if defined(__AVR_ATmega328__)
// ATmega328のボード(USB IO PCB)のオンボードLEDは,PC5
#define LED_DDR DDRC
#define LED_PORT PORTC
#define LED_PIN PINC
#define LED PINC5
/* Ports for soft UART */
#ifdef SOFT_UART
#define UART_PORT PORTD
#define UART_PIN PIND
#define UART_DDR DDRD
#define UART_TX_BIT 1
#define UART_RX_BIT 0
#endif
#endif
#if defined(__AVR_ATmega168P__)
// ATmega168P(PIRAMP PCB)のオンボードLEDは,PB0
#define LED_DDR DDRB
#define LED_PORT PORTB
#define LED_PIN PINB
#define LED PINB0
/* Ports for soft UART */
#ifdef SOFT_UART
#define UART_PORT PORTD
#define UART_PIN PIND
#define UART_DDR DDRD
#define UART_TX_BIT 1
#define UART_RX_BIT 0
#endif
#endif
Makefileの96行目以降に以下を編集。
ISPFUSES = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \
-U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
ISPFLASH = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
↓
ISPFUSES = avrdude -c $(ISPTOOL) \
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \
-U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
ISPFLASH = avrdude -c $(ISPTOOL) \
-p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
Makefileの115行目以降に以下を編集。
CC = $(GCCROOT)avr-gcc
# Override is only needed by avr-lib build system.
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
OBJCOPY = $(GCCROOT)avr-objcopy
OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
SIZE = $(GCCROOT)avr-size
↓
CC = avr-gcc
# Override is only needed by avr-lib build system.
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
Makefileの420行目以降に以下を追加。
# PIRAMP PCB
piramp8: TARGET = piramp_8mhz
piramp8: MCU_TARGET = atmega168p
piramp8: LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
piramp8: CFLAGS += '-DLED_START_FLASHES=4' '-DBAUD_RATE=57600'
piramp8: AVR_FREQ = 8000000L
piramp8: $(PROGRAM)_piramp_8mhz.hex
piramp8: $(PROGRAM)_piramp_8mhz.lst
piramp8_isp: piramp8
piramp8_isp: TARGET = piramp_8mhz
piramp8_isp: MCU_TARGET = atmega168p
piramp8_isp: LFUSE = C2
piramp8_isp: HFUSE = DF
piramp8_isp: EFUSE = FC
piramp8_isp: isp
piramp16: TARGET = piramp_16mhz
piramp16: MCU_TARGET = atmega168p
piramp16: LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
piramp16: CFLAGS += '-DLED_START_FLASHES=4' '-DBAUD_RATE=115200'
piramp16: AVR_FREQ = 16000000L
piramp16: $(PROGRAM)_piramp_16mhz.hex
piramp16: $(PROGRAM)_piramp_16mhz.lst
piramp16_isp: piramp16
piramp16_isp: TARGET = piramp_16mhz
piramp16_isp: MCU_TARGET = atmega168p
piramp16_isp: LFUSE = CF
piramp16_isp: HFUSE = DF
piramp16_isp: EFUSE = FC
piramp16_isp: isp
# USB IO PCB
usbio8: TARGET = usbio_8mhz
usbio8: MCU_TARGET = atmega328
usbio8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
usbio8: CFLAGS += '-DLED_START_FLASHES=4' '-DBAUD_RATE=57600'
usbio8: AVR_FREQ = 8000000L
usbio8: $(PROGRAM)_usbio_8mhz.hex
usbio8: $(PROGRAM)_usbio_8mhz.lst
usbio8_isp: usbio8
usbio8_isp: TARGET = usbio_8mhz
usbio8_isp: MCU_TARGET = atmega328
usbio8_isp: LFUSE = C2
usbio8_isp: HFUSE = DE
usbio8_isp: EFUSE = FF
usbio8_isp: isp
usbio16: TARGET = usbio_16mhz
usbio16: MCU_TARGET = atmega328
usbio16: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
usbio16: CFLAGS += '-DLED_START_FLASHES=4' '-DBAUD_RATE=115200'
usbio16: AVR_FREQ = 16000000L
usbio16: $(PROGRAM)_usbio_16mhz.hex
usbio16_isp: usbio16
usbio16_isp: TARGET = usbio_16mhz
usbio16_isp: MCU_TARGET = atmega328
usbio16_isp: LFUSE = CF
usbio16_isp: HFUSE = DE
usbio16_isp: EFUSE = FF
usbio16_isp: isp
ToolchainにWinAVR-20100110を使用した場合,USB IO PCBが使用しているATmega328のデバイスIDがATmega328Pのものになってしまう。
これはWinAVR-20100110(AVR-GCC 4.3.3)がATmega328に対応していないために発生する。
このためWinAVR-20100110(AVR-GCC 4.3.3)でoptibootをビルドするには,WinAVR-20100110(AVR-GCC 4.3.3)のファイルを以下のように編集する。
C:\WinAVR-20100110\avr\include\avr\iom328p.hを編集。
/* Signature */
#define SIGNATURE_0 0x1E
#define SIGNATURE_1 0x95
define SIGNATURE_2 0x0F
#endif
↓
/* Signature */
#define SIGNATURE_0 0x1E
#define SIGNATURE_1 0x95
#if defined(__AVR_ATmega328__)
# define SIGNATURE_2 0x14
#else /* ATmega328P */
# define SIGNATURE_2 0x0F
#endif
これでうまく動作するoptibootがビルド出来た。
ビルドしてみる。
> make piramp8
> make piramp16
> make usbio8
hexファイルが作成出来ていればOK。
optiboot version4.4をWinAVR-20100110(AVR-GCC 4.3.3)ビルドすると500byte(0x1f4)のサイズになった。
optiboot version4.4をAVR-GCC 7.3.0でビルドすると542byte(0x21e)のサイズになり512byteを超えてしまう。
なのでoptiboot version4.4を使う場合は,WinAVR-20100110(AVR-GCC 4.3.3)でビルドしたものを使用した。
ボードにoptibootを書き込むには,
のようにすれば書き込める。
version 8.3
ソースコードは,こちらのサイトからダウンロードする。
> git clone https://github.com/Optiboot/optiboot.git
> cd optiboot/optiboot/bootloaders/optiboot/
Makefileの137行目から以下のように編集。
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
override LDFLAGS = $(LDSECTIONS) -Wl,--relax -nostartfiles
OBJCOPY = $(GCCROOT)avr-objcopy
OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
SIZE = $(GCCROOT)avr-size
↓
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
override LDFLAGS = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
Makefileの666行目に以下を追加した。
Makefile.yujiを以下の内容で作成した。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
| # PIRAMP PCB
piramp8: TARGET = piramp_8mhz
piramp8: MCU_TARGET = atmega168p
piramp8: LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
piramp8: CFLAGS += '-DLED_START_FLASHES=4' '-DBAUD_RATE=57600' '-DLED=B0'
piramp8: AVR_FREQ = 8000000L
piramp8: $(PROGRAM)_piramp_8mhz.hex
piramp8: $(PROGRAM)_piramp_8mhz.lst
piramp8_isp: piramp8
piramp8_isp: TARGET = piramp_8mhz
piramp8_isp: MCU_TARGET = atmega168p
piramp8_isp: LFUSE = C2
piramp8_isp: HFUSE = DF
piramp8_isp: EFUSE = FC
piramp8_isp: isp
piramp16: TARGET = piramp_16mhz
piramp16: MCU_TARGET = atmega168p
piramp16: LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
piramp16: CFLAGS += '-DLED_START_FLASHES=4' '-DBAUD_RATE=115200' '-DLED=B0'
piramp16: AVR_FREQ = 16000000L
piramp16: $(PROGRAM)_piramp_16mhz.hex
piramp16: $(PROGRAM)_piramp_16mhz.lst
piramp16_isp: piramp16
piramp16_isp: TARGET = piramp_16mhz
piramp16_isp: MCU_TARGET = atmega168p
piramp16_isp: LFUSE = CF
piramp16_isp: HFUSE = DF
piramp16_isp: EFUSE = FC
piramp16_isp: isp
# USB IO PCB
usbio8: TARGET = usbio_8mhz
usbio8: MCU_TARGET = atmega328
usbio8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
usbio8: CFLAGS += '-DLED_START_FLASHES=4' '-DBAUD_RATE=57600' '-DLED=C5'
usbio8: AVR_FREQ = 8000000L
usbio8: $(PROGRAM)_usbio_8mhz.hex
usbio8: $(PROGRAM)_usbio_8mhz.lst
usbio8_isp: usbio8
usbio8_isp: TARGET = usbio_8mhz
usbio8_isp: MCU_TARGET = atmega328
usbio8_isp: LFUSE = C2
usbio8_isp: HFUSE = DE
usbio8_isp: EFUSE = FF
usbio8_isp: isp
usbio16: TARGET = usbio_16mhz
usbio16: MCU_TARGET = atmega328
usbio16: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
usbio16: CFLAGS += '-DLED_START_FLASHES=4' '-DBAUD_RATE=115200' '-DLED=C5'
usbio16: AVR_FREQ = 16000000L
usbio16: $(PROGRAM)_usbio_16mhz.hex
usbio16_isp: usbio16
usbio16_isp: TARGET = usbio_16mhz
usbio16_isp: MCU_TARGET = atmega328
usbio16_isp: LFUSE = CF
usbio16_isp: HFUSE = DE
usbio16_isp: EFUSE = FF
usbio16_isp: isp
|
ビルドしてみる。。
> make piramp8
> make piramp16
> make usbio8
これでhexファイルが作成された。
WinAVR-20100110(AVR-GCC 4.3.3)でビルドすると490byte(0x1ea)のサイズになった。
AVR-GCC 7.3.0でビルドすると488byte(0x1e8)のサイズになった。
しかしWinAVR-20100110(AVR-GCC 4.3.3)でビルドしたものは,何故かうまく動作しなかった。
ボードにoptibootを書き込むには,
のようにすれば書き込める。
新しくコメントをつける