[C.C++] C语言-volatile

362 0
Honkers 2025-6-13 02:29:18 来自手机 | 显示全部楼层 |阅读模式

还是为了自己学习啊 自己基础太差了 

在C/C++嵌入式代码中,你是否经历过以下情况:

  • 代码执行正常–直到你打开了编译器优化

  • 代码执行正常–直到打开了中断

  • 古怪的硬件驱动

  • RTOS的任务独立运行正常–直到生成了其他任务

    如果你的回答是“yes”,很有可能你没有使用C语言关键字volatile。你并不是唯一的,很多程序员都不能正确使用volatile。不幸的是,大多数c语言书籍对volatile的藐视,只是简单地一带而过。

    volatile用于声明变量时的使用的限定符。它告诉编译器该变量值可能随时发生变化,且这种变化并不是代码引起的。给编译器这个暗示是很重要的。在开始前,我们向来看一看volatile的语法。

C语言关键字volatile语法

    声明一个变量为volatile,可以在数据类型之前或之后加上关键字volatile。下面的语句,把foo声明一个volatile的整型。

  1. volatile int foo;int volatile foo;
复制代码

    把指针指向的变量声明为volatile很常见,尤其是I/O寄存器的地址映射。下面的语句,把pReg声明为一个指向8-bit无符号指针,指针指向的内容为volatile。

  1. volatile uint8_t * pReg;uint8_t volatile * pReg;
复制代码

    volatile的指针指向非volatile的变量很少见(我只使用过一次),但我还是给出相应的语法。

  1. int * volatile p;
复制代码

    顺便提一下,关于为什么要在数据类型前使用volatile关键字,请自行百度搜素。

    最后,如果你再struct或者union前使用volatile关键字,表明struct或者union的所有内容都是volatile。如果这不是你的本意,可以在struct或者union成员上使用volatile关键字。

正确使用C语言关键字volatile

    只要变量可能被意外的修改,就需要把该变量声明为volatile。在实际应用中,只有三种类型数据可能被修改:

  • 外设寄存器地址映射

  • 在中断服务程序中修改全局变量

  • 在多线程、多任务应用中,全局变量被多个任务读写

    接下来,我们将分别讨论上述三种情况。

外设寄存器

    嵌入式系统包含真正的硬件,通常会有复杂的外设。这些外设寄存器的值可能被异步的修改。举个简单的例子,我们要把一个8-bit状态寄存器的地址映射到0x1234。在程序中循环查看该状态寄存器的值是否变为非0。

    下面是最容易想到,但错误的实现方法:

当你打开编译器优化时,程序总是执行失败。因为编译器会生成下面的汇编代码:

 程序被优化的原因很简单,既然已经把变量的值读入累加器,就没有必要重新一遍,编译器认为值是不会变化的。就这样,在第三行,程序进入了无限死循环。为了告诉编译器我们的真正意图,我们需要修改函数的声明&#x

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4014
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行