_IO 变量的作用

什么是_IO变量:
_IO为volatile变量,volatile 影响编译器编译的结果, 指出:volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错。
volatile(即__IO) 告诉编译器变量是随时可能发生变化的,每次使用它的时候必须从变量的地址中读取,因而编译器生成的可执行码会重新变量的地址读取数据。而如果没有使用__IO,编译器优化做法是,由于编译器发现两次从i中读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中,而不是重新从i里面读。

使用volatile(即__IO)的情况:

1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义。

加深理解:
例如:volatile表明的是该对象可能会有意想不到的改变,例如从一个寄存器读取温度值,它就会不断的改变,频繁的改变一个变量,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
}
这样的返回值就永远是一个定值的平方了,也就符合本意了。

在C语言中,特别是在嵌入式开发领域,`__IO` 是一种宏定义,用于标识变量的读写属性。它来源于ST库中的定义: ```c #define __IO volatile ``` 这意味着 `__IO` 是 `volatile` 关键字的一个别名,表示该变量可能会在程序不知情的情况下被改变,例如由硬件设备或者中断服务程序修改。使用 `__IO` 宏定义的变量告诉编译器不要对该变量的访问进行优化,以确保每次访问都能直接读取或写入内存中的实际值,而不是依赖于寄存器中的缓存值。这对于确保程序正确处理外部设备的状态变化至关重要,因为它保证了内存可见性,即程序能够立即看到其他线程或硬件对变量所做的更改 [^3]。 例如,在嵌入式系统中,一个 `__IO` 类型的变量可能代表一个与硬件寄存器相对应的地址。当这个变量被用来控制某个外设的状态时,如GPIO(通用输入输出)端口,它的值可能会被硬件自动更新。因此,通过将这样的变量声明为 `__IO`,可以确保编译器不会对该变量的访问进行不必要的优化,从而避免潜在的错误。 考虑以下示例代码,展示了如何使用 `__IO` 宏定义一个变量: ```c #include <stdio.h> #define __IO volatile int main() { __IO int status = 0; // 假设这是一个与硬件寄存器对应的变量 // 模拟硬件更改status变量的值 // 在实际应用中,这可能是由硬件中断触发的 status = 1; while (status == 1) { // 等待status变为0,这可能是因为外部硬件改变了它的值 } printf("Status changed to %d\n", status); return 0; } ``` 在这个例子中,`status` 变量被声明为 `__IO int` 类型,表明它的值可能会被外部因素(如硬件)改变。编译器会根据 `volatile` 的指示,每次循环检查 `status` 的实际内存值,而不是假设其值没有改变而进行优化。这样可以确保程序能够及时响应 `status` 的变化,这对于实现正确的硬件交互非常重要 。 综上所述,`__IO` 在C语言中主要用于嵌入式系统的开发,它通过确保内存可见性来提供对特殊地址的稳定访问,使得程序能够可靠地与外部设备通信 。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值