I'm programming an embedded system that has a number of user configurable parameters, which are stored in flash memory. I have to store a default value for each parameter as well as the user settings. Because the STM32 I use can write 64 Bits of flash memory at a time, I chose to use one word (32 Bits) for the parameter ID (used to identify value in EEPROM emulation) and the second available word for the parameter value itself. That works ok with two different structs, one for the default values and one for the user values in SRAM (which can change any time and be rewritten to flash).
But I'm not really happy with this solution, as I have to maintain two different structs in code and I have no checks, whether each struct sets all parameters or not. Also I can not reliably iterate over all parameters.
Right now it works like this:
// Typedefs for single entry as well the complete flash table typedef struct { uint32_t ID; uint32_t value; } FLASH_PARAM; typedef struct { FLASH_PARAM param1; FLASH_PARAM param2; FLASH_PARAM param3; . . FLASH_PARAM paramN; } FLASH_TABLE;
I init the struct for the default values to store in program memory like this:
FLASH_TABLE ft_default = { .param1 = {1, PARAM1_DEFAULT}, .param2 = {2, PARAM2_DEFAULT}, . . .paramN = {N, PARAMN_DEFAULT}, };
But now I see several problems:
- I don't get a warning if I miss an entry in ft_default. Gcc only gives warnings for missing elements in struct init if the highly confusing syntax of nameless assignment is used. This is a serious problem for me, as there are regular changes to the entries of FLASH_TABLE.
- There is no reliable way to iterate over all struct members. While I could access the struct like an array, this is not really defined behaviour as far as I know, so I would like to avoid that.
- An alternative would be to directly use an array of structs for FLASH_TABLE, iterating would be no problem then. But I want to access the FLASH_TABLE elements efficiently by name in code (ft->param1), so an array is not really an option. I could use an enum to name all array entries, but then again I have the problem of keeping enum list and default value assignment in sync...
I would prefer a clean solution where I can place all information (Name to use in code, ID to use in flash, default value) at a central table in the code. I'm not really experienced with python, but there I would probably use a dict with a list as value like this:
FLASH_PARAMS = { "param1": [ID, default_value], "param2": [ID, default_value], }
I realise that this question kind of turned into a wall of text, but I hope my problem is clear now and there is some standard / default way of handling such a situation to absolutly minimize the chances of two tables not staying in sync when implementing changes.