如果是内存映射,那就方便的多了。
举个例子,比如向寄存器A(地址假定为0x48000000)写入数据0x01,那么就可以这样设置了:
#define A (*(volatile unsigned *) 0x48000000 )... A =0x01;...
这实际上就是内存映射机制的方便性了。其中volatile关键字是嵌入式系统开发的一个重要特点。
volatile(可变的)这个关键字说明这变量可能会被意想不到地改变,这样编译器就不会去假设这个变量的值了。这种“意想不到地改变”,不是由程序去改变,而是由硬件去改变。
volatile 限定编译器不对这个指针的指向的存储单元进行优化,即不用通用寄存器暂时代替这个指针的指向的存储单元,而是每次取值都直接到指针的指向的存储单元取值.volatile主要用于变量会异步改变的情况下,主要有三个方面:
1.cpu外设寄存器
2.中断和主循环都会用到的全局变量
3.操作系统中的线程间都会用到的公共变量.
上述表达式拆开来分析:
首先(volatile unsigned *) 0x48000000的意思是把0x48000000强制转换成volatileunsigned类型的指针,即对指针的操作的范围是从0x48000000开始的4个字节(int型),暂记为p。那么就有:
#define A *p,即A为P指针指向位置的内容了。这里就是通过内存寻址访问到寄存器A,可以读/写操作!
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhangjian8613/archive/2010/02/01/5276607.aspx
映射 很自然想到 数学里面的 函数映射 有一一映射等 通过一个X 可以确定 一个或者多个Y
借用他人的一个比喻
“你家在一个小区里B栋2410室,你朋友来找你,找到小区门口,不知道你住哪层哪号?就问守门的保安,保安很客气的告诉了他你家详细门牌,所以你朋友很轻松的找到了你家。这个过程就是外网访问内网通过端口映射的形象比喻,”
端口映射 内存映射
来自网络的参考:
几乎每一种外设都是通过读写设备上的寄存器来进行的。外设寄存器也称为“I/O端口”,通常包括:控制寄存器、状态寄存器和数据寄存器三大类,而且一个外设的寄存器通常被连续地编址。CPU对外设IO端口物理地址的编址方式有两种:一种是I/O映射方式(I/O-mapped),另一种是内存映射方式(Memory-mapped)。而具体采用哪一种则取决于CPU的体系结构。
CPU的单一物理地址空间”就是指RAM,前文有描述"有些体系结构的CPU(如,PowerPC、m68k等)通常只实现一个物理地址空间(RAM)"。也就是说,这类结构(内存映射方式)的CPU只对RAM编址,其他对象如I/O,ROM等都要映射到RAM中才能被CPU访问。"而另外一些体系结构的CPU(典型地如X86)则为外设专门实现了一个单独地地址空间",这类(I/O映射方式)CPU就是我们现在用的PC中的CPU,这类CPU的寻址空间不是分为常规内存/保留内存/扩展内存吗?其中的保留内存就是用来对I/O,ROM等的直接编址。但由于参与直接编址的I/O,ROM等的读的速度没有RAM快,所以主板提供了映射功能,映射后参与保留内存编址的实际也是物理RAM,这种情形下就跟内存映射方式类似了
有些体系结构的CPU(如,PowerPC、m68k等)通常只实现一个物理地址空间(RAM)。在这种情况下,外设I/O端口的物理地址就被映射到CPU的单一物理地址空间中,而成为内存的一部分。此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要设立专门的外设I/O指令。这就是所谓的“内存映射方式”(Memory-mapped)。 而另外一些体系结构的CPU(典型地如X86)则为外设专门实现了一个单独地地址空间,称为“I/O地址空间”或者“I/O端口空间”。这是一个与CPU地RAM物理地址空间不同的地址空间,所有外设的I/O端口均在这一空间中进行编址。CPU通过设立专门的I/O指令(如X86的IN和OUT指令)来访问这一空间中的地址单元(也即I/O端口)。这就是所谓的“I/O映射方式”(I/O-mapped)。与RAM物理地址空间相比,I/O地址空间通常都比较小,如x86 CPU的I/O空间就只有64KB(0-0xffff)。这是“I/O映射方式”的一个主要缺点。===========================================