在wince 如何访问 io 口

tddwp   2007-1-9 21:26 楼主
比如采用c# 等语言 当io口中断的  时候 我的程序 怎么知道呢?!

回复评论 (18)


一般来说,你先做成你的驱动程序,然后就可以很好的控制了。
点赞  2007-1-10 09:24
这段肯定是用C来写了,注册个自己的IO口中断,然后和中断处理线程映射上就行了
点赞  2007-1-10 09:43
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\n\r")));
  return TRUE;
}
if (!VirtualCopy((PVOID)v_pIOPRegs, (PVOID)IOP_BASE, sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE)) {
  DEBUGMSG (1,(TEXT("v_pIOPRegs is not mapped\n\r")));
  return TRUE;
}
DEBUGMSG (1,(TEXT("v_pIOPRegs is mapped to %x\n\r"), v_pIOPRegs));
这3个步骤之后,对v_pIOPRegs的操作将直接和GPIO的寄存器关联
例如:设置GPB的控制寄存器为全部Output
v_pIOPRegs->rGPBCON=0x155555;
设置GPB的数据寄存器输出高电平
v_pIOPRegs->rGPBDAT=0x3FF;

更多的操作,需要查阅ARM的datasheet以及WINCE的BSP源码完成。

对于非ARM的平台,在CE下操作,也可以参考这个思路。



觉得可以的话别忘了给我加分!!!!!!!!!!!!!!!!我的分少啊.
点赞  2007-1-10 16:06
楼上的说的十分详细
如果 我想在c#下操作 具体该 怎么做的
这个问题解决了
分不是问题
点赞  2007-1-10 20:34
说得很细,mark
点赞  2007-1-10 22:58
mark一个
点赞  2007-1-10 23:41
别mark啊
希望高手 继续发言
谢谢了
点赞  2007-1-11 20:49
偶也mark一下  ce-io
点赞  2007-1-12 14:33
我再顶
点赞  2007-1-13 08:27
再顶
点赞  2007-1-13 21:29
在EVC里嵌汇编直接操作寄存器,或者是做一个映射,操作虚拟地址
点赞  2007-1-14 12:01
各位能否说的详细点
本人实践了怎么长时间 还是没解决啊
点赞  2007-1-17 22:39
俺不是高手,see one down。
点赞  2007-1-18 18:16
郁闷中
点赞  2007-1-18 22:39
地址映射。。但是要对硬件环境比较熟悉才可以。
点赞  2007-1-19 17:38
继续求组
点赞  2007-1-21 20:23
我做的IO端口读写函数,有内联汇编实现的我觉的应该没有问题,但写的时候可以,读不出数据!你参考一下吧!各位也帮我看看!

//写端口
void OutPortByte(WORD wAddr,BYTE bTemp)
{
        _asm
        {
                push eax
                push edx
                mov dx,wAddr
                mov al,bTemp
                out dx,al
                pop edx
                pop eax
        }
}

//读端口
BYTE InPortByte(WORD wAddr)
{
        BYTE bValue=0;
        _asm
        {
                push eax
                push edx
                mov dx,wAddr
                in al ,dx
                mov bValue,al
                pop edx
                pop eax
        }
        return bValue;
}
点赞  2007-7-4 08:29
楼上的IO端口函数到底对不对,我现在也需要在wince下访问IO端口寄存器,不知道如何写,有没有高手知道比较急,谢谢
点赞  2008-8-4 16:10
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复