zoukankan      html  css  js  c++  java
  • Wince下IO口的操作

    相信这是大多刚接触嵌入式系统的人都会碰上的问题,在YC的网上找到了资料,在这儿贴出来,共同学习。 
    
    Windows CE下操作GPIO的方法(以ARM9 S3C2410为例)
      
     
    GPIO 是ARM芯片最基本的输入输出通道,在ADS下操作就是一个单片机工作,直接读写其寄存器。在ARM9平台上,Windows CE系统将GPIO的实地址(例如2410的GPIO的基地址为0x56000000)映射到虚拟地址空间(GPIO对应为0xB1600000),这样,通过对这段虚拟地址空间的操作,就能够完成对GPIO或者其他片内资源的控制、输入输出工作。
    要操作一个平台的GPIO,在其对应BSP中按照基地址,找到虚拟地址,并且找到方便操作这个地址的数据结构就可以了,关键函数就是VirtualAlloc和VirtualCopy。并且CE的方便之处就是用户态的应用程序仍然可以使用这两个函数来访问所有这些虚拟空间,对于不太复杂的程序,甚至可以省略写驱动直接在应用程序中操作,其实在CE6之前,这些驱动也是工作在用户态的。
    下面以操作Samsung S3C2410的GPIO为例,讲述这个步骤:
    1.首先在BSP中的s2410.h文件,找到虚拟地址映射以及操作GPIO的寄存器结构体(这个在自己制作一些特殊设备的BSP时,会依据需要而发生更改)
    //
    // Registers : I/O port
    //
    #define IOP_BASE      0xB1600000 // 0x56000000
    typedef struct  {
        unsigned int  rGPACON;  // 00
        unsigned int  rGPADAT;
        unsigned int  rPAD1[2];
      
        unsigned int  rGPBCON;  // 10
        unsigned int  rGPBDAT;
        unsigned int  rGPBUP;
        unsigned int  rPAD2;
      
        unsigned int  rGPCCON;  // 20
        unsigned int  rGPCDAT;
        unsigned int  rGPCUP;
        unsigned int  rPAD3;
      
        unsigned int  rGPDCON;  // 30
        unsigned int  rGPDDAT;
        unsigned int  rGPDUP;
        unsigned int  rPAD4;
      
        unsigned int  rGPECON;  // 40
        unsigned int  rGPEDAT;
        unsigned int  rGPEUP;
        unsigned int  rPAD5;
      
        unsigned int  rGPFCON;  // 50
        unsigned int  rGPFDAT;
        unsigned int  rGPFUP;
        unsigned int  rPAD6;
      
        unsigned int  rGPGCON;  // 60
        unsigned int  rGPGDAT;
        unsigned int  rGPGUP;
        unsigned int  rPAD7;
      
        unsigned int  rGPHCON;  // 70
        unsigned int  rGPHDAT;
        unsigned int  rGPHUP;
        unsigned int  rPAD8;
      
        unsigned int  rMISCCR;  // 80
        unsigned int  rDCKCON; 
        unsigned int  rEXTINT0;
        unsigned int  rEXTINT1; 
        unsigned int  rEXTINT2;  // 90
     unsigned int  rEINTFLT0;
     unsigned int  rEINTFLT1;
     unsigned int  rEINTFLT2;
     unsigned int  rEINTFLT3;  // A0
     unsigned int  rEINTMASK;
     unsigned int  rEINTPEND;
     unsigned int  rGSTATUS0;  // AC
     unsigned int  rGSTATUS1;  // B0
     unsigned int  rGSTATUS2;  // B4
     unsigned int  rGSTATUS3;  // B8
     unsigned int  rGSTATUS4;  // BC
     
    }IOPreg; 
    将这些复制备用。
    2.在EVC中建立一个应用程序工程,由于VirtualCopy函数没有在头文件中定义,但是在coredll.lib里面提供了符号连接,所以我们这里直接添加一个函数定义就OK了。
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    BOOL VirtualCopy( LPVOID, LPVOID, DWORD, DWORD );
    #ifdef __cplusplus
    }
    #endif
    同时将步骤1里面的定义复制到这里。
    3.按照驱动程序里面操作的方法在应用程序中写GPIO操作函数
    (1)定义一个寄存器结构体变量
    volatile IOPreg *v_pIOPRegs;
    (2)给这个变量分配空间并且映射到寄存器的空间上
    v_pIOPRegs = (volatile IOPreg*)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
     if (v_pIOPRegs == NULL)
     {
      DEBUGMSG (1,(TEXT("v_pIOPRegs is not allocated ")));
      return TRUE;
     }
     if (!VirtualCopy((PVOID)v_pIOPRegs, (PVOID)IOP_BASE, sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE)) {
      DEBUGMSG (1,(TEXT("v_pIOPRegs is not mapped ")));
      return TRUE;
     }
     DEBUGMSG (1,(TEXT("v_pIOPRegs is mapped to %x "), v_pIOPRegs));
    这3个步骤之后,对v_pIOPRegs的操作将直接和GPIO的寄存器关联
    例如:设置GPB的控制寄存器为全部Output
    v_pIOPRegs->rGPBCON=0x155555;
    设置GPB的数据寄存器输出高电平
    v_pIOPRegs->rGPBDAT=0x3FF;
    更多的操作,需要查阅ARM的datasheet以及WINCE的BSP源码完成。
    对于非ARM的平台,在CE下操作,也可以参考这个思路。
    Windows CE下操作GPIO的方法(以ARM9 S3C2410为例)
    GPIO 是ARM芯片最基本的输入输出通道,在ADS下操作就是一个单片机工作,直接读写其寄存器。在ARM9平台上,Windows CE系统将GPIO的实地址(例如2410的GPIO的基地址为0x56000000)映射到虚拟地址空间(GPIO对应为0xB1600000),这样,通过对这段虚拟地址空间的操作,就能够完成对GPIO或者其他片内资源的控制、输入输出工作。
    要操作一个平台的GPIO,在其对应BSP中按照基地址,找到虚拟地址,并且找到方便操作这个地址的数据结构就可以了,关键函数就是VirtualAlloc和VirtualCopy。并且CE的方便之处就是用户态的应用程序仍然可以使用这两个函数来访问所有这些虚拟空间,对于不太复杂的程序,甚至可以省略写驱动直接在应用程序中操作,其实在CE6之前,这些驱动也是工作在用户态的。
    下面以操作Samsung S3C2410的GPIO为例,讲述这个步骤:
    1.首先在BSP中的s2410.h文件,找到虚拟地址映射以及操作GPIO的寄存器结构体(这个在自己制作一些特殊设备的BSP时,会依据需要而发生更改)
    //
    // Registers : I/O port
    //
    #define IOP_BASE      0xB1600000 // 0x56000000
    typedef struct  {
        unsigned int  rGPACON;  // 00
        unsigned int  rGPADAT;
        unsigned int  rPAD1[2];
     
        unsigned int  rGPBCON;  // 10
        unsigned int  rGPBDAT;
        unsigned int  rGPBUP;
        unsigned int  rPAD2;
     
        unsigned int  rGPCCON;  // 20
        unsigned int  rGPCDAT;
        unsigned int  rGPCUP;
        unsigned int  rPAD3;
     
        unsigned int  rGPDCON;  // 30
        unsigned int  rGPDDAT;
        unsigned int  rGPDUP;
        unsigned int  rPAD4;
     
        unsigned int  rGPECON;  // 40
        unsigned int  rGPEDAT;
        unsigned int  rGPEUP;
        unsigned int  rPAD5;
     
        unsigned int  rGPFCON;  // 50
        unsigned int  rGPFDAT;
        unsigned int  rGPFUP;
        unsigned int  rPAD6;
     
        unsigned int  rGPGCON;  // 60
        unsigned int  rGPGDAT;
        unsigned int  rGPGUP;
        unsigned int  rPAD7;
     
        unsigned int  rGPHCON;  // 70
        unsigned int  rGPHDAT;
        unsigned int  rGPHUP;
        unsigned int  rPAD8;
     
        unsigned int  rMISCCR;  // 80
        unsigned int  rDCKCON;
        unsigned int  rEXTINT0;
        unsigned int  rEXTINT1;
        unsigned int  rEXTINT2;  // 90
     unsigned int  rEINTFLT0;
     unsigned int  rEINTFLT1;
     unsigned int  rEINTFLT2;
     unsigned int  rEINTFLT3;  // A0
     unsigned int  rEINTMASK;
     unsigned int  rEINTPEND;
     unsigned int  rGSTATUS0;  // AC
     unsigned int  rGSTATUS1;  // B0
     unsigned int  rGSTATUS2;  // B4
     unsigned int  rGSTATUS3;  // B8
     unsigned int  rGSTATUS4;  // BC
     
    }IOPreg;
    将这些复制备用。
    2.在EVC中建立一个应用程序工程,由于VirtualCopy函数没有在头文件中定义,但是在coredll.lib里面提供了符号连接,所以我们这里直接添加一个函数定义就OK了。
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    BOOL VirtualCopy( LPVOID, LPVOID, DWORD, DWORD );
    #ifdef __cplusplus
    }
    #endif
    同时将步骤1里面的定义复制到这里。
    3.按照驱动程序里面操作的方法在应用程序中写GPIO操作函数
    (1)定义一个寄存器结构体变量
    volatile IOPreg *v_pIOPRegs;
    (2)给这个变量分配空间并且映射到寄存器的空间上
    v_pIOPRegs = (volatile IOPreg*)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
     if (v_pIOPRegs == NULL)
     {
      DEBUGMSG (1,(TEXT("v_pIOPRegs is not allocated ")));
      return TRUE;
     }
     if (!VirtualCopy((PVOID)v_pIOPRegs, (PVOID)IOP_BASE, sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE)) {
      DEBUGMSG (1,(TEXT("v_pIOPRegs is not mapped ")));
      return TRUE;
     }
     DEBUGMSG (1,(TEXT("v_pIOPRegs is mapped to %x "), v_pIOPRegs));
    这3个步骤之后,对v_pIOPRegs的操作将直接和GPIO的寄存器关联
    例如:设置GPB的控制寄存器为全部Output
    v_pIOPRegs->rGPBCON=0x155555;
    设置GPB的数据寄存器输出高电平
    v_pIOPRegs->rGPBDAT=0x3FF;
    更多的操作,需要查阅ARM的datasheet以及WINCE的BSP源码完成。
    对于非ARM的平台,在CE下操作,也可以参考这个思路。


  • 相关阅读:
    刷题篇--热题HOT 71-80
    刷题篇--热题HOT 61-70
    双飞翼布局介绍-始于淘宝UED
    css布局——百度前端技术学院
    CSS多列布局Multi-column、伸缩布局Flexbox、网格布局Grid详解
    CSS之BFC详解
    深入理解BFC和Margin Collapse
    CSS 布局_如何实现容器中每一行的子容器数量随着浏览器宽度的变化而变化?
    3列、2列自适应布局,中部内容优先显示3列布局等方法
    三列布局,中间自适应
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318281.html
Copyright © 2011-2022 走看看