0

So the main question is can I update the program flash while code is running?

I am able to receive a new binary over tcp and save it to the second half of the flash. I want now to copy it to the first half so that it runs after next reboot.

I know this approach has the risk of bricking the board if there are any issues during the copy, and a long term approach should use a 2 stage bootloader or similar, but for now this would be a quick way of doing it.

I found conflicting information regarding if you can or not write over an area of flash that is being executed, but I understood that if the code that does the copy is run from RAM this should be possible.

The following code attempts to do this but only writes two sectors and then freezes. Is there an error in it of this is just not possible due to the reasons mentioned?

The output of the program is:

Position written 0 out of 1048576

Position written 4096 out of 1048576

I read about issues with stopping interrupts when running code in second core, but have disabled that code and result is the same.

Tks

__attribute__((section(".ram_code"))) void copy_flash_to_zero(uint32_t source_address) { uint32_t flash_index = 0; uint8_t led_counter=0; uint32_t ints; uint8_t buffer[FLASH_SECTOR_SIZE]; // Buffer to hold data printf("Starting Flash update\n"); do { // Read data from the source address in flash into the buffer memcpy(buffer, (const void *)(source_address + XIP_BASE + flash_index), FLASH_SECTOR_SIZE); // Disable interrupts during flash operations to prevent issues ints = save_and_disable_interrupts(); // Erase the flash sector at address zero plus bootloades offset (256 bytes) flash_range_erase(flash_index, FLASH_SECTOR_SIZE); // Write the buffer to flash address zero flash_range_program(flash_index, buffer, FLASH_SECTOR_SIZE); // Restore interrupts after flash operations restore_interrupts(ints); printf("position written %u out of %u\n", flash_index, FLASH_SIZE_BYTES / 2); fflush(stdout); // Force flush the buffer flash_index += FLASH_SECTOR_SIZE; led_counter++; } while (flash_index < FLASH_SIZE_BYTES / 2); printf("Flash update complete. RebootingX\n", source_address, FLASH_ADDRESS_ZERO); sleep_ms(2000); watchdog_reboot(0, 0, 0); } 

1 Answer 1

0

Likely, the code overwrites itself as it executes out of the flash itself as well. (it writes to the flash where it executes from and crashes itself). You'd have to (re)locate the updater (this code) into some location of flash that is not been overwritten currently (possibly by relocating itself first). This is tough. Another strategy would be to flash into locations which are not use currently and with very small and tight code located elsewhere again and rewrite it all into proper place and reboot?

1

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.