简体   繁体   English

C中的大结构初始化

[英]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. 我可以选择在C中初始化一个大结构。我正在开发一个内存很小的嵌入式微型计算机。 I've got the chip configuration saved in EEPROM. 我已经将芯片配置保存在EEPROM中。 So I have a struct which contain all the configuration page in EEPROM : 所以我有一个结构,其中包含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 : 这用于修改或访问EEPROM配置:

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 现在,我想用不同的工厂配置(CONFIG A,CONFIG B等)来初始化此变量。每个工厂配置的所有参数都可以通过#define定义。

After that, I don't know which method to use : 之后,我不知道该使用哪种方法:

1) Write an initialization function which take all the values in parameters : 1)编写一个初始化函数,该函数接受参数中的所有值:

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 : 2)创建一个具有所有出厂配置的大型阵列:

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. 缺点:由于每个工厂配置都有一个T_EEPROM实例,因此内存非常大。

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. 如果它们没有变化,则可以使用#define来选择值的工作集,并将其用于工作集变量的静态初始化。

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];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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