其他
Keil、IAR实现处理器复位而变量不被初始化的方法
关注+星标公众号,不错过精彩内容
作者 | strongerHuang
微信公众号 | 嵌入式专栏
有时候,我们有这种需求:处理器复位,要求变量不被初始化。
比如:一个实时统计数据的系统,不想因为某种原因(异常原因死机、看门狗等)复位,而丢失正在计数而未来得及保存的数据。
下面就来讲讲在Keil、 IAR编译环境下,实现该功能的方法。
嵌入式专栏
1
处理器复位的方式有很多种,这里结合STM来讲述MCU复位的来源:
STM32的复位为三类:系统复位、电源复位和后备域复位。
系统复位:
1. NRST引脚上的低电平(外部复位)
2. 窗口看门狗计数终止(WWDG复位)
3. 独立看门狗计数终止(IWDG复位)
4. 软件复位(SW复位)
5. 低功耗管理复位
电源复位:
1. 上电/掉电复位(POR/PDR复位)
2. 从待机模式中返回
备份区域复位:
1. 软件复位,备份区域复位可由设置备份域控制寄存器(RCC_BDCR)中的BDRST位产生。
2. 在VDD和VBAT两者掉电的前提下, VDD或VBAT上电将引发备份区域复位。
请参考《STM32复位来源,Cotrex-M系统与内核复位区别》。
嵌入式专栏
2
实现处理器复位而变量不被初始化方法之前,让我们先了解一下修饰符的知识。
__no_init
嵌入式专栏
3
#define __no_init __attribute__((zero_init))
__no_init uint16_t Cnt_NoInit;
嵌入式专栏
4
在IAR中“__no_init”属于是一个关键字,你会发现在使用这个修饰符之后,字体都是关键字颜色。
直接使用即可,类似上面定义一个不被初始化的变量:
__no_init uint16_t Cnt_NoInit;
嵌入式专栏
5
__no_inituint16_t Cnt_NoInit;
uint16_t Cnt_Init = 100;
int main(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
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
后台回复『嵌入式软件设计与开发』『Keil』『IAR』阅读更多相关文章。
点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。