C program initialize flash memory and detect it was initialized

238 views Asked by At

I want to save some values in external flash memory to a microcontroller. These values are typically going to be incremented every time I run the program. I would like to initialize them to 0. Before I can write to this memory I need to make sure it is initialized. I want to do that by selecting a fixed location in memory that indicates whether or not it is initialized. In the beginning of the program, check whether it was previously initialized, if not, do the initialization and then proceed with reads and writes.

Is there a better way?

work in progress. I will try this, looking for a better approach if possible

2

There are 2 answers

3
Jake Carter On

Initializing flash to 0 (and frequently modifying flash contents) is generally problematic if you want to modify it later because usually the flash controller in micros can only write from a 1 -> 0, and the "erased" state is all 1's.

You can read-erase-write to the flash every time, but this is also somewhat problematic because usually the flash controller can only erase an entire page at a time. So you'll need to read and write back everything you care about on the entire page... If that's acceptable it should work though. Just make sure you've offset your application code correctly so you don't accidentally erase it as well.

Some flash controllers on't support modifying flash while running from flash, and require you to execute out of RAM when modifying the flash contents. That could be another complication to consider.

I can't think of any great alternatives for this unless you're willing to go off-chip to an external EEPROM.

0
kkrambo On

Define a struct to contain the related values that you want to save in nonvolatile memory. Putting the data in a struct makes it easy to serialize the data for reading and writing to nonvolatile memory.

Furthermore, the struct technique allows you to add a versioning parameter to the struct. It's helpful to version the struct so that future versions of the firmware can add features to the struct while remaining backwards compatible with previous versions of the struct (which may be saved in the nonvolatile memory of units out in the field). That is, the new firmware will read the struct version from the saved data and then know how to interpret both the old and new versions of the data.

And finally, the struct technique allows you to add a validation parameter to the struct. I typically add a CRC parameter to the end of the struct. The CRC value is calculated over all the other data bytes in the struct when the struct is saved. And then the CRC value is checked when the struct is read from nonvolatile memory. This ensures that the data read from nonvolatile memory is valid. And it also provides a way to determine whether the saved data is uninitialized. For example, when the firmware reads the data from blank nonvolatile memory then the CRC check will fail and this indicates that the saved data is uninitialized.

struct my_saved_data {
  uint32_t version;       // The version of this struct (for backwards compatibility)
  uint32_t data_value_1;
  uint16_t data_value_2;
  uint16_t data_value_3;
  uint16_t crc;           // The CRC value of the preceding data (for validation and uninitialized check)
} my_saved_data;