C语言中的volatile

volatile的定义:

Indicates that a variable can be changed by a background routine.
Keyword volatile is an extreme opposite of const.It
 indicates that a variable may be changed in a way which is absolutely unpredictable by analysing the normal program flow (for example, a variable which may be changed by an interrupt handler). This keyword uses the following syntax:

翻译为表示一个变量也许会被后台程序改变,关键字 volatile 是与 const 绝对对立的。它指示一个变量也许会被某种方式修改,这种方式按照正常程序流程分析是无法预知的(例如,一个变量也许会被一个中断服务程序所修改)。

变量如果加上volatile,就会从内存中重新装载内容,而不是从寄存器中拷贝内容。volatile 的作用 是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。

volatile主要由一下几种应用场合:

1). 并行设备的硬件寄存器(如:状态寄存器)

#define GPC1CON *((volatile unsigned int*)0xE0200080)
#define GPC1DAT *((volatile unsigned int*)0xE0200084)
#define GPC1PUD *((volatile unsigned int*)0xE0200088)
...........
 typedef const int32_t sc32;  /*!< Read Only */
  typedef const int16_t sc16;  /*!< Read Only */
  typedef const int8_t sc8;   /*!< Read Only */
  typedef __IO int32_t  vs32;
typedef __IO int16_t  vs16;
typedef __IO int8_t   vs8;
typedef __I int32_t vsc32;  /*!< Read Only */
typedef __I int16_t vsc16;  /*!< Read Only */
typedef __I int8_t vsc8;   /*!< Read Only */
typedef uint32_t  u32;
typedef uint16_t u16;
typedef uint8_t  u8;
typedef const uint32_t uc32;  /*!< Read Only */
typedef const uint16_t uc16;  /*!< Read Only */
typedef const uint8_t uc8;   /*!< Read Only */
typedef __IO uint32_t  vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t  vu8;
typedef __I uint32_t vuc32;  /*!< Read Only */
typedef __I uint16_t vuc16;  /*!< Read Only */
typedef __I uint8_t vuc8;   /*!< Read Only *
..............
#ifdef __cplusplus
  #define   __I     volatile             /*!< defines 'read only' permissions                 */
#else
  #define   __I     volatile const       /*!< defines 'read only' permissions                 */
#endif
#define     __O     volatile             /*!< defines 'write only' permissions                */
#define     __IO    volatile             /*!< defines 'read / write' permissions              */

一个参数既可以是const还可以是volatile吗?

可以的,例如只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。软件不能改变,并不意味着我硬件不能改变你的值,这就是单片机中的应用。

2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 

/*   main.c */
int flag=0;
int main(void)
{
  if(flag==1)
    {do somethings}
  if(flag==2)
        {do somethings}
  return 0;
}
/* interrupt*/
void NVIC_Handler(void)
{
  flag=1;
}

在这种情况下,编译器可能会对其做优化,虽然中断服务函数改变了flag的值,但是编译器并没有在变量内存中去读取,而是在寄存器中读取了flag之前的缓存数据。在中断函数中的交互变量,一定要加上volatile关键字修饰,这样每次读取flag的值都是在其内存地址中读取的,确保是我们想要的数据。


3). 多线程应用中被几个任务共享的变量 

原因其实和上面中断一样,要共享标志,又不想让编译器优化了这一点,需要加上该修饰词。

简洁的说就是:volatile关键词影响编译器编译的结果,用volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错

猜你喜欢

转载自www.cnblogs.com/hjhgogo/p/9951896.html