您的位置 首页 软件

STM32 _I _0 _IO volatile const

__I、__O、__IO是什么意思?这是ST库里面的宏定义,定义如下:#define__Ivolatileconst/*!defines#39;readonly…

__I、 __O 、__IO是什么意思?
这是ST库里边的宏界说,界说如下:
#define __I volatile const /*!< defines read only permissions */
#define __O volatile /*!< defines write only permissions */
#define __IO volatile /*!< defines read / write permissions */
明显,这三个宏界说都是用来替换成 volatile 和 const 的,所以咱们先要了解 这两个关键字的效果:

volatile
简略的说,便是不让编译器进行优化,即每次读取或许修正值的时分,都必须从头从内存或许寄存器中读取或许修正。

一般说来,volatile用在如下的几个当地:
1、中止服务程序中修正的供其它程序检测的变量需求加volatile;
2、多使命环境下各使命间同享的标志应该加volatile;
3、存储器映射的硬件寄存器一般也要加volatile阐明,由于每次对它的读写都或许由不同含义;

我以为这是区别C程序员和嵌入式体系程序员的最基本的问题。搞嵌入式的家伙们常常同硬件、中止、RTOS等等打交道,所有这些都要求用到 volatile变量。不懂得volatile的内容将会带来灾祸。假定被面试者正确地答复了这是问题(嗯,置疑是否会是这样),我将略微深究一下,看一下这家伙是不是直正懂得volatile彻底的重要性。
1)一个参数既可所以const还可所以volatile吗?解说为什么。
2); 一个指针可所以volatile 吗?解说为什么。
3); 下面的函数有什么过错:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}

1)是的。一个比如是只读的状况寄存器。它是volatile由于它或许被意想不到地改动。它是const由于程序不应该企图去修正它。
2); 是的。虽然这并不很常见。一个比如是当一个中服务子程序修该一个指向一个buffer的指针时。
3) 这段代码有点反常。这段代码的意图是用来返指针*ptr指向值的平方,可是,由于*ptr指向一个volatile型参数,编译器将发生相似下面的代码:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值或许被意想不到地该变,因而a和b或许是不同的。成果,这段代码或许返不是你所希望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}

const
只读变量,即变量保存在只读静态存储区。编译时,怎么测验修正只读变量,则编译器提示犯错,就能防止误修正。
const与define
两者都能够用来界说常量,可是const界说时,界说了常量的类型,所以更准确一些(其实const界说的是只读变量,而不是常量)。#define仅仅简略的文本替换,除了能够界说常量外,还能够用来界说一些简略的函数,有点相似内置函数。const和define界说的常量能够放在头文件里边。(小注:能够屡次声明,但只能界说一次)

const与指针
int me;
const int * p1=&me; //p1可变,*p1不可变 const 润饰的是 *p1,即*p1不可变
int * const p2=&me; //p2不可变,*p2可变 const 润饰的是 p2,即p2不可变
const int *const p3=&me; //p3不可变,*p3也不可变 前一个const 润饰的是 *p3,后一个const 润饰的是p3,两者都不可变

前面介绍了 volatile 和 const 的用法,不知道咱们了解了没?了解了后,下面的解说就愈加简单了:
__I :输进口。既然是输入,那么寄存器的值就随时会外部修正,那就不能进行优化,每次都要从头从寄存器中读取。也不能写,即只读,否则就不是输入而是输出了。
__O :输出口,也不能进行优化,否则你接连两次输出相同值,编译器以为没改动,就疏忽了后边那一次输出,假设外部在两次输出中心修正了值,那就影响输出
__IO:输入输出口,同上

为什么加下划线?

原因是:防止命名抵触
一般宏界说都是大写,但由于这儿的字母比较少,所以再增加下划线来区别。这样一般都能够防止命名抵触问题,由于很少人这样命名,这样命名的人必定知道这些是有什么用的。
常常写大工程时,都会发现老是命名抵触,要不是全局变量抵触,要不便是宏界说抵触,所以咱们要尽量防止这些问题,否则出问题了都不知道问题在哪里。

volatile一般用在以下三个方面:

1、中止标志位

2、多线程同享的变量

3、状况寄存器
来自ouravr野火M3

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/ruanjian/252272.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部