Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1930961
  • 博文数量: 699
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 4970
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-15 13:45
文章分类

全部博文(699)

文章存档

2011年(1)

2008年(698)

我的朋友

分类:

2008-10-15 13:50:39

        由于桌面绝大多数情况下运行于X86平台上,也就不存在不同平台的可移植性问题。然而 CE运行在四大架构(X86,SHx,MIPS,)的CPU上,编写应用程序时就需要考虑它的移植。
      

        以下通过在wince系统下访问物理地址,来看看如何编写可移植性较好的应用程序。
      

        首先必须明确两个概念。
      

        1. 在X86平台下才有I/O地址这一说,在其他体系的CPU(如/MIPS)下是没有I/O端口的。因为X86下把I/O和器分开编址,导致其有两种地址;而别的CPU是把两者统一编址,即把I/O映射到器上。
       

        2. WinCE的存储管理是通过MMU实现的,在系统启动后,我们只能访问虚拟存储空间,必须经过MMU。但是在X86下,访问I/O口和存储器走的地址总线不同,不用经过MMU。

        比如我们想要访问挂在某总线上物理地址为360h的端口,对于X86平台我们可以直接嵌入汇编操作物理地址, 或者使用地址指针访问物理地址。但对于其他平台,我们必须先作一个物理地址到虚拟地址的映射,然后操作其虚拟地址。这样显然程序的可移植性不好,我们需要定义  #ifdef __x86....#elif defined __  使得在不同平台下程序能够顺利运行。
         

        如果使用下面的代码我们就可以不用这么费劲的定义不同平台了:

        先定义
     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
}

  

[1]  

【责编:Luzi】

--------------------next---------------------

阅读(350) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~