对外设进行
I/O
操作实际上也就是读写外设的寄存器,而我们通常使用的X86或者ARM处理器在硬件上决定了wince系统启动后,无法直接访问物理地址,因此需要做一些工作来实现I/O操作.
首先要理解
windows CE
下的地址映射机制。
wince有两种地址:物理地址和虚拟地址.不同架构的
CPU
硬件上的区别导致地址映射也不同。MIPS和SH
x
处理器,不采用MMU,直接在CPU和内核里定义
1G
的物理地址;而X86和ARM带有
MMU
单元,在
OEMAddressTable
中定义物理地址到虚拟地址间的映射关系或者是OS启动后调用
CreateStaticMapping
和
NKCreateStaticMapping
来实现从虚拟地址到物理地址的静态映射.经过静态映射的地址,可以由操作系统内核用于
ISR
访问设备。如果我们要在应用程序中访问外设,必须在物理地址和虚拟地址间建立动态映射关系,我们可以使用
VirtualAlloc
和
VirtualCopy
(或者直接调用
MmmapIoSpace
函数)来实现。
其次,如果是操作通过总线挂接的
I/O
或者存储器,必须先把总线地址转化成
CPU
上的系统地址,再做物理地址到虚拟地址的映射。这里需要查
CPU
的
Datasheet
,找出所要操作的I/O地址.先调用
HALTranslateBusAddress( )把总线地址转化成CPU上的系统地址,
再调用
MmmapIoSpace
函数实现虚实映射;也可以使用
TransBusAddrToVirtual
()直接把总线上的地址转化成系统的虚拟地址。
第三,在一般的应用程序中访问
I/O
是访问它的缓存段虚拟地址,而驱动中必须访问无缓存段虚拟地址。简单来说无缓存段虚拟地址
=
缓存段虚拟地址
+0x20000000
。
总结起来,如果是
wince
内核(如HAL)访问外部
I/O
,只需要在
OEMAddressTable
中定义物理地址到虚拟地址间的映射关系就可以了;如果是应用程序或者驱动要访问
I/O
,要做的工作包括:
1
。在
CPU
物理地址和虚拟地址间做一个动态映射,
2
。对虚拟地址进行操作。