I do have firmware for an embedded device, which has several UUIDs in flash. The UUIDs have to change for every controller flashed in production. There is no EEProm available - only flash.
I'm wondering how to do this properly (for e.g. mid-scale production environments). I came up with three solutions (Research, Thinkering):
Flash the firmware with dummy-values in flash. Then receive the actual UUIDs from the programming probe (e.g. write to RAM) and write them to flash via a dedicated function in the firmware. This way, the firmware does not change between devices -> Cumbersom, as page-buffering etc. is required. Also CRC recomputation for entire flash must be done after update.
Place the declarations (static const structs with initializers) in seperate .c file. Replace the init values with some-kind of mark (e.g %REPLACE_ME_X%). Then, before flashing, replace the placeholders with the actual values (e.g. via C# app), build the code headless and flash the software -> Allows to compute CRC post-build -> Gives nice automation options, as everything can be done from app (Replace, build, flash, test, log).
Replace the dummy values in the .hex file with some-kind of mark(e.g %REPLACE_ME_X%). Then flash the .hex file -> Requires to recompute the CRC for every .hex file too.
(See answers)
Found an option to export .hex file post-build as c-array. Link UUID array with dummy-values to absolut address in generic firmware. Use c-array in C# (e.g.) app, replace with desired values and recompute CRC. Transform back to .hex and flash -> Avoids the dedicated flash page (flash footprint is of concern), avoids build process for every controller, avoids dedicated interfaces with debugger/programming probes - requires custom app.
Even simpler! Use Opt. Nr. 5 but work with binary files. This also allows to ship encrypted images for field updates (Caution! See Comments!)
Extending Opt. 6: Generate generic FW image as .bin. Write post-build script/app to replace the UUID-Dummys with actual values (e.g. from Database). Flash the modified .bin to the device in production. Link the UUID-Array in a dedicated flash page (Also including CRC-Tables, Hash-Tables, SIN-Tables, basic functions, bare-minimum level-1 bootloader and other stuff that is not going to change over the product/FW life-cycle). Lock this Flash-Page for delete in flash-controller. Use a dedicated CRC for this flash page computed in script -> No Flash-Page wasted, no extra programming step and only a simple script to write. Bonus: Script can have a -flag to remove the specific (constants) page from output .bin and encrypt the remaining contents -> Allows shipping of encrypted image to download with level-1 bootloader to all remaining flash pages (JTAG/SWD locked).
See answer about virgin 0xff state of UUIDs. Can flash generic FW in first step and download/flash only the dedicated UUID-Linker-Section in second step either by FW itself or programming probe. Nontheless: UUIDs should reside in dedicated flash page with other constants (across the entire product/FW life-cycle) as in Opt. 7 -> No flash page wasted, secured against changes due to FW field-update and simple.
I am absolutly happy to learn more about this kind of problems! Thank you.