嵌入式STM32开发中关键字_IO

转载出处:https://blog.csdn.net/u010058695/article/details/101016142
作者:jianwang16


在开发嵌入式过程中,常会看到_IO 修饰符,这两个修饰符是在Core_cm3.h中被重定义:

/* IO definitions (access restrictions to peripheral registers) */
#ifdef __cplusplus
  #define   __I     volatile             /*!< defines 'read only' permissions                 */
#else
  #define   __I     volatile const       /*!< defines 'read only' permissions                 */
#endif
#define     __O     volatile             /*!< defines 'write only' permissions                */
#define     __IO    volatile             /*!< defines 'read / write' permissions              */  

在嵌入式处理器中,为加速访问变量,有时变量的值是直接存储在寄存器,而当某些中断或硬件改变了内存中的值时,程序却读取的是寄存器的值,因此该值不是最新的值,在开启程序优化后,在实时处理一些任务的时候可能会导致致命错误。

例如有一下代码,我们需要对变量i进行操作,一旦开启了优化,编译器可能直接将i=1 赋值语句给优化掉。

uint8_t i;
......
i = 1;
i = 0;
......

二、用法
volatile关键字用于声明变量不被编译器优化,总是从该变量在内存中的地址处去获取数据。volatile修饰的变量,访问该数据任何时候都会直接访问该地址处内容,即通过cache提高访问速度的优化被取消 。

通常用于取绝对地址的数据:例如,要取位于0x20000000处的数据,使用*((volatile unsigned int*) 0x20000000)即可,就是内存映射机制。

具体分析:(volatile unsigned int*) 0x20000000表示把0x20000000的地址指代的数据强制转换成volatile unsigned int类型,此时可以用指针来表示例如ptr:

unsigned int * ptr = (volatile unsigned int*) 0x20000000;

通过*ptr即可取得数据。

用宏定义声明操作该变量的值:

#define VAL ((volatile unsigned int) 0x20000000)

程序中就可以用VAL这个变量操作该地址的数据。

猜你喜欢

转载自blog.csdn.net/Eterlove/article/details/123490898