AVR Bootloader and
Programmer
|
|
For the AVR microcontrollers, control of
program loading to the FLASH memory, and manipulating of the fuse and
lock bits for configuring certain features of the microcontroller, can
be simply done through a PC parallel port programmer (see the cdk4avr
tools howto and references).
Many of the AVRs have a small section
of FLASH memory with capabilities that allow it to
modify the
FLASH memory. This is sometimes referred to as the bootblock. It
resides
in the top of FLASH memory and can be set, through fuse bits, to
different sizes, typically
256 bytes to 4K bytes. The microcontroller can also be configured
through a
fuse bit so that a jump directly to the bootloader section can be
forced, rather
than the usual jump to address 0. For microcontrollers that have a UART,
programming can be done through
a PC serial port using the bootloader. This makes programming even
simpler, particularly for PCs and laptops that do not have a parallel
port. For those without a serial port, a USB to serial adaptor can be
used. AVR BootloaderAtmel's application note AVR109
describes a bootloader that uses the UART to communicate FLASH
programming instructions. They also provide some sample
code in C that allows the programming of FLASH, EEPROM, fuse and
lock bits. The communication protocol used is compatible with their
AVRPROG programming software.
After loading this into the bootloader section, the device can be
configured so that on reset the program counter starts at the
bootloader, and programmer software can program the FLASH memory. The ATMEL example bootloader program
proposes the use of a
port pin on the microcontroller to signal whether to execute the
bootloader
program or to jump directly to the application. This allows a user to
set a jumper on the microcontroller card that pulls the pin low when
programming of the FLASH is
needed. Our adaptation of the code keeps it almost
unchanged, in the interests
of compatibility. By disabling the port pin test and
excluding the EEPROM programming section and the AVRPROG compatibility
section, the code will fit neatly into a 1K block of the
bootloader FLASH section on ATMega48/ATMega88/ATMega168 AVRs. Disabling
the port pin test means that on
reset the microcontroller always ends up in the bootloader program, and
must be explicitly sent out again with a bootloader exit command. For
the moment this is acceptable as the device will normally operate while
connected to a PC serial port. For standalone operation a pin will need
to be made
available to implement the port pin test. Although the code is freely available,
Atmel has not released it under a clear opensource licence. As such the
modified code will not be reproduced here.
Later I may write my own bootloader or find another suitable source,
however it would be difficult to produce more compact C code than that
provided in
the sample. The changes made to the code
are quite reasonable and
simple (most are corrections to perceived minor deficiencies).
For the bootloader, clear all reset flags in the MCUSR, and then perform a write to WDTCSR to set the WDCE and WDE bits. This enables changes to occur in a short timeframe. Then immediately afterwards wipe the entire register to disable the timer. asm("cli"); asm("wdr"); MCUSR = 0; WDTCSR |= (1 << WDCE) | (1 << WDE); WDTCSR = 0; For the application, clear all reset flags in the MCUSR, and then perform a write to WDTCSR to set the WDCE and WDE bits to enable changes. Then immediately afterwards perform a write to WDTCSR to set the WDE bit to enable the timer for system resets only, with the timeout period set at its smallest value (about 15ms). MCUSR = 0; WDTCSR = (1 << WDCE) | (1 << WDE); WDTCSR = (1 << WDE); ProgrammerJust to make things a bit easier, a small vanilla programmer for Linux was written in QT4 and C++. The programmer opens a serial port (which may need to be changed to match the target system) and synchronizes with the device using no parity, 1 stop bit and 8 bit data. A character 0xDD is sent and the character received back from the device is checked for either a 0xDD or a "?". The latter indicates that the bootloader has been found. The 0xDD character relates to the packet protocol used in the Acquisition project. If this is received, then a packet is sent to instruct the device to jump to the bootloader. This can be removed if the application protocol is not needed, but that is not really necessary. Needless to say if the bootloader is not present the device will probably just reset itself. If neither character is received, the baud rate is cyclically changed through a set of standard rates for a couple of cycles.![]() When the program has
synchronized with the device, it gathers a bunch of information and
presents the above window. An Intel hex file can be opened and it will
be
immediately read and loaded to the application area of the bootloader
(the
bootloader is never overwritten by this: it can only be changed through
the parallel or SCI programming method).
The default baud rate to start with is 38400 baud. If this does not match that of the device, then the program will cycle through standard baud rates between 2400 and 57600 baud until it finds the correct one. This process can be sped up by changing the default baud rate to match that of the bootloader. The program allows for turning off block mode, and also allows verification without programming and vice-versa. Autoaddress currently does nothing so it is disabled. Most of the time it is successful in programming a file in block mode, but verification is a bit wobbly. This appears to be related to difficulties experienced by the bootloader in reading FLASH, as the problems aren't present for writing to FLASH. The program will reread a block several times before giving up. Non-block mode is a bit slower but is much more reliable. Quite likely a lower baud rate will help and almost certainly is needed for the slower devices and PCs. To use this, unpack into a directory which by default will be aquisition-prog. Obtain QextSerialPort and in the aquisition-prog directory, unpack the tarball into the subdirectory qextserialport. Go into qextserialport and execute: $ qmake-qt4 $ make clean $ make This will build the libraries. Return to the aquisition-prog directory and execute: $ qmake-qt4 $ make clean $ make This will build the application. Copy the binary to a suitable place. Invoke with: $sudo acq-serial-prog |
| Contact: My email address can be constructed from the username "ksarkies" and the ISP DNS address internode.on.net in the usual way. |
First created 13 May 2007
Last
Modified 22 July 2007