文章目录
前言
前一段时间排查问题时发现Simulink模型生成的代码中有意思的操作,后面思考了一下,才恍然大悟,本文对思考进行总结。
变量存储的区域
熟悉MCU内存的小伙伴应该知道,bss段和data段的差异,不知道的我可以再简单介绍下:
.bss 段:未初始化或初始化为 0 的全局变量,不占用 Flash 空间 ,仅在 RAM 中分配。
.data 段:初始化为非 0 值的全局变量,既占用 RAM 也占用 Flash (用于存储初始值)
bss段和data段的初始化一般在MCU启动代码中执行,bss段直接对ram赋值为0,data段需要从对应的flash空间copy数据到ram
模型生成代码的思考
模型中定义了一个带初始值的全局变量,但是在生成代码时并没有生成带初始值的全局变量,而是一个没有初值的变量。示例如下:
int g_configVal = 0;
在初始化的函数中,对该变量进行赋值:
void nb_init(void)
{
g_configVal = 1;
}
这样生成代码能够节约变量所占用的flash空间,可能有善于思考小伙伴又要问了,你这初始化函数编译使用不是也要占用flash空间么,确实是这样,所以实际需不需要在初始化函数中进行变量赋值,取决于要初始化的变量有多少,理论上来说,变量越多在初始化中进行赋值越节约flash空间。以下占用情况仅供参考,没有实测过
┌─────────────────────────────────────────────────────────────┐
│ Flash 占用对比曲线 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 变量数量 直接初始化 函数初始化 哪种更优 │
│ ───────────────────────────────────────────────── │
│ 1 个 4 字节 ~10 字节 ✅ 直接初始化 │
│ 2 个 8 字节 ~12 字节 ✅ 直接初始化 │
│ 3 个 12 字节 ~15 字节 ✅ 直接初始化 │
│ 4 个 16 字节 ~18 字节 ✅ 直接初始化 │
│ 5 个 20 字节 ~20 字节 ⚖️ 基本持平 │
│ 10 个 40 字节 ~30 字节 ✅ 函数初始化 │
│ │
│ 💡 临界点:约 5 个变量时开始划算 │
└─────────────────────────────────────────────────────────────┘
同时,也要考虑Flash空间(一般MCU现在Flash都比较大,很少存在flash不够用的情况),如果flash完全够用,也没必要在初始化函数中赋值来初始化了。
总结
合理选择初始化方式,在代码优化中也是能够有一定帮助的,需要注意的时,如果选择在初始化函数中进行初始化变量,一定不要忘记对初始化函数进行调用~