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

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

3天内不再提示

一文详解volatile关键字

CHANBAEK 来源:CSDN-借过风景 作者:CSDN-借过风景 2023-02-15 11:54 次阅读

1、volatile关键字

volatile 是易变的、不稳定的意思。 和const一样是一种类型修饰符,volatile关键字修饰的变量,编译器对访问该变量的代码不再进行优化,从而可以提供对特殊地址的稳定访问。
以前只是听过这个关键词,知道它的存在,但从来没用过。 用此文记录下在开发RISC-V MCU过程中,未用volatile修饰标志位变量,编译器进行优化,导致程序运行异常。

2、演示

开发中,常见的需求,主循环中根据中断中修改的标志位,运行不同的功能,

#include "debug.h"
 
uint8_t flag_interrupt = 0;
 
int main(void)
{
    USART_Printf_Init(115200);
    printf("SystemClk:%d\\r\\n",SystemCoreClock);
 
    EXTI0_INT_INIT();
 
    while(1)
    {
        if(flag_interrupt == 1)
        {
            flag_interrupt = 0;
            printf("do something\\r\\n");
        }
    }
}
 
/* 外部中断服务函数*/
__attribute__((interrupt("WCH-Interrupt-fast")))
void EXTI0_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line0)==SET)  //EXTI_GetITStatus用来获取中断标志位状态
    {
        flag_interrupt = 1;
        printf("Run at EXTI\\r\\n");
        EXTI_ClearITPendingBit(EXTI_Line0);  //清除中断标志位
    }
}

进入中断服务函数,改变了flag_interrupt的值,但是主函数仍然没有运行相应的程序,很是奇怪,检查反汇编代码,才发现是编译器对flag_interrupt变量的访问进行了优化,如图,将程序下载至MCU后,给P1.0引脚下降沿触发信号,运行现象如下

图像

图像

278:    01271063 bne    a4,s2,278 0x34> # 不相等就跳转至0x278的位置,即还是本条语句的位置,

可以看到,编译器对flag_interrupt变量的访问进行了优化,没有重新去0x20000080的位置进行取值,而是每次都用a4寄存器的值与s2寄存器(值为1)比较,不相等还是跳回本条语句的位置,重复运行,导致即使在中断中改变了其值,主循环中也不能运行对应的功能。 这时候就需要使用volatile关键字对flag_interrupt进行修饰。

volatile uint8_t flag_interrupt = 0;

加了volatile关键字修饰flag_interrupt后,程序按照设定的预期运行,如下图所示:

图像

查看反汇编代码,编译器未对flag_interrupt变量进行优化,老老实实的每次去源地址0x20000080处取值访问。

图像

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

    关注

    5

    文章

    895

    浏览量

    41338
  • 代码
    +关注

    关注

    30

    文章

    4708

    浏览量

    68176
  • 编译器
    +关注

    关注

    1

    文章

    1614

    浏览量

    49002
  • 关键字
    +关注

    关注

    0

    文章

    37

    浏览量

    6889
  • volatile
    +关注

    关注

    0

    文章

    44

    浏览量

    12995
收藏 人收藏

    评论

    相关推荐

    C语言关键字volatile的用法

    许多程序员都无法正确理解C语言关键字volatile,这并不奇怪。因为大多数C语言书籍通常都是一两句带而过,本文将告诉你如何正确使用它。
    发表于 04-11 09:35 2528次阅读

    c语言中 volatile _Bool 关键字说明

    volatile 关键字呢?volatile总是与优化有关,编译器有种技术叫做数据流分析,分析程序中的变量在哪里赋值、在哪里使用、在哪里失效,分析结果可以用于常量合并,常量传播等优
    发表于 01-06 10:46

    请问关键字volatile该什么时候用?

    这东西的概念我懂,但是实际编程时,关键字volatile该什么时候用啊,求大神来点经验之谈!
    发表于 04-28 09:06

    【原创分享】单片机编程关键字volatile

    volatile其实和const样是种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素而改变,比如操作系统、硬件或者其他线程等等。遇到这个关键字声明的变量,编译器对访问该
    发表于 06-29 11:17

    C语言volatile关键字详解 精选资料分享

    1.volatile和什么有关百度翻译是这样子翻译volatile的:图1-1 百度翻译volatile截图volatile属于C语言的关键字
    发表于 07-22 07:20

    volatile关键字应用场景及示例

    volatile关键字1.应用场景2.示例1.应用场景volatile关键字分析,往往应用在三种场合1)多线程编程共享全局变量的时候,该全局变量要加上
    发表于 08-24 07:21

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

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

    C语言volatile关键字之间有什么关系?

    C语言volatile关键字之间有什么关系?
    发表于 11-11 07:01

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

    开发中,const、static、volatile都是很常见的,我们嵌入式程序员需要熟知这三个关键字的恰当用法。下面是我参照网路上的大咖,大牛的博,然后做些代码测试,撰写
    发表于 12-21 06:08

    C语言中的volatile关键字

    volatile关键字种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改。
    发表于 05-27 09:32 3262次阅读

    关于volatile关键字对编译器优化的影响

    volatile关键字对编译器优化的影响
    的头像 发表于 02-28 17:15 2888次阅读

    般什么时候需要使用volatile关键字

    想必大家平时都见过volatile关键字,可是大家知道什么时候需要使用volatile关键字吗?
    的头像 发表于 12-24 17:29 992次阅读

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

    volatile06. 附录01. volatile概述volatile是C语言中的关键字。将变量定义为
    发表于 10-21 10:21 6次下载
    【嵌入式】C语言中<b class='flag-5'>volatile</b><b class='flag-5'>关键字</b>

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

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

    C环境中的VOLATILE关键字

    volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这 个变量的时候,都会直接从变量地址中读取数据。如果没有 volatile 关键字,则编译器可能
    发表于 06-14 15:03 2次下载
    C环境中的<b class='flag-5'>VOLATILE</b><b class='flag-5'>关键字</b>