先了解一下修饰符知识
修饰符是用于限定类型以及类型成员申明的一种符号。如c语言中常见的修饰符:
1.static静态修饰符:修饰变量,函数。作用域:变量仅仅在本文件可见,函数在本文件可以被调用;
2.extern声明修饰符:修饰变量,函数。修饰变量时候,变量的声明在外面;
3.const常量修饰符:修饰变量,函数。修饰变量时候,不能被重复赋值,只能放在只读段中;
4.volatile不稳定变量修饰符:这个变量不好翻译,在c中的作用大概有两点意思:a.表示变量是易失的,易变的;b.强制访存操作,防止编译器去优化,告诉编译器每次必须去内存中取值,而不是从寄存器或者缓存。
在c++ java中还有更多:
public公共访问修饰符、private私有访问修饰符、protected保护访问修饰符、friendly、abstract等。
了解了修饰符之后,看见本文标题就知道本文提供的那个修饰符对于变量来说是比较重要的。
之前写过一篇文章【cm3(stm32)内核复位与系统复位区别及应用】,讲述了系统和内核复位之后存在差异,其实主要就是说内核复位之后,芯片外设资源没有进行复位的操作。
而本文说的修饰符,修饰的变量位于ram中,在默认情况下,编译器会将其变量存放在主ram中,并在启动时对其进行初始化。而本文说的__no_init类型修饰符使编译器把变量放在非易失ram区中,在启动时也不对它们进行初始化,也就是说__no_init在系统启动时不初始化变量。
什么情况下使用这修饰符使系统禁止变量的初始化?
看门狗复位的现场恢复,如果初始化了就完全不可恢复了。
在keil和iar集成开发环境下,这个修饰符有所不同;keil中不集成这个修饰符,需要配置; 而iar中集成这个修饰符,可直接使用。
ⅰ
keil中__no_init的配置和使用
在keil中,__no_init不是集成在开发环境中,故需要配置,配置之后就可以使用了。
1.宏定义__no_init
#define __no_init __attribute__((zero_init))
2.在工程选项中配置__no_init
project -> options for targets -> target,里面右下有个noinit,这个就是需要我们配置的区域(可设定某一区域);
3.使用方法
__no_init uint16_t cnt_noinit;
提示:不能初始化这个变量。
ⅱ
iar中的__no_init
iar中的“__no_init”是一个关键字,你会发现在使用这个修饰符之后,字体都是关键字颜色。
__no_init uint16_t cnt_noinit;
ⅲ
例程源代码下载与说明
代码下载地址:
http://pan.baidu.com/s/1hskscba
两个工程名称:
1.stm32f103ze(keil)_复位不初始化变量noinit
2.stm32f103ze(iar)_复位不初始化变量noinit
本文提供的例程是一个demo比较简单,但具有实际意义。keil和iar工程实现的功能一样。
源代码:
__no_inituint16_t cnt_noinit;
uint16_t cnt_init = 100;
intmain(void)
{
system_initializes();
printf(start...\n); //复位打印
while(1)
{
printf(cnt_noinit = %d\n, cnt_noinit); //打印变量
cnt_noinit++;
if(cnt_noinit > 1000)
{
cnt_noinit = 0;
}
printf(cnt_init = %d\n, cnt_init);
cnt_init++;
if(cnt_init > 1000)
{
cnt_init = 0;
}
led_on;
timdelay_nms(500);
led_off;
timdelay_nms(500);
nvic_systemreset(); //系统复位
}
}
不初始化变量,则会打印如下消息:
start...
cnt_noinit = 0
cnt_init = 100
start...
cnt_noinit = 1
cnt_init = 100
start...
cnt_noinit = 2
cnt_init = 100
start...
cnt_noinit = 3
cnt_init = 100
如果cnt_noinit不被修饰成不初始化
uint16_t cnt_noinit;
uint16_t cnt_init = 100;
则会打印出如下信息
start...
cnt_noinit = 0
cnt_init = 100
start...
cnt_noinit = 0
cnt_init = 100
start...
cnt_noinit = 0
cnt_init = 100
start...
cnt_noinit = 0
cnt_init = 100
相信聪明的你,看了上面例子会明白为什么没有初始化的变量“cnt_noinit”在变化,而初始化了的“cnt_init”一直不变。
手机摄像头:成就独一无二的产业链
电子节气门控制系统的工作原理和检测步骤
硬核MCU技术为汽车智能化控制保驾护航
VR与文旅高度融合,打开了新世界大门
提升工业相机性能,YXC扬兴科技:YSO110TR石英振荡器助力稳定信号传输
一种修饰符能使变量在处理器复位而不被初始化
压电薄膜传感器工作原理以及应用
D1智能手表推世界杯纪念版,售价199元起
如何检测车速传感器?
人工智能开放平台的作用是什么?
嵌入式核心板在全自动生化仪设备中的应用
基于CAN智能模块和网络服务器实现DNC集成制造系统的设计
除了价钱贵,iPhone8新神秘设计我很喜欢
“老旧系统”没有正式的定义
36种常见家用照明控制原理图
巨哥科技发布光谱建模软件与水质监测模型
空中唤醒:为低功耗设备量身定制
惯性导航在GNSS导航中的应用
水电站智慧生态流量监测,实时在线、超限报警
中国移动5G医疗边缘云平台发布,携手中兴共创5G智慧医疗新时代