嵌入式C语言中__I,__O,__IO详解

嵌入式C语言中__I,__O,__IO简介

__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 */

能改变变量值的两种方式

 

C编译器的优化机制

 

当连续改变一个变量值的时候,C编译器会将其优化为:

编译器会认为,这样过于频繁的“连续”的改变是无意义的,是“陷入死循环的前兆”,因此必须对其进行优化。

__I的功能

顾名思义,__I的含义就是将变量限制在“只读状态”,“只读状态”表示的是“变量的值只能通过读取寄存器的值改变自身,而且可以连续的改变,但是就是不可以人为的在程序中对变量进行改变”。

其实这就是“嵌入式输入的含义”,我们只允许通过读取外设寄存器的值来改变变量,不允许人为的在程序中改变变量的值。

 

__O的功能

顾名思义,__O的含义是将变量限制在“输出状态”,输出状态有别于输入状态的本质就在于,输出状态去掉了对于变量的const常量限定,使得我们可以通过任意方式(寄存器/人为修改)来改变变量的属性(值和数据类型)进而对变量进行处理。

 

__IO的功能

顾名思义,__IO指的是“该变量可以进行输入输出操作——读/写操作”。它的作用和__O相同。

对于嵌入式的深入理解

volatile符号的含义是什么?

Volatile关键字主要是声明那些“频繁被改变的变量”,频繁被改变的情况且每次改变都有意义,情况如下所示:

1、中断服务程序中修改的供其它程序检测的变量需要加volatile;

2、多任务环境下各任务间共享的标志应该加volatile;

3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义。

Const符号的含义是什么?

嵌入式中const关键字和普通C语言中的const关键字含义作用相同,都是用于限定变量不可以在程序中被改变。

为什么一个变量既可以是volatile类型也可以是const类型,这两个不冲突吗?

Const主要是限定“不可以在程序中人为的改变”,而volatile则是限定“变量可以被寄存器频繁的改变”,针对对象不同,含义也就不矛盾了。

例如:volatile表明的是该对象可能会有意想不到的改变,例如从一个寄存器读取温度值,它就会不断的改变,而const表示的是该对象不能被程序改动也就是不能在程序中再对它赋值,这两者是不矛盾的。

频繁的改变一个变量,C编译器会对其做何种优化?

这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:

int square(volatile int *ptr)    
{     
    int a,b;     
    a = *ptr;    
    b = *ptr;    
    return a * b;     
// 中间*ptr的值可能会被寄存器所改变进而导致a,b两个变量不同,得不到a^2这样的结果
}    

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的例如可能开始*ptr=1,过会*ptr=2了这就会导致a,b两个变量不相同。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

int square(int *ptr)    
{     
    int a,b;     
    a = *ptr;    
    b = *ptr;    
    return a * b;     
// 这样即使*ptr在函数体内发生相应改变编译器也会进行优化使得*ptr在函数内不会发生改变,最终a,b值相同,这也就是我们所期望的a^2
}   

 

这样的返回值就永远是一个定值的平方了,也就符合本意了。

猜你喜欢

转载自blog.csdn.net/weixin_45590473/article/details/109228449