一个、说明

(*(volatile unsigned long *))

这个语句对于不同的计算机体系结构,设备可能是port映射,也可能是内存映射的。

假设系统结构支持独立的IO地址空间。而且是port映射,就必须使用汇编语言完毕实际对设备的控制。由于C语言并没有提供真正的“port”的概念。假设是内存映射。那就方便多了。


二、举例解说
以 #define IOPIN (*((volatile unsigned long *)0xE0028000))为例:
作为一个宏定义语句,define是定义一个变量或常量的伪指令。首先 (volatile unsigned long *) 的意思是将后面那个地址强制转换成 volatile unsigned long * , unsigned long *是无符号长整型,volatile是一个类型限定符,如const一样。当使用volatile限定时,表示这个变量是依赖系统实现的。意味着这个变量会被其它程序或者计算机硬件改动。因为地址依赖于硬件,volatile就表示他的值会依赖于硬件。
volatile 类型是这种,其数据确实可能在未知的情况下发生变化。比方,硬件设备的终端更改了它,如今硬件设备往往也有自己的私有内存地址,比方显存,他们通常是通过映象的方式,反映到一段特定的内存地址其中。这样,在某些条件下,程序就能够直接訪问这些私有内存了。另外,比方共享的内存地址。多个程序都对它操作的时候。你的程序并不知道。这个内存何时被改变了。

假设不加这个voliatile修饰,程序是利用cache其中的数据,那个可能是过时的了,加了
voliatile,就在须要用的时候,程序又一次去那个地址去提取,保证是最新的。归纳起来例如以下:

1. volatile变量可变同意除了程序之外的比方硬件来改动他的内容

2. 訪问该数据不论什么时候都会直接訪问该地址处内容,即通过cache提高訪问速度的优化被取消

对于((volatile unsigned long *) 0xE0028000)为随硬件须要定义的一种地址,前面加上“*”指针。为直接指向该地址,整个定义约定符号IOPIN取代,调用的时候直接对指向的地址寄存器写内容既可。

这实际上就是内存映射机制的方便性了。当中volatilekeyword是嵌入式系统开发的一个重要特点。

上述表达式拆开来分析,首先(volatile unsigned long *) 0xE0028000的意思是把0xE0028000强制转换成volatile
unsigned long类型的指针。暂记为p,那么就是#define A *p。即A为P指针指向位置的内容了。这里就是通过内存寻址訪问到寄存器A,能够读/写操作。


对于(volatile unsigned char *)0x20能够再分析一下,它是由两部分组成:
1)(unsigned char *)0x20,0x20仅仅是个值。前面加(unsigned char *)表示0x20是个地址。并且这个地址类型是unsigned char ,意思是说读写这个地址时。要写进unsigned char 的值,读出也是unsigned char 。

2)volatile。keywordvolatile 确保本条指令不会因C 编译器的优化而被省略,且要求每次直接读值。比如用while((unsigned char *)0x20)时,有时系统可能不真正去读0x20的值。而是用第一次读出的值。假设这样。那这个循环可能是个死循环。用了volatile 则要求每次都去读0x20的实际值。

那么(volatile unsigned char *)0x20是一个固定的指针。是不可变的,不是变量。而char *u则是个指针变量。
再在前面加"*":*(volatile unsigned char *)0x20则变成了变量(普通的unsigned char变量,不是指针变量),假设#define i (*(volatile unsigned char *)0x20),那么与unsigned char i是一样了,仅仅只是前面的i的地址是固定的。

那么问题就可解答了。(*(volatile unsigned char *)0x20)可看作是一个普通变量。这个变量有固定的地址,指向0x20。而0x20仅仅是个常量,不是指针更不是变量。

參考文章:http://blog.sina.com.cn/s/blog_65861d3f0100xsz0.html

版权声明:本文博客原创文章,博客,未经同意,不得转载。

嵌入式开发(*(volatile unsigned long *)) 认识的更多相关文章

  1. 嵌入式中的 *(volatile unsigned int *)0x500 解释

    C语言中*(volatile unsigned int *)0x500的解释: 如下: (unsigned int *)0x500:将地址0x500强制转化为int型指针*(unsigned int ...

  2. 【嵌入式】——对#define GPBCON (*(volatile unsigned long*)0x56000010)的理解

    #define GPBCON (*(volatile unsigned long*)0x56000010) 1:volatile 当计算机需要一个数值的时候,会先把内存中的值读取到寄存器,然后下次在使 ...

  3. 嵌入式开发中常见3个的C语言技巧

    Hey,大家好!我是CrazyCatJack.今天我来说几个在嵌入式开发中常用的C语言技巧吧.也许你曾经用过,也许你只是见到过但是没有深入理解.那么今天好好补充下吧^_^ 1.指向函数的指针 指针不光 ...

  4. C语言面试题(嵌入式开发方向,附答案及点评)

    整理自C语言面试题(嵌入式开发方向,附答案及点评) 预处理器(Preprocessor) 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SEC ...

  5. (*(volatile unsigned long *)详解

    (*(volatile unsigned long *) 对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的.如果系统结构支持独立的IO地址空间,并且是端口映射,就必须使用汇编语言完成实 ...

  6. 嵌入式开发—C语言面试题

    嵌入式开发—C语言面试题 源地址:http://blog.csdn.net/xdx2ct1314/article/details/7358929   1. 用预处理指令#define 声明一个常数,用 ...

  7. iTOP-4412嵌入式开发板ioremap控制GPIO寄存器

    转自迅为电子技术论坛:http://bbs.topeetboard.com GPIO 的寄存器通过 ioremap函数转换之后,可以通过直接控制虚拟地址来控制物理地址(寄存器的实际地址),这样就实现 ...

  8. (C)理解#define write(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))

      理解 #define write(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) 嵌入式系统编程,要求程序员能够利用C语言访问固 ...

  9. (嵌入式开发)自己写bootloader之编写第二阶段

    内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M.     ...

随机推荐

  1. 使用UIDataDetectorTypes自己主动检測电话、网址和邮箱

    支付宝公布最新版本号9.0.再一次引发一场撕逼大战.微信说支付宝抄袭了它.支付宝说微信一直都在抄袭自己.在我看来.微信和支付宝都抄袭了对方.对于大佬们的抄袭.我们也是司空见惯了. 支付宝这一次更新,真 ...

  2. 使用C#版本的gdal库打开hdf文件

    作者:朱金灿 来源:http://blog.csdn.net/clever101 最近应同事的请求帮忙研究下使用C#版的gdal库读取hdf文件,今天算是有一点成果,特地做一些记录. 首先是编译C#版 ...

  3. Fragment之一:Fragment入门 分类: H1_ANDROID 2013-11-15 18:16 2799人阅读 评论(2) 收藏

    参考自张泽华视频 Fragment是自Android3.0后引入的特性,主要用于在不同的屏幕尺寸中展现不同的内容. Fragment必须被嵌入Activity中使用,总是作为Activity的组成部分 ...

  4. Java NIO详细介绍

    不错的文章,推荐一下. http://www.ibm.com/developerworks/cn/education/java/j-nio/j-nio.html JavaNIO非堵塞技术实际是采取Re ...

  5. css 翻牌 翻转 3d翻转 特效

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. mysql mha高可用架构的安装

    MMM无法全然地保证数据的一致性,所以MMM适用于对数据的一致性要求不是非常高.可是又想最大程度的保证业务可用性的场景对于那些对数据一致性要求非常高的业务,非常不建议採用MMM的这样的高可用性架构.那 ...

  7. RSA算法原理(转)

    如果你问我,哪一种算法最重要?我可能会回答“公钥加密算法”.因为它是计算机通信安全的基石,保证了加密数据不会被破解.你可以想象一下,信用卡交易被破解的后果. 进入正题之前,我先简单介绍一下,什么是”公 ...

  8. 海思hi3716c机顶盒接usb摄像头和usb无线耳机时,无线耳机有时没有声音

    两个USB设备各自是: A:USB摄像头带录音功能,但不带放音功能. B:USB无线耳机是使用USB转2.4G的无线耳机. 详细现象: 1, A,B两者同一时候插上机顶盒,并开机进入android,此 ...

  9. [React Router v4] Use URL Parameters

    URLs can be looked at as the gateway to our data, and carry a lot of information that we want to use ...

  10. 机器学习 Softmax classifier (无隐含层)

    程序实现 Softmax classifer, 没有隐含层, f=wx+b y=efi∑jefj %% Softmax classifier function Out=Softmax_Classifi ...