0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式分享#62:volatile 到底在防谁?

BSP调试从0到1 来源:嵌入式分享 作者:嵌入式分享 2026-05-27 16:48 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式 C 的朋友,应该都见过volatile。它常出现在寄存器、中断标志位、状态变量这些地方,但也特别容易被误解。

很多新手会觉得:volatile不就是修饰变量的吗?甚至怕出问题,所有变量都加一个。其实这玩意不是护身符,用错了照样坑。

先说结论:

volatile是用来告诉编译器:这个变量或地址可能被程序之外的因素改变,每次访问都必须真实发生,不要缓存,不要乱优化。

1. 一个典型坑

比如读取 GPIO 输入寄存器,等待引脚变成高电平:

unsignedintgpio_val = *(unsignedint*)0x12345678;while(gpio_val ==0) { // 期望一直读取 GPIO 状态}
这段代码看起来没毛病,但实际可能直接死循环。

原因很简单:gpio_val只在进入循环前读了一次。后面 while 判断的一直是这个普通变量,而不是重新读取硬件寄存器。

正确写法应该是:

#defineGPIO_IN_REG (*(volatile unsigned int *)0x12345678)while(GPIO_IN_REG ==0) { // 每次循环都会重新读取寄存器}
这就是volatile的价值:防止编译器把硬件寄存器当普通变量优化。

2. 为什么嵌入式必须懂 volatile?

在嵌入式里,很多变量或地址的值,不一定由当前代码修改。

比如:

  • GPIO 输入寄存器会被外部电平改变;

  • ADC 数据寄存器会被硬件更新;

  • 中断服务函数会修改标志位;

  • DMA 可能在后台修改内存。

如果不加volatile,编译器可能认为这个值“不变”,于是缓存到 CPU 寄存器里,后续不再真实访问内存或硬件地址。

这在普通 C 程序里可能没问题,但在嵌入式里就容易出现“调试看着正常,运行直接抽风”的问题。

3. 硬件寄存器必须加

典型写法如下:

#defineGPIO_CTRL_REG (*(volatile unsigned int *)0x12345678)#defineGPIO_IN_REG  (*(volatile unsigned int *)0x1234567C)unsignedintread_gpio(void){ returnGPIO_IN_REG;}voidset_gpio_output(void){  GPIO_CTRL_REG |= (1<< 0);}
读取寄存器时,必须每次读到硬件最新值;写控制寄存器时,也必须真实写入硬件,不能被编译器省略或延迟。

	

4. 几个常见误区

误区一:volatile 能保证原子性。

错。volatile只保证每次真实访问,不保证操作不可打断。

volatile int cnt;
cnt++;

cnt++本质是“读-改-写”三步,多线程同时执行仍然会有竞态。该用锁、原子操作时,还是要老老实实用。

误区二:所有变量都加 volatile 更安全。

错。volatile会限制编译器优化,滥用会降低效率。普通局部变量、临时计算变量,不需要加。

误区三:volatile 不能和 const 一起用。

也错。比如只读硬件寄存器:

#define ADC_DATA_REG (*(volatile const unsigned int *)0x12345680)

const表示程序不能写,volatile表示硬件可能改。两者并不冲突。

5. 总结

一句话记住:

volatile防的是编译器优化,不是防多线程竞态。

它常用于硬件寄存器、中断共享变量、DMA 状态标志、轮询等待外部状态等场景。

但它不能替代锁、原子操作、内存屏障和 cache 一致性维护。

所以,volatile的正确姿势不是“能加就加”,而是:该加的地方必须加,不该加的地方别乱加。

(完)


本人专注Linux 嵌入式全栈开发,可提供从硬件方案评估与设计、Linux/Android BSP 适配、驱动开发、外设调试、系统移植到产品交付的全流程技术支持。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5212

    文章

    20792

    浏览量

    338987
  • volatile
    +关注

    关注

    0

    文章

    47

    浏览量

    13823
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    嵌入式前景到底怎么样?

    `嵌入式前景到底怎么样?是很多想要从事嵌入式行业的人有的疑问?而作为未出校门的大学生们来讲,嵌入式就如同一个全新未知的领域,充满着迷茫与疑惑?那么
    发表于 07-06 17:14

    到底什么是嵌入式?我们该如何学习嵌入式

    `  到底什么是嵌入式?我们该如何学习嵌入式  随着IT行业的迅速发展,计算机已经成为生活中不可或缺的一部分,越来越多的人开始向IT行业进攻,可到底应该选择哪个方向成了很多人纠结的问题
    发表于 07-25 17:44

    嵌入式软件编程中const、static、extern和volatile的原理是什么?怎么使用?

    嵌入式软件编程中const、static、extern和volatile的原理是什么?怎么使用?
    发表于 04-28 06:21

    关于嵌入式的技术竞争力的相关资料分享

    转载自火哥公众号 嵌入式老鸟的职场之道相信很多刚入行1-2年,甚至5年10年的嵌入式工程师都会有这些疑惑。我做的事情好像没有多少技术含量,我做的事情好像没有多少创新,做嵌入式的技术竞争力到底在
    发表于 10-27 07:51

    嵌入式软件开发过程

    为了在对嵌入式有更深层次的理解,向Oracle询问了这样的一个问题:我怎么才能知道并懂得我的系统到底在干些什么呢?   Oracle面对这个问题有些吃惊,因为在当时没有人这么问过,而同时代的嵌入式开...
    发表于 10-27 07:28

    Volatile关键字对于嵌入式开发有什么作用呢

    前言进行嵌入式开发中,我们往往会看到一个名为volatile或者__IO的关键字,那么,它们对于嵌入式开发有什么作用呢?浅析volatile
    发表于 11-05 09:20

    嵌入式C volatile、const、define相关资料下载

    嵌入式C volatile、const、define
    发表于 12-15 06:10

    嵌入式软件测试的秘诀有哪些

    为了对嵌入式有更深层次的理解,向Oracle询问了这样的一个问题:我怎么才能知道并懂得我的系统到底在干些什么呢? Oracle面对这个问题有些吃惊,因为在当时没有人这么问过,而同时代的嵌入式开发人员问的...
    发表于 12-21 07:17

    嵌入式程序员常见的const、static、volatile关键字

    嵌入式程序员const、static、volatile三个关键字的朴素认识摘要:C语言程序编写中,const、static关键字是比较熟悉的,volatile关键字是比较少见的。但是
    发表于 12-21 06:08

    嵌入式中定义变量时volatile关键字的作用是什么?

    嵌入式中定义变量时volatile关键字的作用?
    发表于 10-24 07:50

    通用嵌入式基础技术

    相信很多刚入行1-2年,甚至5年10年的嵌入式工程师都会有这些疑惑。我做的事情好像没有多少技术含量,我做的事情好像没有多少创新,做嵌入式的技术竞争力到底在哪?嵌入式
    发表于 05-18 10:20 1405次阅读

    到底什么是嵌入式? 什么是单片机?

    到底什么是嵌入式?什么是单片机?
    的头像 发表于 02-25 16:13 1.6w次阅读

    到底什么是嵌入式

    凡是从事计算机或电子信息相关领域工作的童鞋,一定都听说过嵌入式吧?然而对于非相关专业的同学来说肯定是一知半解,只觉得嵌入式“高端”,但具体什么是嵌入式却一脸懵逼。那么,到底什么是
    发表于 10-19 15:08 8次下载
    <b class='flag-5'>到底</b>什么是<b class='flag-5'>嵌入式</b>?

    嵌入式】C语言中volatile关键字

    00. 目录文章目录00. 目录01. volatile概述02. volatile应用场景03. volatile应用示例04. 嵌入式系统中应用05.
    发表于 10-21 10:21 6次下载
    【<b class='flag-5'>嵌入式</b>】C语言中<b class='flag-5'>volatile</b>关键字

    Volatile关键字嵌入式开发中的应用

    前言进行嵌入式开发中,我们往往会看到一个名为volatile或者__IO的关键字,那么,它们对于嵌入式开发有什么作用呢?浅析volatile
    发表于 11-02 18:21 6次下载
    <b class='flag-5'>Volatile</b>关键字<b class='flag-5'>在</b><b class='flag-5'>嵌入式</b>开发中的应用