比如采用c# 等语言 当io口中断的 时候 我的程序 怎么知道呢?!
一般来说,你先做成你的驱动程序,然后就可以很好的控制了。
这段肯定是用C来写了,注册个自己的IO口中断,然后和中断处理线程映射上就行了
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下操作,也可以参考这个思路。
觉得可以的话别忘了给我加分!!!!!!!!!!!!!!!!我的分少啊.
楼上的说的十分详细
如果 我想在c#下操作 具体该 怎么做的
这个问题解决了
分不是问题
在EVC里嵌汇编直接操作寄存器,或者是做一个映射,操作虚拟地址
各位能否说的详细点
本人实践了怎么长时间 还是没解决啊
我做的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;
}
楼上的IO端口函数到底对不对,我现在也需要在wince下访问IO端口寄存器,不知道如何写,有没有高手知道比较急,谢谢