简体   繁体   中英

big struct init in C

I have got a choice to do to initialize a big structure in C. I am working on an embedded micro with a tiny memory size. I've got the chip configuration saved in EEPROM. So I have a struct which contain all the configuration page in EEPROM :

Typedef struct
{
    unsigned int Param1;
    float Param2;
    unsigned char Param3;
    [...]
    char Paramx[SIZE];
} T_EEPROM;

We have to keep in mind that this struct is heavy regarding the tiny memory size of the micro.

I have a global variable of this type :

T_EEPROM MyConfig;

This is used to modify or access EEPROM configuration :

MyConfig.Param1 = NewValue;
WriteEEPROM(MyConfig);

Now I want to initialize this variable with diffrents kind of factory configurations (CONFIG A, CONFIG B, etc) All the parameters for each factory configuration can be defined by a #define

After that, I don't know which method to use :

1) Write an initialization function which take all the values in parameters :

bool InitEEPROM(unsigned int param1, float param2, unsigned char param3, [...], char *Paramx)
{
    MyConfig.Param1 = param1;
    MyConfig.Param2 = param2;
    MyConfig.Param3 = param3;
    [...]
    MyConfig.Paramx = paramx;
}

After, I could call the function lake that :

void InitFactoryEEPROM (unsigned char type)
{
    if (type == 1)
        InitEEPROM(DEFINE_PARAM1_CONFIG_1, DEFINE_PARAM2_CONFIG_1,DEFINE_PARAM3_CONFIG_1, [...], DEFINE_PARAMx_CONFIG_1);
    else if (type == 2)
        InitEEPROM(DEFINE_PARAM1_CONFIG_2, DEFINE_PARAM2_CONFIG_2,DEFINE_PARAM3_CONFIG_2, [...], DEFINE_PARAMx_CONFIG_2);
    else if (type == 3)
        [...]
}

Disadventage: heavy to write

2) Create a big array with all the factory configurations :

T_EEPROM FactoryEepromConfig[CONFIG_COUNT] =
{
    {DEFINE_PARAM1_CONFIG_1, DEFINE_PARAM2_CONFIG_1, DEFINE_PARAM3_CONFIG_1, [...], DEFINE_PARAMx_CONFIG_1},
    {DEFINE_PARAM1_CONFIG_2, DEFINE_PARAM2_CONFIG_2,DEFINE_PARAM3_CONFIG_2, [...], DEFINE_PARAMx_CONFIG_2},
    [...]
};

With an easier initialisation function:

bool InitEEPROM(T_EEPROM factoryConfig)
{
    MyConfig.Param1 = factoryConfig.Param1 ;
    MyConfig.Param2 = factoryConfig.Param2;
    MyConfig.Param3 = factoryConfig.Param3;
    [...]
    MyConfig.Paramx = factoryConfig.Paramx;
}

And this call:

void InitFactoryEEPROM (unsigned char type)
{
    InitEEPROM(FactoryEepromConfig[type]);
}

Disadventage: Very heavy in memory because I have a T_EEPROM instance for each factory configuration.

Anyone has got a better idea?

In all the scenario's (possibilities) you gave, the values need to be in memory, either as variables or as values to initialize variables with. So there is not much difference in the memory footprint. Using initialization functions has the overhead of code bytes required to execute the initialization.

Having one static array containing all the values, and that you index every time you need a value, has the overhead of instructions to index the array. Copying the values of an array index to a "working set" variable has the overhead of the extra variable.

Possibly you can measure which is smallest by making several versions, eg:

  • one static array that is indexed for each parameter access;

  • one static array and copying the working set to an extra variable;

  • initializing a working set variable using an initialization function.

But this assumes the working set of values can change during execution. If they don;t change, then you can use #define s to select the working set of values and use that for static initialization of the working set variables.

This is short and clean:

static const T_EEPROM FactoryEepromConfig[CONFIG_COUNT] =
{
{DEFINE_PARAM1_CONFIG_1, DEFINE_PARAM2_CONFIG_1, DEFINE_PARAM3_CONFIG_1, [...],     DEFINE_PARAMx_CONFIG_1},
{DEFINE_PARAM1_CONFIG_2, DEFINE_PARAM2_CONFIG_2,DEFINE_PARAM3_CONFIG_2, [...],     DEFINE_PARAMx_CONFIG_2},
[...]
};

void InitFactoryEEPROM (size_t type)
{
    assert(type < CONFIG_COUNT);
    MyConfig = FactoryEepromConfig[type];
}

to avoid globals you can change the function to this:

void InitFactoryEEPROM (T_EEPROM* config, size_t type)
{
    assert(type < CONFIG_COUNT);
    *config = FactoryEepromConfig[type];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM