I'm struggling with getting system settings from EEPROM and trying to avoid having them as global variables and wondered what the prevailing wisdom is and if there's an accepted practice and / or elegant solution.
I'm getting system settings stored in an EEPROM via structures with some error checking and the sizeof operator in main.c along the lines of:
// EEPROM data structures
typedef struct system_tag
{
uint8_t buzzer_volume;
uint8_t led_brightness;
uint8_t data_field_3;
} system_t;
typedef struct counters_tag
{
uint16_t counter_1;
uint16_t counter_2;
uint16_t counter_3;
} counters_t;
typedef struct eeprom_tag
{
system_t system_data;
uint8_t system_crc;
counters_t counters;
uint8_t counters_crc;
} eeprom_t;
// Default values
static system_t system_data =
{
.buzzer_volume = 50,
.led_brightness = 50,
.data_field_3 = 30
};
static counters_t counter =
{
.counter_1 = 0,
.counter_2 = 0,
.counter_3 = 0
};
// Get system settings data from the EEPROM
if (EEPROM_check_ok(EEPROM_BASE_ADDRESS, sizeof(system_t)))
{
eeprom_read_block(&system_data, (uint16_t *) EEPROM_BASE_ADDRESS, sizeof(system_t));
}
if (EEPROM_check_ok((EEPROM_BASE_ADDRESS + offsetof(eeprom_t, counters)), sizeof(counters_t)))
{
eeprom_read_block(&counter, (uint16_t *) EEPROM_BASE_ADDRESS, sizeof(counters_t));
}
I'm then using the system settings data at the moment to set other variables in different modules. E.g. in another file, buzzer.c, I have a module static variable (in an effort to avoid globals) with accessor functions to try and give some encapsulation:
// Current volume setting of the buzzer
static uint8_t volume = 50;
void BUZZER_volume_set(uint8_t new_volume)
{
volume = new_volume;
}
uint8_t BUZZER_volume_get(void)
{
return (volume);
}
The problem I feel is I've now got unnecessary duplication of data, as when I pass the buzzer_volume from the system data to set the static volume variable in the buzzer module things could get out of synchronisation. Having the system settings as globals would be easy, but I know this is frowned upon.
Is there a more elegant way of doing this without using globals and still having some encapsulation?
Any suggestions would be gratefully received.