C中的大结构初始化
big struct init in C
我可以选择在 C 中初始化一个大结构。
我正在研究一个内存大小很小的嵌入式微型计算机。
我已经将芯片配置保存在 EEPROM 中。
所以我有一个包含 EEPROM 中所有配置页面的结构:
Typedef struct
{
unsigned int Param1;
float Param2;
unsigned char Param3;
[...]
char Paramx[SIZE];
} T_EEPROM;
我们必须记住,这个结构对于 micro 的微小内存大小来说很重。
我有一个这种类型的全局变量:
T_EEPROM MyConfig;
这用于修改或访问 EEPROM 配置:
MyConfig.Param1 = NewValue;
WriteEEPROM(MyConfig);
现在我想用不同种类的工厂配置(CONFIG A、CONFIG B 等)初始化这个变量
每个出厂配置的所有参数都可以通过 #define
定义
之后不知道用什么方法:
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;
}
之后,我可以调用 lake 函数:
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)
[...]
}
缺点:写起来很重
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},
[...]
};
使用更简单的初始化函数:
bool InitEEPROM(T_EEPROM factoryConfig)
{
MyConfig.Param1 = factoryConfig.Param1 ;
MyConfig.Param2 = factoryConfig.Param2;
MyConfig.Param3 = factoryConfig.Param3;
[...]
MyConfig.Paramx = factoryConfig.Paramx;
}
这个电话:
void InitFactoryEEPROM (unsigned char type)
{
InitEEPROM(FactoryEepromConfig[type]);
}
缺点:
内存非常大,因为每个出厂配置都有一个 T_EEPROM
实例。
有人有更好的主意吗?
这是简短而干净的:
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];
}
为了避免全局变量,您可以将函数更改为:
void InitFactoryEEPROM (T_EEPROM* config, size_t type)
{
assert(type < CONFIG_COUNT);
*config = FactoryEepromConfig[type];
}
在您给出的所有场景(可能性)中,值都需要在内存中,作为变量或作为初始化变量的值。所以内存占用没有太大区别。使用初始化函数会产生执行初始化所需的代码字节开销。
拥有一个包含所有值的静态数组,并且每次需要一个值时都对其进行索引,这会产生索引数组的指令开销。将数组索引的值复制到 "working set" 变量会产生额外变量的开销。
可能你可以通过制作几个版本来衡量哪个最小,例如:
一个为每个参数访问建立索引的静态数组;
一个静态数组并将工作集复制到一个额外的变量;
正在使用初始化函数初始化工作集变量。
但这假设工作值集可以在执行期间更改。如果它们不改变,那么您可以使用 #define
s 到 select 值的工作集,并将其用于工作集变量的静态初始化。
我可以选择在 C 中初始化一个大结构。 我正在研究一个内存大小很小的嵌入式微型计算机。 我已经将芯片配置保存在 EEPROM 中。 所以我有一个包含 EEPROM 中所有配置页面的结构:
Typedef struct
{
unsigned int Param1;
float Param2;
unsigned char Param3;
[...]
char Paramx[SIZE];
} T_EEPROM;
我们必须记住,这个结构对于 micro 的微小内存大小来说很重。
我有一个这种类型的全局变量:
T_EEPROM MyConfig;
这用于修改或访问 EEPROM 配置:
MyConfig.Param1 = NewValue;
WriteEEPROM(MyConfig);
现在我想用不同种类的工厂配置(CONFIG A、CONFIG B 等)初始化这个变量 每个出厂配置的所有参数都可以通过 #define
定义之后不知道用什么方法:
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;
}
之后,我可以调用 lake 函数:
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)
[...]
}
缺点:写起来很重
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},
[...]
};
使用更简单的初始化函数:
bool InitEEPROM(T_EEPROM factoryConfig)
{
MyConfig.Param1 = factoryConfig.Param1 ;
MyConfig.Param2 = factoryConfig.Param2;
MyConfig.Param3 = factoryConfig.Param3;
[...]
MyConfig.Paramx = factoryConfig.Paramx;
}
这个电话:
void InitFactoryEEPROM (unsigned char type)
{
InitEEPROM(FactoryEepromConfig[type]);
}
缺点:
内存非常大,因为每个出厂配置都有一个 T_EEPROM
实例。
有人有更好的主意吗?
这是简短而干净的:
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];
}
为了避免全局变量,您可以将函数更改为:
void InitFactoryEEPROM (T_EEPROM* config, size_t type)
{
assert(type < CONFIG_COUNT);
*config = FactoryEepromConfig[type];
}
在您给出的所有场景(可能性)中,值都需要在内存中,作为变量或作为初始化变量的值。所以内存占用没有太大区别。使用初始化函数会产生执行初始化所需的代码字节开销。
拥有一个包含所有值的静态数组,并且每次需要一个值时都对其进行索引,这会产生索引数组的指令开销。将数组索引的值复制到 "working set" 变量会产生额外变量的开销。
可能你可以通过制作几个版本来衡量哪个最小,例如:
一个为每个参数访问建立索引的静态数组;
一个静态数组并将工作集复制到一个额外的变量;
正在使用初始化函数初始化工作集变量。
但这假设工作值集可以在执行期间更改。如果它们不改变,那么您可以使用 #define
s 到 select 值的工作集,并将其用于工作集变量的静态初始化。