关于“#define REG_MEM_BASE (*(volatile unsigend long *)(PA_BAES + 0x00000050))”语句的解析

对于嵌入式开发中经常遇到类似上述文件的定义,尤其在内存映射部分;为方便今后理解特举一个例子进行分析:

#define REG_MEM_BASE (*(volatile unsigend long *)(PA_BAES + 0x00000050))

(1)PA_BASE是一个宏定义

  #define PA_BASE  0x40000000   ----一般定义一个内存映射之后某一区域(如IO口映射)的首地址

(2)00000050h

这个是一个内存的偏移地址,实际为0x40000000+0x00000050=0x40000050

(3)volatile

这个是C中的一个关键字,经常在嵌入式开发中使用(尤其是在涉及存储器操作的时候),目的是告诉编译器不要对这个变量进行优化,这样实际代码中访问此变量时都会从外部存储器直接读取,防止变量值在读取操作过程中发生变化,而程序却无法察觉,导致异常错误

(4)(volatile unsigend long *)(PA_BAES + 0x00000050)

这表示一个地址,通过unsigned long进行强制转化;

(5) (*(volatile unsigend long *)(PA_BAES + 0x00000050))

这个表示指针变量,可以看做一个普通变量,这个变量有固定地址,指向PA_BAES + 0x00000050,并且可以进行读写操作

(6)为方便进行读写操作,使用#define预定义,将 (*(volatile unsigend long *)(PA_BAES + 0x00000050)) 重新命名为 REG_MEM_BASE。

注:

关于volatile关键字:

volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。这个关键字是用来设定某个对象的存储位置在内存中,而不是寄存器中。因为一般的对象编译器可能会将其的拷贝放在寄存器中用以加快指令的执行速度。

一般说来,volatile用在如下的几个地方:

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

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章