ARTS 挑战打卡的第8天 ---volatile 关键字在MCU中的作用,四个实例讲解(Tips)
前言
(1)volatile 关键字作为嵌入式面试的常考点,很多人都不是很了解,或者说一知半解。
(2)可能有些人会说了,volatile 关键字不就是防止编译器优化的吗?有啥好详细讲解的?那么,我就反问一句,为什么要防止编译器优化,编译器优化什么?编译器优化之后会产生什么问题?
(3)今天我就来详细解答一下这些疑惑。
软件延时所造成的bug
(1)在初学51单片机的时候,我们都是使用软件延时,例如下面是STC89,12MHZ晶振的1ms的软件延时。
(2)有些人说,这样写延时可以啊,没有问题。但是,假如你在MSP430中这样写,一定会产生bug。你会发现,软件延时没效果。
(3)这个时候,有些人会告诉你,要让CCS的编辑优化等级降低然后就可以了。
(4)这是为什么呢?如下代码,编译会发现,这就是让两个变量进行自减,于是编译器自作主张,认为这是没有意义的代码,并且将其删除。于是,你看汇编代码会发现,这里没有进行自减操作。
(5)但是,如果你加上volatile 关键字,就会发现,软件延时能够正常运行。这个是为什么呢?volatile 关键字会告诉编译器,这个变量你没有权限动,你不要擅自主张的进行优化。
(6)因此,我们可以知道,volatile 关键字其实就是告诉编译器,不要对变量进行优化。
void Delay1ms() //@12.000MHz
{unsigned char i, j;//加上volatile 关键字//volatile unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);
}
外设寄存器被异步修改所产生的bug
(1)假设我们现在有一个外设寄存器叫做ExternalDevice ,这个寄存器会自动减少,地址为0x1000。(例如定时器的计数器就会自己增加或减少)
(2)现在我们要等ExternalDevice 寄存器值变成0的时候,再进行一些操作。
(3)但是你实际跑的时候会发现,这个地方要么无法阻塞,要么永远阻塞。这是为什么呢?编译器是不知道ExternalDevice这个变量是一个寄存器的,也不知道他最终是怎么变化的。所以他就会认为,这个地方是一个不变的变量进行反复判断。他就会把while()这一行代码删除,认为是没有意义的。
(4)于是我们需要加上volatile 告诉编译器,这个东西你别动。
int main()
{//下面这三种写法是等价的//int volatile *ExternalDevice = (uint8_t volatile *)0x1000; //volatile int *ExternalDevice = (uint8_t volatile *)0x1000; //volatile int *ExternalDevice = (volatile uint8_t *)0x1000; int *ExternalDevice = (uint8_t *)0x1000; // 假设外设寄存器的地址是 0x1000while(*ExternalDevice == 0); //等待这个外设寄存器的值变成0再进行操作
}
全局变量在中断和正常运行的程序存在竞争问题
(1)比如群友给出一个这样的代码,发现一直无法实现点灯。感到非常的疑惑。
(2)这个地方就涉及到全局变量在中断和正常运行的程序存在竞争问题。我们会发现,中断程序和主函数里面都调用了全局变量a。但是,我们要知道,编译器是无法知道运行态的情况的,他只能够进行静态优化。
(3)比如这里,编译器他会认为,变量a的赋值是0。然后主函数里面的while()判断是判断他是否为0。这个时候,他无法查看到串口中断的情况,就会认为,你就是要进行一个死循环。所以,最终这个程序最终会卡死在while(a == 0);这里。
(4)因此我们要将a加上volatile 关键字。

多线程共享变量
(1)当我们上了操作系统之后,都是会跑多线程的。
(2)但是跑多线程,就会存在一个问题,我们很可能会让一个变量让多个线程之间共享。例如,下面我们需要创建两个线程,一个是GUI图像显示,一个是按键扫描。他们都需要共享要给变量key_num。这个时候,编译器无法知道key_num什么时候会进行改变,所以他可能就会想,既然我不知道,我就不要他。所以,我们需要加上volatile 关键字,告诉编译器,这里不要搞骚操作
uint8_t key_num;
//线程1
void GUI()
{while(1){switch(key_num){case key_short_down://...break;case key_long_down://...break;case key_up://...break;}}
}
//线程2
void key_scanf()
{while(1){if(key_Pin == HIGH) key_num = key_up;else if(key_time < 2000) key_num = key_short_down;else key_num = key_short_down;}
}
void main()
{register_task(GUI);register_task(key_scanf);while(1);
}
总结
(1)volatile 关键字本质就是编译器防止优化。但是我们也要明白,为什么编译器会进行优化。知道这个以后,我们才能够更好的使用volatile 关键字。
相关文章:
ARTS 挑战打卡的第8天 ---volatile 关键字在MCU中的作用,四个实例讲解(Tips)
前言 (1)volatile 关键字作为嵌入式面试的常考点,很多人都不是很了解,或者说一知半解。 (2)可能有些人会说了,volatile 关键字不就是防止编译器优化的吗?有啥好详细讲解的࿱…...
第二课-一键安装SD-Stable Diffusion 教程
前言 看完这篇文章并跟着操作,就可以在本地开始 SD 绘图了。 理论上来说,这篇课程结束,想要画什么图都可以画了。 启动器介绍 SD 是开源的,可以在 github 上找到。但直接下载源码安装,非常费劲,而且因为国内外差异,就是我这样的秃头程序员也难以应对。 所以,我们改…...
Vue3 动态列 <el-table-column> 实现 formatter 的两种方法
文章目录 动态列实现动态列实现formatter第一种第二种方法 动态列实现 参考此篇文章 Vue3 动态列实现 动态列实现formatter 第一种 以此为例:传递该行的wxUserInfo字段(对象)中的nickName 假设该行 {prop: "wxUserInfo", label: …...
室温超导是什么?有哪些应用场景?
目录 一、应用场景:二、案例分析: 室温超导是指在室温下(即约 20C 至 30C)实现超导现象的材料。超导是指某些材料在低温下电阻为零的物理现象,室温超导材料是超导材料的一种。室温超导现象的发现和研究是超导领域的一个…...
Windows+VMware+Ubuntu+Anaconda+VMware Tools
Q1:Windows不支持***agent模拟器 A1:在VMware安装Ubuntu虚拟机 P1: 下载 VMware-workstation-full-15.5.6-16341506.exe 安装包(峰哥电脑软件) P2: 下载Ubuntu镜像 地址 ubuntu-18.04.6-desktop-amd64.iso P3:搭载镜…...
Xray配置文件详解
Xray配置文件详解 1.并发配置2.HTTP配置3.插件配置4.被动代理配置5.反连平台配置1.并发配置 在配置文件中可以用下面的配置改变漏洞探测的 worker 数量: parallel: 30 # 漏洞探测的 worker 数量,可以简单理解为同时有 30 个 POC 在运行这个值并非越大越好,因为高并发的情况…...
flink优化
1. 大状态调优 大状态调优:在我们的项目中,在做新老访客修复时,我们将每个mid的访问时间都存到了状态里面,在做回流用户数时,我们将每个用户的登录时间都存到了状态里面,导致了大状态问题,由于…...
docker: ERROR: Couldn‘t connect to Docker daemon at http+docker://localhost
环境: linuxt centos 7.x 如下图, 使用docker-compose时,提示错误 [explorebridge tinyproxy]$ docker-compose up ERROR: Couldnt connect to Docker daemon at httpdocker://localhost - is it running?If its at a non-standard locati…...
大模型在金融医疗、生命系统和物理仿真领域的创新应用探索
点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 在当今迅速发展的科技领域,大模型技术正日益成为金融医疗、生命系统和物理仿真等领域中的重要工具。2023年6月16日,AI TIME举办的青年科学家大模型专场活动邀请了国防科技大学理学院数学…...
tensorflow / tensorflow-gpu cuda cudNN tensorRT 安装,启用显卡加速
tensorflow / tensorflow-gpu cuda cudNN tensorRT 安装,启用显卡加速 说明 Tensorflow-GPU 已被移除。请安装 tensorflow 。 tensorflow 通过 Nvidia CUDA 支持 GPU 加速操作。 自 2019 年 9月发布 的 TensorFlow2.1 以来,tensorFlow 和 tensorflow-GPU 一直是同…...
计算机视觉中的Transformer
几十年来,理论物理学家一直在努力提出一个宏大的统一理论。通过统一,指的是将被认为是完全不同的两个或多个想法结合起来,将它们的不同方面证明为同一基础现象。一个例子是在19世纪之前,电和磁被看作是无关的现象,但电…...
UVA-1601 万圣节后的早晨 题解答案代码 算法竞赛入门经典第二版
GitHub - jzplp/aoapc-UVA-Answer: 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 以三个点的当前位置作为状态,广度优先遍历,找到终点即为最短次数。 注意: 一次可以移动多个点,但是每个点只能移动一步。在同一次中…...
nacos 403错误
403错误 2023-08-12 18:04:55,418 [main] ERROR [com.alibaba.cloud.nacos.client.NacosPropertySourceBuilder:106] [trace,span,parent] - get data from Nacos error,dataId:gateway-server.yaml, com.alibaba.nacos.api.exception.NacosException: <html><body&…...
Python遥感图像处理应用篇(三十四):GDAL+Scikit-image+GLCM计算遥感图像纹理特征
1.运行环境 GDAL 3.4.2,Scikit-image最新版本0.19.3,numpy1.21.5 GDAL主要用于实现图像的读取和保存,Scikit-image和numpy对图像进行各种计算处理。 在调试好之前,由于numpy版本(1.16.6)低的问题,运行提示如下错误,更新为1.21.5版本之后就可以正常运行了,在此记录一…...
solr迁移到另一个solr中(docker单机)
背景介绍 solr数据迁移,或者版本升级,需要用到迁移,此处记录一下迁移方法以及过程中遇到的问题。我这边使用的是docker环境,非docker部署的应该也是一样的。 solr部署教程 准备工作 ● solrA 版本: 8.11.2 (已有so…...
谁能讲清楚Spark之Spark系统架构
### 整体架构概述 Spark与Hadoop MapReduce的结构类似,Spark也采用Master-Worker结构。如果一个Spark集群由4个节点组成,即1个Master节点和3个Worker节点,那么在部署Standalone版本后,Spark部署的系统架构图如图2.1所示。简单来说,Master节点负责管理应用和任务,…...
力扣:59. 螺旋矩阵 II(Python3)
题目: 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 来源:力扣(LeetCode) 链接:力扣(LeetCode)官网 - 全…...
【electron】electron项目创建的方式:
文章目录 【1】npm init quick-start/electron(推荐)【2】 克隆仓库,快速启动【3】 通过脚手架搭建项目【4】 手动创建项目 【Electron官网】https://www.electronjs.org/zh/docs/latest/api/app 【1】npm init quick-start/electron…...
Vim学习(一)——基本命令与三种模式
写在前面, 致敬 8月3日,Vim创始人Bram Moolenaar去世,在此向老爷子致敬!感谢他为这个世界带来的优秀编辑器Vim。 基本介绍 Vim全称叫Vi IMproved. 而vi则是Visual Interface的缩写,他们处理都是ASCII码字符数据&am…...
unity新输入系统的简单使用(New InputSystem)
1、在包管理器 unity注册表中下载安装InputSystem 2、给玩家添加组件PlayerInput,点击CreatAction,创建一个InputAct InputAct,这是玩家的输入文件,在里面可以设置玩家输入 3、使用 例如玩家控制角色移动 在InputAct中,默认已经设置好了移…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
