c - 嵌入式 C:初始化全局数据的风险
问题描述
c语言的一般问题:
在声明中初始化数据是否安全?例子:
static unsigned char myVar =5u;
这个值是否会被启动代码覆盖?
解决方案
通常,嵌入式系统微控制器项目有两种风格,IDE 通常让您选择一种:
- 符合标准 C(有时被混淆的工具供应商称为“ANSI”)。
- 最小化启动。
前一个标准 C 兼容项目要求所有具有静态存储持续时间的变量,例如在文件范围和/或使用关键字声明的变量,在static
调用 main() 之前进行初始化。此初始化发生在启动代码(“C 运行时”/“CRT”)中。在这样的系统上,myVar = 5u;
保证会被启动代码写入(而不是覆盖)。它将值 5 从闪存复制到 RAM。
后者,“mimizined”/“fast”启动版本不严格符合 C 标准。在这样的项目中,所有静态存储持续时间变量的初始化代码都被简单地删除了。这可以减少从重置到调用 main() 的时间。在这样的系统上,没有任何东西会执行static unsigned char myVar =5u;
代码——即使你明确地初始化了它,你的变量仍然是未初始化的和不确定的。您必须在“运行时”手动设置它,这通常是通过一些初始化“构造函数”代码完成的。
如果您static uint8_t foo_count;
属于foo.c
,则该foo
模块将必须提供一个执行foo_init()
代码的函数foo_count = 5;
。
由于“最小化启动”版本在嵌入式系统中非常常见,因此通常认为依赖静态存储持续时间变量的默认初始化是危险的,以防代码被移植到这样的系统。
推荐阅读
- spring-boot - 为什么必须在 AbstractMongoClientConfiguration 中指定数据库名称?
- javascript - 待办事项列表删除所有功能
- javascript - 正则表达式在多个方括号内返回内容
- php - 如何通过 FORM 将数据插入 MYSQL
- javascript - 如何根据值更改元素的颜色
- postgresql - Aurora Postgresql 中的副本和数据库实例有什么区别?
- python - 我们应该使用多少次福特-富克森?
- javascript - 搜索表格单元格
- javascript - 三元条件找expmod?
- python - 如何在Django中将图像从一个表移动到另一个表