linfelix 发表于 2023-9-29 12:00

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

最近一个项目需要保存一下临时数据,而产品容易受干扰而复位。所以需要保存一下数据,那么只有在系统复位时候不再初始化变量即可。对应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

变量可以被定义为全局变量,并且可以显式地指定其节点名

updownq 发表于 2023-10-5 15:06

在变量的声明前面添加关键字volatile。例如,如果你有一个名为my_variable的变量,你可以这样修改它的声明:volatile int my_variable;

lihuami 发表于 2023-10-5 15:20

可能会导致性能下降,因为编译器无法对变量进行优化。

geraldbetty 发表于 2023-10-5 15:46

当你在复位时不初始化一个变量时,这个变量在复位后的值是无法预料的。因此,你应该只在必要的情况下,才使用这种方法。

burgessmaggie 发表于 2023-10-5 15:55

变量的初始值将保留在上一次运行的值上,而不会被清零。

geraldbetty 发表于 2023-10-5 18:59

在程序的复位代码中,将未初始化的变量视为未定义,并对其进行初始化。

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。
有了上述设置后,我们就可以进行变量设置了。在这里需要注意的是变量需定义为全局变量,且不能赋初值,后面要加入存放的节点。

robertesth 发表于 2023-10-5 19:46

通过修改启动文件(startup file)来控制变量的初始化行为。启动文件是在程序启动时被调用的汇编代码文件,负责初始化芯片的系统和变量等。你可以根据需要修改启动文件中的初始化代码,将特定的变量排除在初始化过程之外。

uytyu 发表于 2023-10-5 19:54

volatile关键字只是告诉编译器,变量的值可能会在外部环境的影响下发生变化,而不是实际的内存地址

eefas 发表于 2023-10-5 20:15

使用__no_init关键字来定义变量需要谨慎使用,因为变量的初始状态可能是未定义的,这可能导致不确定的行为。

iyoum 发表于 2023-10-5 20:21

将变量声明为__no_init存储类别可以告诉编译器在复位时不对其进行初始化。例如:

__no_init int myVariable;// 声明一个

burgessmaggie 发表于 2023-10-5 20:54

volatile 关键字用于指示编译器不要对变量进行优化,这样变量在复位时就不会被初始化。

macpherson 发表于 2023-10-5 21:24

在项目中添加一个新的RAM区,然后在该RAM区的属性中选择“ZI”属性,这样就可以避免该RAM区中的变量在复位时被初始化了。

jimmhu 发表于 2023-10-5 21:53

可以使用__no_init关键字来定义变量,以确保在复位时不会被初始化。

saservice 发表于 2023-10-5 22:23

可以使用特殊的存储类别来控制变量的初始化行为

louliana 发表于 2023-10-8 12:41

在程序的其他地方使用该变量。注意,在使用变量之前,必须将其赋初值或使用其他方式保证其有意义。

gygp 发表于 2023-10-8 13:16

在变量定义前添加__attribute__((noinit))修饰符。例如:

int variable;
attribute((noinit));
页: [1] 2
查看完整版本: MDK下怎样才能让变量在复位时不被初始化