打印
[应用相关]

MDK下怎样才能让变量在复位时不被初始化

[复制链接]
897|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
linfelix|  楼主 | 2023-9-29 12:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近一个项目需要保存一下临时数据,而产品容易受干扰而复位。所以需要保存一下数据,那么只有在系统复位时候不再初始化变量即可。对应MDK(keil)来说是一个比较麻烦的问题。通过网络上找了大量资料和测试发现终于可以了。
如果要实现以上要求,必须设置两点,缺一不可:

1. 在MDK的选项中设置如下:

2. 必须在程序代码中如下编写:

#define__noinit____attribute__((zero_init))// 变量不初始化为0
__noinit__ int tmp; // 变量前加上宏__noinit__

当然也可以直接:

__attribute__((zero_init))int tmp;

说明:__noinit__不是mdk的关键字

当然也可以直接把启动代码中的__main()改成main(),也可以达到相同的目的,但是不知道有没有什么不好的影响。

使用特权

评论回复
沙发
kkzz| | 2023-10-5 13:16 | 只看该作者
在中断向量表中,可以定义一些特殊的存储区域,这些区域在复位时不会被初始化。例如,可以定义一个名为NonInit的存储区域,然后在定义变量时,可以使用这个存储区域来存储变量。

使用特权

评论回复
板凳
bartonalfred| | 2023-10-5 13:48 | 只看该作者
__attribute__((section(".data"))) __attribute__((zero_init)) int myVar;

使用特权

评论回复
地板
biechedan| | 2023-10-5 13:59 | 只看该作者
变量可以被定义为全局变量,并且可以显式地指定其节点名

使用特权

评论回复
5
updownq| | 2023-10-5 15:06 | 只看该作者
在变量的声明前面添加关键字volatile。例如,如果你有一个名为my_variable的变量,你可以这样修改它的声明:volatile int my_variable;

使用特权

评论回复
6
lihuami| | 2023-10-5 15:20 | 只看该作者
可能会导致性能下降,因为编译器无法对变量进行优化。

使用特权

评论回复
7
geraldbetty| | 2023-10-5 15:46 | 只看该作者
当你在复位时不初始化一个变量时,这个变量在复位后的值是无法预料的。因此,你应该只在必要的情况下,才使用这种方法。

使用特权

评论回复
8
burgessmaggie| | 2023-10-5 15:55 | 只看该作者
变量的初始值将保留在上一次运行的值上,而不会被清零。

使用特权

评论回复
9
geraldbetty| | 2023-10-5 18:59 | 只看该作者
在程序的复位代码中,将未初始化的变量视为未定义,并对其进行初始化。

使用特权

评论回复
10
iyoum| | 2023-10-5 19:31 | 只看该作者
在Keil MDK中,可以通过以下步骤来实现在复位时不初始化变量:

打开Options for Target对话框,在Linker标签下,去掉勾选“Use Memory Layout from Target Dialog”。这个选项的意思是使用Target标签进行链接设置,勾选的情况下,分散文件是不能自己编辑的。
点击分散文件后面的Edit按钮,打开分散文件。原先仅有一个RAM节点,其起始地址是0x20000000,其长度是0x00008000。我们可以新编辑分散文件,将RAM分为2部分,第1部分长度为0x7000,第2部分长度为0x1000,并将第2部分设置为UNINIT,也就是不初始化,显式节点名为NO_INIT。
有了上述设置后,我们就可以进行变量设置了。在这里需要注意的是变量需定义为全局变量,且不能赋初值,后面要加入存放的节点。

使用特权

评论回复
11
robertesth| | 2023-10-5 19:46 | 只看该作者
通过修改启动文件(startup file)来控制变量的初始化行为。启动文件是在程序启动时被调用的汇编代码文件,负责初始化芯片的系统和变量等。你可以根据需要修改启动文件中的初始化代码,将特定的变量排除在初始化过程之外。

使用特权

评论回复
12
uytyu| | 2023-10-5 19:54 | 只看该作者
volatile关键字只是告诉编译器,变量的值可能会在外部环境的影响下发生变化,而不是实际的内存地址

使用特权

评论回复
13
eefas| | 2023-10-5 20:15 | 只看该作者
使用__no_init关键字来定义变量需要谨慎使用,因为变量的初始状态可能是未定义的,这可能导致不确定的行为。

使用特权

评论回复
14
iyoum| | 2023-10-5 20:21 | 只看该作者
将变量声明为__no_init存储类别可以告诉编译器在复位时不对其进行初始化。例如:

__no_init int myVariable;  // 声明一个

使用特权

评论回复
15
burgessmaggie| | 2023-10-5 20:54 | 只看该作者
volatile 关键字用于指示编译器不要对变量进行优化,这样变量在复位时就不会被初始化。

使用特权

评论回复
16
macpherson| | 2023-10-5 21:24 | 只看该作者
在项目中添加一个新的RAM区,然后在该RAM区的属性中选择“ZI”属性,这样就可以避免该RAM区中的变量在复位时被初始化了。

使用特权

评论回复
17
jimmhu| | 2023-10-5 21:53 | 只看该作者
可以使用__no_init关键字来定义变量,以确保在复位时不会被初始化。

使用特权

评论回复
18
saservice| | 2023-10-5 22:23 | 只看该作者
可以使用特殊的存储类别来控制变量的初始化行为

使用特权

评论回复
19
louliana| | 2023-10-8 12:41 | 只看该作者
在程序的其他地方使用该变量。注意,在使用变量之前,必须将其赋初值或使用其他方式保证其有意义。

使用特权

评论回复
20
gygp| | 2023-10-8 13:16 | 只看该作者
在变量定义前添加__attribute__((noinit))修饰符。例如:

int variable;
attribute((noinit));

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

1218

帖子

1

粉丝