AVR Bootloader and Programmer
Note 15 February 2014: This project is workable but I'm no longer developing anything for AVR. The best alternative option is the Open Programmer Project by A. Maccione (see below) which covers both PIC and AVR extensively, although development has not progressed since July 2013.
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 provide a small section of FLASH memory with capabilities that allow it to modify its own FLASH memory. This is sometimes referred to as the bootblock. It normally 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 after a reset, 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 commercially available USB to serial adaptor can be used.
Some tools developed for AVR programming are presented here. Similar tools are available in both open source and commercial versions, including bootloaders, PC programming control applications and hardware programmers. The tools described here were constructed to add some useful features.
Atmel'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, and lock bits. Note that the AVR109 bootloader does not support the programming of fuses which for safety cannot be changed by the bootloader. The communication protocol used is compatible with the 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.
The adaptation of this code described here, 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 (if the appropriate fuse bit has been set), 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, or the appropriate fuse bit programmed to start the device on reset at location 0. In the latter case the application firmware will need to manage a jump to the bootloader when firmware update is required.
Although the AVR109 code is freely available, Atmel has not released it under a clear open source 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 turns out to be difficult to produce more compact C code than that provided in Atmel's sample. There are assembler versions of the bootloader available (e.g. that by Herbert Dingfelder) that take up less space, however assembler code is less readable and potentially less general than a higher level lenguage. The changes made to the code are quite reasonable and simple (most are corrections to perceived minor deficiencies):
To allow the application to
execute a jump into the bootloader I used an instruction to enable
the Watchdog Timer on a very short timeout to force the MCU to be
reset, the fuses being set to send it to the bootloader section.
There seemed to be a problem either with the (old) compiler or the
AVR that a long jump was not possible. This has the advantage that
it does not require the exact address of the bootloader to be set
in the code, but of course prevents the Watchdog Timer from being
used for for other purposes. I then added code to disable the
Watchdog Timer at the start of the bootloader. This turned out to
be problematical as the ATMega88 and related microcontrollers use
a two step process to prevent accidental changes to the Watchdog
Timer control registers. Therefore the code below is specific to
these MCUs. A small amount of work will be needed to adapt it to
other devices. The wdt.h header file provided with avr-libc does
not support this at the time of writing.
To support the above bootloader a GUI programmer for Linux was written in QT4 and C++ (see the documentation) . This provides basic hex file load and verify, and some fuse/lock bit programming for selected devices (do not fiddle with these settings until you have carefully read and understood the datasheets). 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 may have 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 packet protocol is not needed, but that is not really necessary as the bootloader will just reject anything unknown. 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 swag of information and
presents the above window. Note that unlike avrdude it assumes
that a valid and working AVR device is connected. An Intel hex
file can be opened and will be immediately read and loaded to the
application area of the device FLASH.
Thus the command:
will use the non-GUI mode, an initial baudrate of 19200 baud (only the standard rates from 2400 to 115200 are supported), the given serial port (the one shown uses a USB to serial adapter), to write the file shown with verification, to give pages of useless debug information, and to pass through serial communications at the end (so that the PC can communicate without removing the programmer). The -x parameter is only useful if the programmer described below is attached. In the GUI mode, the command line baud rate and port parameters can be used to set those values in the program, but the other parameters will be ignored.
To install the programmer for qextserialport v1.1, unpack into a directory (which by default will be serial-programmer-pc). The serial device used (/dev/ttyUSB0 in Linux) is specified in the main program and refers to a USB port for use with a USB to serial converter.
Obtain QextSerialPort and unpack the tarball into the directory qextserialport, making sure that all the source directories are under the same top directory (otherwise the .pro files will need to be changed). Make sure that the QT4 tools are installed and also g++. These should be readily available for most distros. This was tested on Ubuntu.
qextserialport v1.1: Go into the directory qextserialport and execute:
qextserialport v1.2: This does not require compilation. The updated programmer tarball results in qextserialport being included in the build.
Now go into the
serial-programmer-pc directory and execute:
Note that it should not require root privileges. If it fails to run and gives an error message, check that the serial link is working.
Also note that all the QT4 libraries will still be needed to compiled in even if the program is never used in non-GUI mode. For a programmer with no GUI at all, try avrdude or uisp.
An AT90S2313 (possibly obsolete by now but replaceable by the ATTiny2313 and ATTiny4313) was used to build a small serial programmer (described here). This was designed to communicate serially with a PC programming application using the AVRPROG protocol as used in the bootloader, and to program the target AVR device using the SPI interface.
A feature of the circuit is that when programming of a target device has completed, an output port pin can be configured to switch the serial communications from the "PC to programmer" over to "PC to target". This allows the programmer to remain connected after programming while the target device program runs normally. To restore to programming mode the programmer must be physically reset. This approach reduces a lot of fiddling with plugs during application development. There are two SPI connectors in the circuit, a 10 pin header compatible with the ET-AVR series of boards sold through Futurlec, and a 6-pin polarised header. The program supports target programming of FLASH, EEPROM, lock and fuse bits. The programmer source code is provided for the ATTiny2313, and ATTiny4313. Note that avr-gcc 4.3.5 or later is needed for support of the ATTiny4313. The ATTiny2313 version includes the .hex file compiled with a very old version of avr-gcc (cdk4avr of February 2006) as more recent version of avr-gcc produce code just slightly too big for the 1K Flash space. It is also limited in the devices it can program. It could be modified to compile for the AT90S2313 by changing the MCU in the Makefile and at the top of the source file. Also provided is a gEDA schematic of the circuit shown below.
The devices supported at this time are: "ATTiny26", "ATTiny2313", "ATTiny261", "ATMega48", "ATTiny461", "ATMega8535", "ATMega88", "ATTiny861", "ATMega16", "ATMega168", "ATMega32". The ATTiny4313 version adds "ATTiny24", "ATTiny44", "ATTiny84", "ATTiny4313".
OpenProgrammer project originated and supported by Alberto
Maccione for the Microchip PIC series also supports programming of
AVR devices. The hardware is not oriented to ISP but uses ZIF
sockets to program the devices. It
can be modified easily enough to support ISP.
1/11/2010 Added a checkbox to the GUI to allow the program to pass through the serial communications to the target device.
13/11/2010 Updated the AVR code to add more devices and to compile for the ATTiny2313. The MCU needs to be changed in the Makefile and also at the top of the .c file. The code now incorporates the serial link functions and is self contained.
13/11/2010 The old AT90S2313 has been added but so far does not program correctly. It doesn't support FLASH page programming and would require additional code in the AVR for special handling. As code memory is too limited it has been omitted from the AVR code (although it remains in the GUI). The larger device ATTiny4313 would be needed to support the additional code.
14/11/2010 The AVR code now enables the SPI output ports only when programming mode is entered, and reverts them to inputs as soon as programming mode quits. This enables the sharing of the SPI ports for small devices when using in-circuit programming.
13/10/2011 Some refactoring to move GUI specific code away from programmer operations code. Addition of features to provide command line operation.
05/01/2012 Change over to ATTiny4313 and update code.
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 15 February 2014