对外设进行 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 。对虚拟地址进行操作。

在X86和ARM架构的CPU中,wince访问系统内存的方法随程序所属模式层次的不同而有所区别. 
  1.在系统内核模式下(kernel mode),在OAL层访问,只需要在OEMAddressTable 中做静态的虚实地址映射就可以了.例如X86架构的映射表格式如下: 
   ; OEMAddressTable defines the mapping between Physical and Virtual Address  // 定义4GB的虚拟地址和512MB存储的映射关系 
   ;   o MUST be in a READONLY Section 
   ;   o First Entry MUST be RAM, mapping from 0x80000000 -> 0x00000000 
   ;   o each entry is of the format ( VA, PA, cbSize ) 
   ;   o cbSize must be multiple of 4M 
   ;   o last entry must be (0, 0, 0) 
   ;   o must have at least one non-zero entry 
   ; RAM 0x80000000 -> 0x00000000, size 64M       //把物理地址为0x00000000映射到虚拟地址为 0x80000000 处 
   dd  80000000h,    0,   04000000h 
   ; FLASH and other memory, if any 
   ; dd  FlashVA,      FlashPA,    FlashSize 
   ; Last entry, all zeros 
   dd  0   0   0 
2.在驱动或应用程序(user mode)中访问RAM,既可以通过OEMAddressTable+VirtualCopy方式,也可以直接用MmMapIoSpace函数建立物理地址到当前进程虚拟地址的映射关系. 
经过OEMAddressTable,实现的只是CPU物理地址到OS内核层虚拟地址的一次映射,如果需要在普通的应用程序中访问内存,还要再用VirtuaAlloc+VirtualCopy做一个内核到当前进程的二次映射(有一种情况例外,就是你的OS被配置成Full Kernel Mode,这时任何应用程序都可以访问OS内核地址). 
     简单说明几个关键函数: 
     VirtualAlloc用于在当前进程的虚拟地址空间中保留或者提交空间,在保留时以64KB为单位,提交时以4KB为单位。其函数原型为

LPVOID VirtualAlloc(

LPVOID lpAddress,  // 分配虚拟地址的起始指针

DWORD dwSize,     // 大小,以字节为单位

DWORD flAllocationType, // 类型,设为MEM_RESERVE

DWORD flProtect    //  存取保护,设为PAGE_NOACCESS

);

c:

BOOL VirtualCopy(

LPVOID lpvDest,         // 虚拟目的地址指针,接受VirtualAlloc的返回值

LPVOID lpvSrc,         // 源物理地址指针

DWORD cbSize,          // 大小必须与虚拟地址相同

DWORD fdwProtect  // 存取保护类型

);

这里需要注意的是 fdwProtect 参数。如果是驱动程序访问,需要设置为 PAGE_NOCACHE ,以访问无缓存段虚拟地址。如果映射的物理地址范围在 0x1FFFFFFF 之上,必须使用 PAGE_PHYSICAL ,此时必须把 lpvSrc 右移八位,实现地址对齐。(这是由内核中 VirtualCopy 的实现决定的,在那个函数中会判断如果是 PAGE_PHYSICAL 就将 PHYSADDR 左移 8 位移回来,源代码位于 private/winceos/coreos/nk/kernel 目录下的 virtmem.c中的DoVirtualCopy )

MmMapIoSpace 用来把物理地址直接映射到与进程无关的虚拟地址上。函数原型为

PVOID MmMapIoSpace(

PHYSICAL_ADDRESS PhysicalAddress,

ULONG NumberOfBytes,

BOOLEAN CacheEnable

);

一个使用 VirtualAlloc+Copy 的例子:把物理地址为 0x10000000 的单元映射到虚拟地址空间中。

#include <windows.h>

#define PHYSADDR  ((PVOID)0x10000000)

// PHYSADDR is the physical address of the peripheral

// registers

#define SIZE  (4800*4)

LPVOID lpv;

BOOL bRet;

lpv = VirtualAlloc(0, SIZE, MEM_RESERVE, PAGE_NOACCESS);

// For a user mode driver, always leave the first

// parameter 0 and use only the flags MEM_RESERVE

// and PAGE_NOACCESS Check the return value: lpv == 0

// is an error

printf(TEXT("VirtualAlloc reservation @%8.8lx/r/n"), lpv);

bRet = VirtualCopy(lpv, PHYSADDR>>8, SIZE, PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL);

// The lpv parameter is the virtual address returned

// by VirtualAlloc().

// Always use PAGE_NOCACHE */

// Check the return value: bRet ==0 is an error */

printf(TEXT("VirtualCopy returned: %d/r/n"), bRet);

// At this point lpv is a virtual address which maps

// the I/O registers

// at PHYSADDR for SIZE bytes */

WINCE下I/O操作基础相关推荐

  1. Linux下Mysql数据库的基础操作

    Linux下Mysql数据库的基础操作 一.Mysql数据介绍 二.数据库相关术语介绍 1.数据库相关名词 2.相关术语介绍 三.Mysql数据库的管理 1.创建数据库用户 2.查询用户状态 3.修改 ...

  2. 在数据仓储的情况下进一步封装数据库基础操作,此版本为异步版本

    1 /// <summary> 2 /// 在数据仓储的情况下进一步封装数据库基础操作,此版本为异步版本 Created by ZhangQC 2016.08.17 3 /// </ ...

  3. 【WinCE】SD card技术了解并WINCE下SDHC驱动开发(updated)

    SD Card Driver on ADS Summary 了解SD card. 1 WinCE 5.0下SD Stack. 6 Bus Driver 7 Host Controller Driver ...

  4. 在Window Embedded CE(Wince)下使用OpenNETCF进行路由表的开发

    点击打开链接 背景 在开发3G项目的是时候,发现尽管3G网络连接已经建立成功了,但是数据不能发送成功,查明原因,由于路由表的问题,导致数据往ActiveSync连接的对端,也就是PC发送,而不是发送到 ...

  5. 记WinCE下调试SIM900 GSM module

    记WinCE下调试SIM900 GSM module 近几天在调试sim900,把遇到的一些问题总结下吧. 一.一些引脚的说说明. Sim900有几个引脚需要了解下. 1.  CTS.RTS 由于使用 ...

  6. datagrid出现相同两组数据_stata 数据操作基础知识:以一篇论文数据操作为例

    stata 数据操作基础知识:以一篇论文数据操作为例 上节回顾及问题 统计学学习大图景 数据描述 分位数回归 存在的问题: 1.学了就要多使用,哪怕生搬硬套也要多用 2.时间序列的方法,大家可以操作, ...

  7. 计算机操作业务知识题库,《计算机操作基础知识题库》.doc

    计算机网络考试 第 PAGE 1 页 共 NUMPAGES 10 页 计算机操作基础知识题库 一.单选题(共59题) 1.在 Excel 工作窗口上,"状态栏"是在屏幕的( ). ...

  8. ubuntu 电源按钮操作_Ubuntu电脑操作基础:桌面背景,屏保和电源

    一个干净整洁的桌面,有利于我们操作电脑,如何设置一个漂亮的背景,我们来看一个练习; 1.桌面背景 1)在桌面空白处点右键,在出来的菜单里选"更改桌面背景"命令,出来一个对话框面板; ...

  9. WinCE下的GPIO中断的处理

    在我所负责的音频驱动部分代码中,采用了PXA270的GPIO34来检测Headphone的插入与拔出.原驱动部分有个BUG,即当耳机插入以后,耳机和喇叭同时在响,很明显没有对耳机插入事件做出响应.所以 ...

最新文章

  1. 文本类控件(EditView 的介绍)
  2. 电脑动态屏保_8款电脑软件,每一款都能让你的电脑更好用
  3. linux 如何查看属性,linux 下查看系统属性
  4. 洛谷——P1657 选书
  5. datatable自定义搜索和导出按钮并解决在后端分页无法导出全部数据的问题
  6. rocketmq同步消息,异步消息
  7. android添加本地资源文件,本地html文件放置位置,android中加载本地Html文件
  8. Nginx灰度升级实现说明
  9. 唐太宗灵州受降【会盟】的意义
  10. 无线网DNS服务器有错误,关于dns错误的原因和解决办法
  11. 业界最全,阿里云混合云灾备服务上线!
  12. 【什么办公软件好用】万彩办公大师教程丨PDF转图片工具
  13. 基于华为WAC双机VRRP热备份下旁挂三层组网隧道转发模式解决方案
  14. Lifecycle的基本使用和原理
  15. javaweb项目通过natapp实现项目让外网访问
  16. 纳米器件,量子点理论文献拾遗
  17. 工具及方法 - 项目管理工具ProjectLibre
  18. C语言 while循环和do...while循环
  19. lotus收到的外部邮件是html语言,46. Lotus Notes中编程发送邮件(一)
  20. junction工具安装及简单使用

热门文章

  1. ei加声调怎么加_ei在e还是i上标声调
  2. 数据结构实验五 查找算法的实现
  3. docker绑定端口主机访问curl: (56) Recv failure: Connection reset by peer
  4. mysql error 1201_ERROR 1201 (HY000): Could not initialize master info structure; .....
  5. hive工作中分享总结
  6. 上传文件插件(plupload)
  7. 语言统计学中的几个定律,可作为设计检索的参考
  8. WebSite和Web Application\网站与Web项目的区别
  9. 关闭弹出窗体,刷新父页面
  10. 企业效益真的向好么?