嵌入式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
}
这样的返回值就永远是一个定值的平方了,也就符合本意了。