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声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错

原文地址:http://www.cnblogs.com/rongjiangwei/p/16886923.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性