在keil中使用不初始化变量

本文围绕STM32F030R8单片机,介绍在Keil中设置不初始化变量的方法。系统异常复位后,为保留变量原先值,需阻止初始化操作。文中详细说明了在Keil里设置分散文件、定义变量等步骤,还提及辨别系统上电和复位的方法,此外还给出了其他实现思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单片机型号:STM32F030R8

    我们进行程序设计的时候,都会知道,系统上电或复位时,会执行变量初始化操作,但是有些情况下,我们并不希望变量初始化,例如,在系统异常复位发生后,我们希望系统能够迅速恢复复位前的现场状况,这样就希望变量能够保留原先的值,而不被初始化。实际上,大家都知道,变量是存储在RAM中的,只要不掉电,变量的数值是不会改变的,只要我们不让系统进行初始化操作就可以了。

    不同的编译环境,有不同的设置方法,本文介绍在Keil中设置不初始化变量的方法。在这里需要说明的是,网上介绍了许多的设置方法,但并不是所有的方法都起作用,本文将介绍一种最为直接的方法。

    1、打开Options for Target对话框Linker标签,勾选掉Use Memory Layout from Target Dialog,这个选项的意思是使用Target标签进行链接设置,所以在其勾选的情况下,分散文件是不能自己编辑的,勾选掉以后,我们就可以进行分散文件的设置了。

    2、点击分散文件后面的Edit按钮,打开分散文件,按下图所示的方法,增加节点。原先仅有一个RAM节点,其起始地址是0x20000000,其长度是0x00008000。我们新编辑的分散文件,将RAM分为2部分,第1部分长度为0x7000,第2部分长度为0x1000,并将第2部分设置为UNINIT,也就是不初始化,显式节点名为NO_INIT。

    3、有了上述设置后,我们就可以进行变量设置了,在这里需要注意的是变量需定义为全局变量,且不能赋初值,后面要加入存放的节点,如下面程序所示。我们定义了5个变量,第1个为u16_Start,后面为4个数组(仅是举例子,没有什么实际意义)。

    uint16_t u16_Start __attribute__((section("NO_INIT"),zero_init));                        
    uint16_t u16_a[2]  __attribute__((section("NO_INIT"),zero_init));            
    uint16_t u16_b[2]  __attribute__((section("NO_INIT"),zero_init));        
    uint16_t u16_c[2]  __attribute__((section("NO_INIT"),zero_init));            
    uint16_t u16_d[2]  __attribute__((section("NO_INIT"),zero_init));

    4、正确编译后,将程序下载到目标板,我们就可以观察到这些变量不会因为单片机复位,而被初始化了。不过这又产生了一个新的问题,由于我们没有给这些变量赋初值,当系统上电时,这些变量的值是随机的,所以我们还需要辨别是系统上电,还是系统复位,使用下面的程序就可以了,这也是变量u16_Start的作用。当系统上电时,由于RAM是刚刚加电,所以变量u16_Start为12345的可能性几乎为0,我们认为这是系统上电,将u16_Start设置为12345后,并初始化这些变量。当系统复位时,u16_Start中的数值仍然保留,所以还为12345,这样就不再初始化变量。

        if (u16_Start != 12345)
        {
            u16_Start = 12345;
            u16_a[0] = 0;
            u16_a[1] = 0;
            u16_b[0] = 0;
            u16_b[1] = 0;
            u16_c[0] = 0;
            u16_c[1] = 0;
            u16_d[0] = 0;
            u16_d[1] = 0;
        }

原创性文章,转载请注明出处
优快云:http://blog.youkuaiyun.com/qingwufeiyang12346。
---------------------  
作者:snmplink  
来源:优快云  
原文:https://blog.youkuaiyun.com/qingwufeiyang12346/article/details/79520095  
版权声明:本文为博主原创文章,转载请附上博文链接!

 

可以有另外的方法:

最近一个项目需要保存一下临时数据,而产品容易受干扰而复位。所以需要保存一下数据,那么只有在系统复位时候不再初始化变量即可。对应MDK(keil)来说是一个比较麻烦的问题。通过网络上找了大量资料和测试发现终于可以了。

       如果要实现以上要求,必须设置两点,缺一不可:

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

 

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

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

当然也可以直接:

__attribute__((zero_init))    int  tmp; 

说明:__noinit__ 不是mdk的关键字

 

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值