I have had a few times that a Due was working funny and after more time than I would like to admit it was fixed by re- flashing the firmware.
I did search and did find:
Verify the entire flash (including machine code)
On the form, and the idea first brought up seems like overkill.
But the last idea of just using a checksum to verify firmware is good / not corrupt I think would work.
Problem is I don't know how or where to start.
The two ideas I had;
run all flash through a checksum to create a hash, save the hash (probably in an external eeprom) at boot check if hash is the same.
Alert if difference is found.
if the flash has a checksum for every line like .hex code. Check each line and report error.
Are either of those options workable or is there a better option out there I should be working towards?
I found one way that I think will work for me.
If anyone can verify or give reason why it would not work that would be great.
Using the DueFlashStorage libary but modifying the DueFlashStorage.h file at line 25
changing to #define FLASH_START ((byte *)IFLASH0_ADDR)
It was previously set as IFLASH1_ADDR
So now it is reading from Flash bank zero, were your code is normally written.
I then cand do code like the follwoing.
#include <DueFlashStorage.h>
DueFlashStorage dueFlashStorage;
#define BUF_SIZE 256 // Buffer -> Page Size (256 bytes)
#define NUM_PAGES 1024 // Number of Pages in each Flash Bank Arduino Due
uint8_t page_buf[BUF_SIZE]; // 256 bytes per page on Arduino Due
uint8_t byte_buf[1];
uint32_t byte_iter;
uint32_t crc32_res1 = 0;
void setup() {
Serial.begin(115200);
while(!Serial);
}
void loop() {
for (int i = 0; i < BUF_SIZE * NUM_PAGES; i++) {
//SerialUSB.print(dueFlashStorage.read(i));
//SerialUSB.println();
crc32_res1 = dueFlashStorage.read(i) + crc32_res1;
}
Serial.print("Start ");
Serial.print("Check(\"");
Serial.print("\") = 0x");
Serial.println(crc32_res1, HEX);
crc32_res1 = 0;
Serial.println();
delay(5000);
}
This will read every byte of code and add it onto a running total. If the total gets too big it will rap around. Once you have the value of crc32_res1 you can save it in IFLASH1_ADDR or an external EEprom.
On the first boot after loading new code you have 2 options.
if saving the value in IFLASH1_ADDR you can read address 0 of IFLASH1_ADDR and if the value is 0xff, you can set it to 0x01 and then save the checksum value in the following address of the flash. You will then compare the value stored in Flash1 to the calculated checksum. If there is an error you can give a warning screen or something. This will work as every time you upload new code the the flash will be over written to 0xff. The downside is you will be using your Flash1 for the data storage so your available code space is half.
You can use an external EEprom to store the checksum value. If the checksum is different you can alert the user of the error and provide options to ignore, overwrite saved value, or restart. The downside is the user will get an error every time new code is loaded as you will not know if new code was loaded or flash was corrupted.