之前笔者在做一个基于 Air724UG openmcu CSDK
项目,里面写了如下的代码片段。
uint32_t flag = 0;
void timer_handle(void *para)// 1秒定时器中断
{
flag = 1;
}
void thread_run(void *para)
{
if (flag)
{
flag = 0;
do1();
}
do2();
}
按正常的逻辑应该是每次执行一次thread_run
就能执行一次do2
,thread_run
执行频率很高,所以每秒都能执行一次do1
。但是经常系统跑着跑着就发生很玄学的事情,只执行do2
,再也不执行do1
了。
相信有经验的工程师一眼就能发现问题,但当时系统架构复杂,加上Air724UG openmcu CSDK开发用的人少,源码又不开放,第一感觉是认为定时器挂掉了导致的。后面加入一系列log,细细分析才发现一切都是volatile
惹的祸。只缘身在此山中,一下子没分析出来,有点尴尬。。。
volatile关键字一般是告诉编译器不要去优化变量。以下几个地方是volatile关键字常用到的地方:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile(就像笔者遇到的这一场景);
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为寄存器可能因为外设或其他原因发生了变化;加入该关键字可以让程序到对应的寄存器地址取值,而不是从ram里面读取,熟悉stm32的朋友应该不陌生。
如果有工程师朋友在以上场景也遇到了类似笔者“玄学”的地方,可以对照是否有加入volatile
关键字。