WINCE下I/O操作基础

 
对外设进行 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 */ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436405.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SM4对称加密算法及Java实现

文章来源&#xff1a;https://www.jianshu.com/p/5ec8464b0a1b 一、简介 与DES和AES算法类似&#xff0c;SM4算法是一种分组密码算法。 其分组长度为128bit&#xff0c;密钥长度也为128bit。 加密算法与密钥扩展算法均采用32轮非线性迭代结构&#xff0c;以字&#xff08;32位…

【转】DICOM网络协议(一)概述

转自&#xff1a;https://www.jianshu.com/p/8a0f0fe6a738 作者&#xff1a;我住的城市没有福合埕 DICOM (Digital Imaging and Communications in Medicine)即医学数字成像和通信&#xff0c;DICOM网络是基于TCP/IP的网络协议。通过DICOM将影像设备和存储管理设备连接起来。…

Windows进程系列(2) -- Svchost进程

在基于NT内核的Windows操作系统家族中&#xff0c;Svchost.exe是一个非常重要的进程。很多病毒、木马驻留系统与这个进程密切相关&#xff0c;因此深入了解该进程是非常有必要的。本文主要介绍Svchost进程的功能&#xff0c;以及与该进程相关的知识。      Svchost进程概述…

mysql数据库字符集设置_查看和设置MySQL数据库字符集

查看和设置MySQL数据库字符集作者&#xff1a;scorpio 2008-01-21 10:05:17 标签&#xff1a; 杂谈 Liunx下修改MySQL字符集&#xff1a;1.查找MySQL的cnf文件的位置find / -iname *.cnf -print /usr/share/mysql/my-innodb-heavy-4G.cnf/usr/share/mysql/my-large.cnf/usr/sha…

MQTT和HTTP的区别

来源&#xff1a;http://blog.sina.com.cn/s/blog_68f485d10102yowx.html HTTP是最流行和最广泛使用的协议。但在过去几年中&#xff0c;MQTT迅速获得了牵引力。当我们谈论物联网开发时&#xff0c;开发人员必须在它们之间做出选择。 设计和消息传递 MQTT以数据为中心&#x…

【转】DICOM入门(一)——语法

转自&#xff1a;https://www.jianshu.com/p/5db8933a25a4 作者&#xff1a;我住的城市没有福合埕 1.什么是DICOM DICOM(Digital Imaging and Communications in Medicine)即医学数字成像和传输协议&#xff0c;是用医疗影像&#xff08;CT 核磁共振 DR CR 超声等&#xff0…

1000并发 MySQL数据库_再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化...

继上篇文章《绝对干货&#xff0c;教你4分钟插入1000万条数据到mysql数据库表&#xff0c;快快进来》发布后在博客园首页展示得到了挺多的阅读量&#xff0c;我这篇文章就是对上篇文章的千万级数据库表在高并发访问下如何进行测试访问这篇文章的知识点如下:1.如何自写几十行代码…

从高中一次半夜不冲厕所的经历谈程序

我高中的时候&#xff0c;是住校生。寝室到了10点半就会熄灯&#xff0c;早上6点40左右就要起来跑早操。 一天半夜大概两三点&#xff0c;起床放了个大号。想要充厕所的时候发现没有水&#xff0c;很尴尬&#xff0c;也没有其他的办法。半夜还冷的很。就上床睡觉了&#xff0…

Oracle:ORA-28000异常(帐户已被锁定),修改账号登录失败次数

问题描述 最近系统更换了数据库服务器&#xff0c;IP地址也变了&#xff0c;于是就把应用服务器中配置数据库连接的位置做了修改&#xff0c;但是修改后应用起不来了。 经过半天也没发现问题&#xff0c;后来想试试连数据库看看&#xff0c;结果PL/SQL提示“ORA-28000错误”&…

【转】VTK修炼之道1_初识VTK

1.VTK是什么&#xff1f; Visualization ToolKit 3D计算机图形学、图象处理及可视化工具包 VTK使用C、面向对象技术开发&#xff1b;基于OpenGL&#xff0c;封装了OpenGL中的功能&#xff0c;屏蔽细节、便于交互、易于使用提供多种语言接口C&#xff0b;&#xff0b; 、Java 、…

一道解决的非常漂亮的算法题

这是多年以前做的一道题目&#xff0c;原题来自软件报或者电脑报 &#xff0c;我记不清了。解决这个题目有一个关键的步骤&#xff0c;就是要求一个整数在一个整数三角阵中的坐标。这篇blog就是讨论这个求坐标的问题&#xff0c;不是讨论那个报纸上的题目。现在将题目描述如下&…

HTTPS原理和对中间件攻击的预防

一、https/tls原理 HTTPS访问的三个阶段 第一阶段 认证站点 客户端向站点发起HTTPS请求&#xff0c;站点返回数字证书。客户端通过数字证书验证所访问的站点是真实的目标站点。 第二阶段 协商密钥 客户端与站点服务器协商此次会话的对称加密密钥&#xff0c;用于下一阶段的加…

【转】医学影像技术(中国普通高等学校本科专业)

医学影像技术专业培养适应我国社会主义现代化建设和医疗卫生事业发展需要的&#xff0c;德、智、体全面发展&#xff0c;具有基础医学、临床医学和现代医学影像必备的基本理论知识和基本技能&#xff0c;从事临床影像检查、诊断与治疗技术工作的高级技术应用性专门人才。 中文…

Windows CE下流驱动的动态加载

Windows CE下流驱动的动态加载 闲话少说&#xff0c;进入正题。查找EVC的帮助&#xff0c;发现函数ActivateDevice&#xff08;&#xff09;可用来加载驱动程序。而这个函数的使用是相当简单的。我就不多说了&#xff0c;贴上一段帮助最能说明问题。当然&#xff0c;你也可以用…

HTTPS原理全面介绍【备查】

来源&#xff1a;https://www.cnblogs.com/haimishasha/p/11373034.html 目录 应用层协议&#xff1a;HTTPS 1. HTTPS定义 2. 密码学基础  3. HTTP通信问题 4. SSL/TLS协议 5. HTTP 向 HTTPS 演化的过程 5.1 对称加密 5.2 非对称加密 5.3 对称加密非对称加密 5.4 安…

【转】VTK修炼之道2_VTK体系结构1

1.OverView综述 The Visualization Toolkit consists of two basic subsystems: a compiled C class library &#xff08;一个已经编译好的C类库&#xff09;and an “interpreted” wrapper layer&#xff08;一个用于解释的语言层&#xff09; that lets you manipulate the…

WINCE6.0 DM.EXE 激活驱动失败的原因之一

前些天把WINCE6.0的开发环境建好了&#xff0c;今天定制了一个系统&#xff0c;练习了一下驱动的编写和调试。把DLL文件通过VS2005部署到开发板上&#xff0c;用一位大侠写的DM.EXE工具进行激活&#xff0c;但是发现点击激活按钮式无反应&#xff0c;驱动还是停在“停用”状态&…

Linux:tomcat安装/版本升级

本文适用于安装或更新tomcat版本。 1.进入tomcat目录&#xff0c;查看当前tomcat版本 cd /usr/local/tomcat/bin ./version.sh 2.备份原tomcat 可以拷贝原tomcat&#xff0c;或者直接修改原tomcat的文件夹名称作为备份。 cd /usr/local/ #方法1&#xff1a;创建目录&…

【转】VTK与Qt整合的示例

VTK与Qt整合的示例 VTK附带的程序示例中大多是基于控制台的&#xff0c;作为可视化开发工具包&#xff0c;VTK也可以与很多流行的GUI开发工具整合&#xff0c;比如MFC、Qt(题外话&#xff1a;Qt已经被Digia从诺基亚手中收购了&#xff0c;Qt现在的链接是&#xff1a;http://qt…

WinCE驱动调试助手V2.5

http://www.cnblogs.com/we-hjb/archive/2008/12/15/1280822.html http://blog.chinaunix.net/u1/49088/showart.php?id1279989 工欲善其事&#xff0c;必先利其器。做WinCE驱动的开发已有一段时间了&#xff0c;WinCE驱动调试助手也跟着更新了很多功能。现在只要做驱动&#…