Bootloader for my project

Hi,

I have an Arduino UNO and my application needs to reprogram itself. The hex file is transmitted and stored in the SRAM and after going through the AVR109 Application note I have realized that I need to write my bootloader to make self programming possible. Where should I start by writing my own bootloader. AVR109 basically gave me a good understanding of how self programming works but I want access to resources/info. which can enable me to write my own bootloader. Also in the same application note they refer to a protocol and a bootloader that can make self programming possible. Where can I get the source code as I searched online and I could not find the "main.c" as mentioned. Thanks!

arduino-pgm-1912: The hex file is transmitted and stored in the SRAM...

That limits the image to 2 KiB. Do you really only intend to use 2 KiB of the available 32 KiB of Flash?

There are many protocols and bootloaders, so if you are determined to write your own bootloader, it's your problem to choose protocol which suits you best :-)

Maybe you even don't need any bootloader? Self programming is not limited to program called 'bootloader' and booting sequence. Self programming code just need to sit in that memory area.

You can also use something what is ready made :-) I have modified version of Optiboot with application self flashing, check this thread: http://forum.arduino.cc/index.php?topic=332191.0

I call "XY Problem" on this.

First explain why you think you need your device to self-program. It is extremely improbable that you would.

If you care to answer, I (and half a dozen other people) will explain.

Hello,

Thanks all for your replies. I am basically working on a project that can receive new firmware code wirelessly and upgrade the code in the application section. I was told that in the AVR architecture the program counter is confined to the flash and cannot point anywhere else. If the program counter could say point to the SRAM then I would set the PC to the SRAM's buffer address where the hex code so received wirelessly resides and then the application would run from that point on until it encounters a halting condition or busy loop. I do know that the SRAM is 2 kB and it doesn't make any sense to do this but to accomplish the task I have to take the help of the bootloader to load the application to the application section. Hence, I have to design my bootloader. I checked out a number of bootloaders online and many of them use the AVR-GCC library avr/boot.h. I was reading the documentation of the library and the example found on that page but I need help in porting that API. For instance I would like to load an application as you normally would via the serial interface using avrdude and if a software interrupt is generated then it should call the boot code and pass the address of the SRAM buffer where the hex file resides. I do not know what steps I should take from here on. I can also adapt/port the optiboot bootloader but I am not sure what approach I should take. I need your guidance. Thanks for your replies!

You still appear to be running round in circles for no clear reason!

Remotely uploading code is exactly what the bootloader does, and many people have used various serial interfaces to do this, such as Bluetooth modules. The only requirement is that you must actuate a reset to start the bootloader immediately before starting the download process.

A rather simple “cheat” to do this is to use an ESP8266 module which is rather amusing since it is in itself a considerably more powerful and capable processor than the UNO, so can easily take control of the bootloader.

I think you really need to explain how your expectation differs from this common process. If for example, you are concerned about the possibility of failure through a partial download, then one of the common ways of accounting for this is to divide the flash into two notional pages and load them alternately; the bootloader managing which correctly downloaded image will be activated. The cost is requiring the application to fit in half the flash, but that is frequently no problem in itself.

Anther approach is of course, to have an interpreter/ library common to all applications, which can then be loaded as much smaller modules. FORTH is such an example. This is not how the bootloader presently functions, but no reason you cannot do just that.

@Paul__B: Do you mean to say that I do not need to design a custom bootloader? Can the Arduino bootloader accept the code sent via a bluetooth module or any other serial interface?? Do I have to make calls to the bootloader? Thanks!

Well, basically, the bootloader starts as the chip comes out of reset. It then waits a limited time for a synchronising signal via the serial line and if this is received, engages in a dialogue (that is, two-way) to receive the data to be written to the Flash.

This can be done via just about any implementation of a two-way serial link with the IDE - or something that emulates it and can generate a reset pulse (promptly) on opening the link. The original Arduinos used the RS-232 port of the PC, current ones use the USB port, but as long as the link emulates a COM port and you have the speed right, it should work.

@Paul__B: Thanks for your reply! How does the serial interface on the PC interrupt the MCU and cause the control to be passed to a bootloader. Does the serial interface implement some kind of hardware interrupt? For instance when I pass my program to avrdude, how does avrdude interrupt the MCU that causes a system reset which passes the control back to the bootloader?

avrdude causes the USB/Serial chip to assert RTS or DTR, which goes thru a 0.1uF cap to the Reset pin, and combined with the 10K pullup resistor results in a reset pulse.

arduino-pgm-1912: Does the serial interface implement some kind of hardware interrupt?

Sure does :astonished: - it is the most fundamental interrupt on any computer system - it is called "reset".

arduino-pgm-1912: For instance when I pass my program to avrdude, how does avrdude interrupt the MCU that causes a system reset which passes the control back to the bootloader?

avrdude closes the serial port if it is presently open, then opens it anew. This causes the "Ready To Send" line on the serial port or the equivalent function on the USB bus, to go false if it was not already, then go true (it happens to be negative logic, so "true" is LOW). You then feed the RTS status line of the RS-232 port or the USB to TTL converter to the reset pin of the microcontroller via a capacitor with a pull-up, so that a brief pulse is fed to reset the chip.

Hey,

Thanks for all your replies! I have written a custom bootloader which upon reset can jump to the bootloader code and receive a hex file via serial interface. I wanted to know if my bootloader will be compatible with avrdude. As @CrossRoads and @Paul__B mentioned avrdude simply causes a hardware reset via the serial interface which makes the microcontroller jump to the bootloader code, I wanted to know if I have to implement any protocol or configure avrdude in any way that will make my microcontroller receive the hex error free. Thanks for those replies!

arduino-pgm-1912: Hello,

Thanks all for your replies. I am basically working on a project that can receive new firmware code wirelessly and upgrade the code in the application section. I was told that in the AVR architecture the program counter is confined to the flash and cannot point anywhere else.

The "application section" IS the flash section!

You could place code into EEPROM by doing it the exact same way as PROGMEM, but use the EEMEM keyword instead.

In fact, I can't figure why there is even an EEPROM library since eeprom read and write is supported by AVR-GCC, and in a MUCH smarter manner.

arduino-pgm-1912: I wanted to know if I have to implement any protocol or configure avrdude in any way that will make my microcontroller receive the hex error free. Thanks for those replies!

Intel HEX files have a checksum at the end (which AVRDUDE does check). As far as uploading "error free" code, where do you expect an error to crop up? Especially since you can tell AVRDUDE to verify (read back and compare) what it wrote.

All in all, it seems to me that you are doing it the hard way.......

Krupski: I can't figure why there is even an EEPROM library since eeprom read and write is supported by AVR-GCC, and in a MUCH smarter manner.

You might want to take a look at the latest version of the EEPROM library, it provides some very useful functions(and more on the way in the next version). I agree the old EEPROM library was nothing special.

@Krupski and @pert: Thanks for your replies. I have figured out how to write pages in the flash section using the <avr/boot.h> library. I have to implement self programming wirelessly via zigbee or bluetooth and hence to do that I have to write a custom bootloader. The bootloader should be able to upload code as you normally would via avrdude and be able to implement the over the air self programming. Thus the skeleton of my code is:

if(hardware reset)
//receive code via avrdude as you normally would

else if (software reset)
//receive code from the buffer in SRAM whose address is specified.

Can you provide any suggestions as to where I should start or how I should approach this problem?

I can also combine the if-else-if in a single statement:
if(hw reset || sw reset)
//receive code from the buffer’s address in SRAM/EEPROM (address must be known by the bootloader)

Please do give feedback. Thanks!

Can the bluetooth and zigbee modules provide a hardware reset?

I am sending the hex file via serial interface for initial testing and I am sending a code such that when the MCU parses the coded message it performs a software reset sing the watchdog timer and the code then jumps to the bootloader. This is what I have planned to do but I need to figure out the bootloader implementation first to actually make this happen. Thanks!

Ok, that's what I was going to suggest if you can't get a hardware reset. It's how the Ariadne TFTP bootloader does it.

pert:
You might want to take a look at the latest version of the EEPROM library, it provides some very useful functions(and more on the way in the next version). I agree the old EEPROM library was nothing special.

Well, if you look into it, the EEPROM memory SHOULD be used something like this:

#include <avr/eeprom.h>

#define VAR1 0x00 // initial EEPROM values
#define VAR2 0x00

const uint8_t variables[] EEMEM = {
    VAR1, VAR2,
};

eeprom_write_byte (VAR1, 0x13); // store 0x13 in eeprom
eeprom_write_byte (VAR2, 0x24);

uint8_t x = eeprom_read_byte (VAR1); // get 0x13 out of EEPROM into x

This way, you don’t need to worry about EEPROM addresses (such as going in steps of 2 for uint16_t). You refer to your data by name.

It’s just like PROGMEM, but it’s also writable.