完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
由于桌面Windows绝大多数情况下运行于X86平台上,也就不存在不同平台的可移植性问题。然而Windows CE运行在四大架构(X86,SHx,MIPS,ARM)的CPU上,编写应用程序时就需要考虑它的移植。
|
|
相关推荐
1个回答
|
|
以下通过在wince系统下访问物理地址,来看看如何编写可移植性较好的应用程序。
首先必须明确两个概念 1. 在X86平台下才有I/O地址这一说,在其他体系的CPU(如ARM/MIPS)下是没有I/O端口的。因为X86下把I/O和存储器分开编址,导致其有两种地址;而别的CPU是把两者统一编址,即把I/O映射到存储器上。 2. WinCE的存储管理是通过MMU实现的,在系统启动后,我们只能访问虚拟存储空间,必须经过MMU。但是在X86下,访问I/O口和存储器走的地址总线不同,不用经过MMU。 比如我们想要访问挂在某总线上物理地址为360h的端口,对于X86平台我们可以直接嵌入汇编操作物理地址, 或者使用地址指针访问物理地址。但对于其他平台,我们必须先作一个物理地址到虚拟地址的映射,然后操作其虚拟地址。这样显然程序的可移植性不好,我们需要定义 #ifdef __x86....#elif defined __arm 使得在不同平台下程序能够顺利运行。 如果使用下面的代码我们就可以不用这么费劲的定义不同平台了: 先定义 inIoSpace = 1; ioPhysicalBase.QuadPart = 0x360; if( HalTranslateBusAddress( Isa, //此函数把ISA总线上物理地址映射为系统物理地址 0, ioPhysicalBase, &inIoSpace, //此参数=1说明转化的是I/O空间地址,=0时存储器地址 &ioPhysicalBase ) ) { if( !inIoSpace ) ////如果是存储器地址,针对非X86 平台 { ioPortBase = ( PUCHAR ) MmMapIoSpace( //此函数把系统物理地址转化为虚拟地址 ioPhysicalBase, IoLen, FALSE ); if( ioPortBase == NULL ) { //TODO: Error handling } } else //如果是I/O,即X86 下,不需要做地址映射 { ioPortBase = ( PUCHAR ) ioPhysicalBase.LowPart; } } else { //TODO: Error Handling } 随后对于端口的操作( ioPortBase),我们也可以充分挖掘它的可移植性。通过使用READ_PORT_UCHAR, WRITE_PORT_UCHAR这些wince下的宏来实现端口读写。而不是在X86下用指针操作(不仅移植性差,而且容易产生问题)。CE下的宏在内部是封装好的API函数。例如WRITE_PORT_UCHAR这个宏在X86 处理器上转化为一条OUT的汇编指令;而在ARM处理器上会转化成一条对虚拟地址的写指令。 WinCE5.0下可以使用CreateBusAccessHandle(总线注册表路径)+BusTransBusAddrToVirtual来实现总线物理地址到系统虚拟地址的直接变换。这种方式比起使用OEMAddressTable+VirtualAlloc+VirtualCopy方式更具不同平台的可移植性。 |
|
|
|
只有小组成员才能发言,加入小组>>
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-20 08:36 , Processed in 1.276764 second(s), Total 78, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号