Hi. I am in unfamiliar territory so please be a little forgiving :). I have a .hex file (generated by the Arduino IDE) for a simple Blink program written for the Arduino Mega2560 board that I am working with right now. it is 4362 bytes in size exactly. I want to write a program that does the following:
- load this entire hex file into (flash) memory.
- rewrite the current application code in flash with the hex file that was loaded in step 1, so that...
- the bootloader can pick up this newly flashed hex file (Blink) the next time the Arduino is reset.
So far with my limited knowledge I have been able to cobble together the following program with avr/boot.h
whose documentation provided a function boot_program_page
that I more or less have a good understanding of and decided to use as is:
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/boot.h> // contains functions for SPM operations
// Hex code for the blink program
#include "hexfile.h"
// Function that writes a page to flash in SPM (taken from: https://www.nongnu.org/avr-libc/user-manual/group__avr__boot.html)
void bootProgramPage (uint32_t page, uint8_t *buf)
{
uint16_t i; // Loop index for iterating using 16-bit address offsets
uint8_t sreg; // 8-bit word for saving 8-bit status registers before restoring
sreg = SREG; // Store current state of the status register for later restoring
cli(); // Clear interrupts so that following critical section is not interrupted
eeprom_busy_wait(); // Wait for eeprom operations to complete
boot_page_erase(page); // Erase page (prepare it) before writing
boot_spm_busy_wait(); // Wait until page is erased
for (i=0; i<SPM_PAGESIZE; i+=2) // Fill page buffer with contents from hexfile to write to application flash
{
// Take two bytes at a time and combine them into a single 16-bit word (AVR is little endian)
uint16_t w = *buf++;
w += (*buf++) << 8;
boot_page_fill (page + i, w);
}
boot_page_write (page); // Write buffer to flash page (in SPM)
boot_spm_busy_wait(); // Wait for write operation to complete
boot_rww_enable (); // Reenable RWW-section again (We need this if we want to jump back to the application after bootloading)
SREG = sreg; // Re-enable interrupts (if they were ever enabled)
}
void setup()
{
Serial.begin(115200);
Serial.println("Writing program to flash...");
bootProgramPage(0x0000, hexcode); // write to page at 0x0000 ?? (not really sure on this one)
Serial.print("Done.");
// now i press the reset button on the arduino
}
void loop()
{
}
Here hexfile.h
contains all the 4362 bytes for the hex file in a uint8_t
array (which I generated using a python script from the actual hex file...not the best idea perhaps but I'll address it later.)
const uint8_t hexcode[] PROGMEM = {0x3a, 0x31,...
The code runs but pressing reset simply restarts THIS program itself, NOT the blink sketch. I'm clearly doing something wrong...my guesses are i am writing to the wrong address in application flash. Maybe the whole idea is flawed. Any suggestions are welcome. Thanks for your time.