Design Tip: Give Your Project the Boot!

With flash memory becoming more readily available in microcontrollers, the possibility of software updates in applications can now be more easily realized.

Firstly, for those who are not familiar with bootloaders; a bootloader is a utility which reads a program from a communication channel, writes it to program or data memory and executes it. It therefore allows the possibility for programs to be updated or changed at a later date without requiring special programming hardware. Often products refer to this feature as "flash upgradeable".

This design tip will describe the implementation of a bootloader for a Microchip PIC® processor (16F877A), however, the same procedure could be applied to many other types of processors (8051, ARM, MSP430, etc.).

The first thing to do when developing a bootloader is to decide exactly how it is going to work and under what situations.

List of things that should be considered:

    • Is the bootloader interacting with a user or another processor(s)?
    • How will the updated program be presented to the bootloader? Will it simply be a HEX file, or will it come in another form?
    • Will a special program and/or protocol be required to transmit the updated program to the bootloader?
    • How much program memory is going to be available for the bootloader and where in memory will it be located?
    • Will the bootloader have to take care of any relocation requirements such as redirecting interrupts, etc.

For this particular example, we have decided the bootloader should have the following features:

    • Since PICs do not really have that much program memory, we need to make the bootloader as small as possible so as to maximize the available space for downloaded programs.
    • For this example, the bootloader will interact with the user to do its updating. We would like to make it so that the user does not require any special downloading program. They should be able to use a regular terminal program such as Windows HyperTerminal.
    • Because we will not be using a special downloading program, it will mean that HEX files will be sent directly to the bootloader and so it will have to interpret this directly.
    • It would also be nice if programs which are intended to be downloaded to the bootloader, didn't require special changes to the code or complicated linker options in order to be compatible.

Before any coding starts, we should first think about how things are going to be positioned in program memory. Since the bootloader needs control after reset, it will mean that it will need to use the reset vector. Since we want to make it easy to build bootloader compatible programs, it is best if the bootloader is positioned entirely at the start of memory, or, all at the end of memory. On mid-range PICs, the regular interrupt vector is located at address 0x4. If the bootloader was going to be positioned entirely at the start of memory, it would then have to redirect the interrupt vector to the downloaded program. Since this would add complexity to the code and latency to the vector, we have decided to position the bootloader at the end of memory. We will still need the reset vector, however, so this will mean shifting the downloaded program's reset vector elsewhere. Below is a diagram showing the memory map of a program with and without the bootloader installed.



As shown in Figure A, the reset vector typically contains instructions to jump into the main program. Since the bootloader needs the reset vector, we must move the downloaded program's reset vector elsewhere. Figure B shows how the reset vector now points to the bootloader code and that the downloaded program's reset vector will be positioned to an address just before the bootloader.

How it works:

    • On reset the bootloader will take control and prompt the user to send a hex file. It will wait here (with count down) for a configurable number of seconds.
    • If no hex file is sent, the bootloader will assume that no update is required and it will jump to the redirected reset vector which in turn will run the previously downloaded program. If no program has ever been downloaded, the redirected reset vector will simply contain a jump to the beginning of the bootloader and the whole process will start again.
    • If a HEX file is sent to the bootloader within the count down period, it will start interpreting the data and writing it to program memory. The bootloader will look for addresses less than 0x4 (reset vector) and will instead write this elsewhere. It will also ignore addresses conflicting with those used by the bootloader, thus protecting itself from being overwritten.

Compiling the bootloader:

Since the bootloader will live at the end of program memory, we can make use of the -A compiler option to shift it to the desired location. Some assembler code with an absolute psect will put the reset vector at address 0x0.

Compiling downloaded programs:

Since the bootloader will live at the end of program memory, we will have to make sure the downloaded program won't use those addresses. To do this we can use the compiler's -RESROM option which allows us to reserve those memory addresses. Because the bootloader takes care of redirecting the reset vector, nothing extra has to be done.

This bootloader is suitable for the following processors: 16F870, 16F871, 16F873, 16F873A, 16F874, 16F874A, 16F876, 16F876A, 16F877, 16F877A. All source code, documentation and a sample download program is included with the latest version of the compiler. There is also further information on HI-TECH Software's Forum.

  Previous versions of the bootloader are available from the HI-TECH Software ftp site.

 

January 2005.