一个、说明

(*(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. 【42.86%】【Codeforces Round #380D】Sea Battle

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  2. 为何在查询中索引未被使用 (Doc ID 1549181.1)

        To Bottom * 为何在查询中索引未被使用 (Doc ID 1549181.1) To Bottom 文档内容 用途   排错步骤   高速检查   表上是否存在索引?   索引是否应该 ...

  3. 【29.70%】【codeforces 723D】Lakes in Berland

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. 【u106】3D模型

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 一座城市建立在规则的n×m网格上,并且网格均由1×1正方形构成.在每个网格上都可以有一个建筑,建筑由若 ...

  5. [D3] Convert Input Data to Output Values with Linear Scales in D3

    Mapping abstract values to visual representations is what data visualization is all about, and that’ ...

  6. JavaScript实现form表单的多文件上传

    form表单的多文件上传,具体内容如下 formData对象可以使用一系列的键值对来模拟一个完整的表单,然后使用Ajax来发送这个表单 使用<form>表单初始化FormData对象的方式 ...

  7. [TypeScript] Create random integers in a given range

    Learn how to create random integers using JavaScript / TypeScript. /** * Returns a random int betwee ...

  8. [NPM] Use a shorthand syntax for running multiple npm scripts with npm-run-all

    Running multiple scripts in series or in parallel can become very verbose. Using a tool such as npm- ...

  9. Android 用SSL构建安全的Socket

    SSL(安全套接层)是 Netscape公司在1994年开发的,最初用于WEB浏览器,为浏览器与服务器间的数据传递提供安全保障,提供了加密.来源认证和数据完整性的功能.现在SSL3.0得到了普遍的使用 ...

  10. ScrollView嵌套ListView问题

    ScrollView嵌套ListView问题 导致Listview  第一主角 它是 Listview 的item 显示器的数量是不完全. 这是因为item 中间 Textview 话是太多的问题 一 ...