The bootloader built/used in Part 1 and Part 2 is based on the traditional “Atmega”code. This is an older bootloader, which works very well, but it’s fairly large: it takes up close to the maximum 2048-byte limit.

The newer “Optiboot” bootloader is a bit more on the bleeding edge but it is also much slower. It looks possible to compile it down to 512 bytes, but for some reason my build system is allergic to the -mshort-calls directive (avr-gcc gives me a “Internal error”) so I need to remove it to get things to compile, which yields code that is just over 512 bytes. Drats.

Still, reclaiming 1K of space over the traditional bootloader is not bad.

For the impatient, the hex file and install instructions are at the bottom of this post. But if you want to build it from scratch…

Building the sloptiboot

First one needs to edit the file
Arduino/hardware/arduino/bootloaders/optiboot/Makefile

And add a section, that will once again look rather like the “diecimila” section:

# Slow-going 1MHz internal oscillator ATMega168
#
sloptiboot168_1mhz_rc: TARGET = sloptiboot168_1mhz_rc
sloptiboot168_1mhz_rc: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=4800'
sloptiboot168_1mhz_rc: OPTIMIZE = -O2 -fno-inline-small-functions -fno-split-wide-types -std=gnu99 -W -Wall -Wundef -Werror
sloptiboot168_1mhz_rc: AVR_FREQ = 1000000L
sloptiboot168_1mhz_rc: LDSECTION  = --section-start=.text=0x3c00
sloptiboot168_1mhz_rc: $(PROGRAM)_sloptiboot168_1mhz_rc.hex
sloptiboot168_1mhz_rc: $(PROGRAM)_sloptiboot168_1mhz_rc.lst

sloptiboot168_1mhz_rc_isp: sloptiboot168_1mhz_rc
sloptiboot168_1mhz_rc_isp: TARGET = sloptiboot168_1mhz_rc
sloptiboot168_1mhz_rc_isp: HFUSE = DE # 1.8V brownout
sloptiboot168_1mhz_rc_isp: LFUSE = 62 # Internal RC Oscillator @ 8MHz
sloptiboot168_1mhz_rc_isp: EFUSE = 02 # 512 word (1024 byte) boot loader
sloptiboot168_1mhz_rc_isp: isp

The explanation for the high and low fuse settings is detailed in Part 2.

The new things here are:

  • Override the OPTIMIZE directives, to exclude -mshort-calls

  • HFUSE=DE, LFUSE=62. See Part 2 for the detailed explanation


  • EFUSE=02. Extended Fuse byte.

    0×02 = 00000010 (binary). So this means:

    • BOOTSZ1/0 is set to ’01′, which means that the boot size is set for 512 words (1024 bytes)

    • BOOTRST is programmed, which moves the Reset vector to the start of the Boot Flash section.
  • After this, cd to Arduino/hardware/arduino/bootloaders/optiboot and do a

    make sloptiboot168_1mhz_rc
    
    avr-gcc -g -Wall -O2 -fno-inline-small-functions -fno-split-wide-types -std=gnu99 -W -Wall -Wundef -Werror  -mmcu=atmega168 -DF_CPU=1000000L   '-DLED_START_FLASHES=3' '-DBAUD_RATE=4800'   -c -o optiboot.o optiboot.c
    avr-gcc -g -Wall -O2 -fno-inline-small-functions -fno-split-wide-types -std=gnu99 -W -Wall -Wundef -Werror  -mmcu=atmega168 -DF_CPU=1000000L   '-DLED_START_FLASHES=3' '-DBAUD_RATE=4800' -Wl,--section-start=.text=0x3c00 -Wl,--relax -nostartfiles -o optiboot_sloptiboot168_1mhz_rc.elf optiboot.o
    avr-objcopy -j .text -j .data -O ihex optiboot_sloptiboot168_1mhz_rc.elf optiboot_sloptiboot168_1mhz_rc.hex
    avr-objdump -h -S optiboot_sloptiboot168_1mhz_rc.elf > optiboot_sloptiboot168_1mhz_rc.lst
    rm optiboot.o optiboot_sloptiboot168_1mhz_rc.elf
    



    Installing the bootloader in the Arduino development environment

    For the impatient that skipped over the build phase, the precompiled file is here: optiboot_sloptiboot168_1mhz_rc.zip (unzip to get hex file).

    The bootloader file (optiboot_sloptiboot168_1mhz_rc.hex) needs to be placed together with the rest of the “optiboot” family of booloaders. I am using a Mac, so for me it is:

    cp -a optiboot_sloptiboot168_1mhz_rc.hex /Applications/Arduino/Arduino.app/Contents/Resources/Java/hardware/arduino/bootloaders/optiboot


    Creating a new “board”

    In order for the Arduino development environment to recognize the new bootloader, the “boards.txt” file (on the Mac, /Applications/Arduino/Arduino.app/Contents/Resources/Java/hardware/arduino/boards.txt) needs to be modified. A new entry must be created for this bootloader.

    sloptiboot168_1mhz_rc.name=Slowduino 1MHz Internal RC Clock (1K Optiboot)
    
    sloptiboot168_1mhz_rc.upload.protocol=stk500
    sloptiboot168_1mhz_rc.upload.maximum_size=15360
    sloptiboot168_1mhz_rc.upload.speed=4800
    
    sloptiboot168_1mhz_rc.bootloader.low_fuses=0x62
    sloptiboot168_1mhz_rc.bootloader.high_fuses=0xde
    sloptiboot168_1mhz_rc.bootloader.extended_fuses=0x02
    sloptiboot168_1mhz_rc.bootloader.path=optiboot
    sloptiboot168_1mhz_rc.bootloader.file=optiboot_sloptiboot168_1mhz_rc.hex
    sloptiboot168_1mhz_rc.bootloader.unlock_bits=0x3F
    sloptiboot168_1mhz_rc.bootloader.lock_bits=0x0F
    
    sloptiboot168_1mhz_rc.build.mcu=atmega168
    sloptiboot168_1mhz_rc.build.f_cpu=1000000L
    sloptiboot168_1mhz_rc.build.core=arduino
    
    ##############################################################
    


    Burning the bootloader on an ATMega168

    At this point, it’s just a matter of going through the bootloader burn process.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)