许多程序员都无法正确理解C语言关键字 volatile,这并不奇怪。因为大多数C语言书籍通常都是一两句一带而过,本文将告诉你如何正确使用它。
RTOS的任务独立运行正常–直到生成了其他任务
声明一个变量为volatile,可以在数据类型之前或之后加上关键字volatile。下面的语句,把foo声明一个volatile的整型。
volatile int foo;
int volatile foo;
volatile uint8_t * pReg;
uint8_t volatile * pReg;
int * volatile p;
最后,如果你再struct或者union前使用volatile关键字,表明struct或者union的所有内容都是volatile。如果这不是你的本意,可以在struct或者union成员上使用volatile关键字。
只要变量可能被意外的修改,就需要把该变量声明为volatile。在实际应用中,只有三种类型数据可能被修改:
在多线程、多任务应用中,全局变量被多个任务读写
接下来,我们将分别讨论上述三种情况。
嵌入式系统包含真正的硬件,通常会有复杂的外设。这些外设寄存器的值可能被异步的修改。举个简单的例子,我们要把一个8-bit状态寄存器的地址映射到0x1234。在程序中循环查看该状态寄存器的值是否变为非0。
在中断服务程序中,经常会修改一些全局变量值,来作为主程序中的判断条件。例如,在串口中断服务程序中,可能会检测是否接收到了ETX(假如是消息的结束标识符)字符。如果接收到了ETX,ISR设置一个全局标志位。
在实时系统中,尽管有想queues,pipes等这些同步机制,使用全局变量实现两个任务共享信息的做法依然很常见。即使在你的程序中加入了抢占式调度器,你的编译器依然无法知道什么是上下文切换,或何时发生上下文切换。因此从概念上讲,多任务修改全局变量的做法与中断服务程序中修改全局变量的做法是相同的。
因此,所有这类全局变量都应该声明为 volatile。
往期推荐
来都来了,点个 在看 再走吧~~~