Tengo una tarjeta con un ATMega2560 que también tiene una memoria flash SST25VF016B SPI. Estoy tratando de hacer un cargador de arranque OTA. Entonces, lo que está pasando es esto:
- Tengo un nuevo binario de firmware en mi servidor
- El programa principal está descargando el binario en SPI Flash y verifica CRC (crc32)
- Luego se reinicia para que Bootloader pueda activarse y escribir el nuevo flash.
Lo que está sucediendo ahora es que después de que se escribe el flash y trato de pasar del cargador de arranque a la sección de aplicaciones, termino en el cargador de arranque.
Así que necesito saber qué estoy haciendo mal.
Para programar el avr, estoy usando el siguiente código:
uint32_t address = 0;
uint32_t flashSize = 30612;
flash_readInit(4096);
uint32_t cnt = 0;
uint8_t sreg;
// Disable interrupts.
sreg = SREG;
cli();
//erase all pages
for(uint32_t addr = 0; addr < BOOT_START; addr += SPM_PAGESIZE) {
boot_page_erase_safe(addr);
}
for (i=0; i<flashSize; i+=2) {
uint16_t data = flash_readNext();
data |= flash_readNext() << 8;
boot_page_fill(i,data);
cnt +=2;
//when 1 page is full or flash file is at the end
if ((cnt % SPM_PAGESIZE) == 0 || cnt == flashSize) {
boot_page_write_safe(address);
boot_spm_busy_wait();
boot_rww_enable();
address += SPM_PAGESIZE;
}
}
_delay_ms(500);
// Re-enable interrupts (if they were ever enabled).
SREG = sreg;
//finish reading flash
flash_readFinish();
//write eeprom that the flashing was completed
eeprom_write_word((uint16_t*)0X00,1);
//now trigger a watchdog reset
watchdogConfig(WATCHDOG_2S); // short WDT timeout
while (1);
Y para iniciar el programa principal en la función principal del gestor de arranque, estoy usando esto:
uint16_t start_main = eeprom_read_word((uint16_t*)0X00);
if (start_main != 1) {
checkFlashImage();
}
else {
//jump to main program
//EXIT BOOTLOADER
(*((void(*)(void))0))();
}
Ahora algo no funciona como debería y no sé por qué.
¿Estoy escribiendo incorrectamente el flash del SPI Flash al AVR?
¿Estoy pateando incorrectamente a la aplicación principal? (Intenté asm("jmp 0000");
también pero el mismo resultado)