请教关于Micro2440的userkey驱动的调用
又来CSDN请教了,呵呵,首先感谢先前回帖者!你们的回复对我帮助很大,呵呵!
我用的是Micro2440的板子,WinCE5.0的BSP。在D:\WINCE500\PLATFORM\mini2440\Src\Drivers\Userkey下面有对应开发板上面的6个用户按键的驱动,驱动程序把他们设置成了TAB键,RIGHT DOWN,LEFT DOWN ,ENTER,RIGHT,LEFT等六个功能键,主要程序如下(完整代码见Micro2440和mini2440驱动原文件(部分非关键函数省略)):
#include <windows.h>
//#include <ceddk.h>
#include <nkintr.h>
//#include <oalintr.h>
#include <pm.h>
#include "pmplatform.h"
#include "Pkfuncs.h"
#include "s2440.h"
volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
volatile INTreg *s2440INT = (INTreg *)INT_BASE;
UINT32 g_KeySysIntr[6];
HANDLE KeyThread;
HANDLE KeyEvent;
void Virtual_Alloc();// Virtual allocation
DWORD UserKeyProcessThread(void);
DWORD UserKeyProcessThread(void)
{
UINT32IRQ;
KeyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!KeyEvent) {
RETAILMSG(1, (TEXT("ERROR: kEYBD: Failed to create event.\r\n")));
return FALSE;
}
IRQ = 36; //IRQ_EINT8;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IRQ, sizeof(UINT32), &g_KeySysIntr[0], sizeof(UINT32), NULL)) {
RETAILMSG(1, (TEXT("ERROR: kEYBD: Failed to request sysintr value.\r\n")));
return FALSE;
}
IRQ = 39; //IRQ_EINT11;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IRQ, sizeof(UINT32), &g_KeySysIntr[1], sizeof(UINT32), NULL)) {
RETAILMSG(1, (TEXT("ERROR: kEYBD: Failed to request sysintr value.\r\n")));
return FALSE;
}
IRQ = 41; //IRQ_EINT13;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IRQ, sizeof(UINT32), &g_KeySysIntr[2], sizeof(UINT32), NULL)) {
RETAILMSG(1, (TEXT("ERROR: kEYBD: Failed to request sysintr value.\r\n")));
return FALSE;
}
IRQ = 42; //IRQ_EINT14;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IRQ, sizeof(UINT32), &g_KeySysIntr[3], sizeof(UINT32), NULL)) {
RETAILMSG(1, (TEXT("ERROR: kEYBD: Failed to request sysintr value.\r\n")));
return FALSE;
}
IRQ = 43; //IRQ_EINT15;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IRQ, sizeof(UINT32), &g_KeySysIntr[4], sizeof(UINT32), NULL)) {
RETAILMSG(1, (TEXT("ERROR: kEYBD: Failed to request sysintr value.\r\n")));
return FALSE;
}
IRQ = 47; //IRQ_EINT19;
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &IRQ, sizeof(UINT32), &g_KeySysIntr[5], sizeof(UINT32), NULL)) {
RETAILMSG(1, (TEXT("ERROR: kEYBD: Failed to request sysintr value.\r\n")));
return FALSE;
}
if (!InterruptInitialize(g_KeySysIntr[0], KeyEvent, NULL, 0)) {
RETAILMSG(1,(TEXT("Fail to initialize userkey interrupt event\r\n")));
return FALSE;
}
if (!InterruptInitialize(g_KeySysIntr[1], KeyEvent, NULL, 0)) {
RETAILMSG(1,(TEXT("Fail to initialize userkey interrupt event\r\n")));
return FALSE;
}
if (!InterruptInitialize(g_KeySysIntr[2], KeyEvent, NULL, 0)) {
RETAILMSG(1,(TEXT("Fail to initialize userkey interrupt event\r\n")));
return FALSE;
}
if (!InterruptInitialize(g_KeySysIntr[3], KeyEvent, NULL, 0)) {
RETAILMSG(1,(TEXT("Fail to initialize userkey interrupt event\r\n")));
return FALSE;
}
if (!InterruptInitialize(g_KeySysIntr[4], KeyEvent, NULL, 0)) {
RETAILMSG(1,(TEXT("Fail to initialize userkey interrupt event\r\n")));
return FALSE;
}
if (!InterruptInitialize(g_KeySysIntr[5], KeyEvent, NULL, 0)) {
RETAILMSG(1,(TEXT("Fail to initialize userkey interrupt event\r\n")));
return FALSE;
}
while(1)
{
WaitForSingleObject(KeyEvent, INFINITE);
RETAILMSG(0,(L"EINTMASK=%X, rGPGCON=%X\r\n", s2440IOP->rEINTMASK, s2440IOP->rGPGCON));
//EINT8 - K1 - VK_TAB - 0x09
if(s2440IOP->rEINTMASK & (DWORD)(0x1<<8))
{
RETAILMSG(1,(TEXT("[Key1 - TAB]\r\n")));
keybd_event(VK_TAB ,0x09, 0, 0);
Sleep(30);
keybd_event(VK_TAB ,0x09, KEYEVENTF_KEYUP, 0);
InterruptDone(g_KeySysIntr[0]);
}
//EINT11 - K2 - VK_UP - 0x26
if(s2440IOP->rEINTMASK & (DWORD)(0x1<<11))
{
RETAILMSG(1,(TEXT("[Key2 - UP]\r\n")));
keybd_event(VK_UP ,0x26, 0, 0);
Sleep(30);
keybd_event(VK_UP ,0x26, KEYEVENTF_KEYUP, 0);
InterruptDone(g_KeySysIntr[1]);
}
//EINT13 - K3 - VK_RETURN - 0x0D
if(s2440IOP->rEINTMASK & (DWORD)(0x1<<13))
{
RETAILMSG(1,(TEXT("[K3 - RETURN]\r\n")));
keybd_event(VK_RETURN ,0x0D, 0, 0);
Sleep(30);
keybd_event(VK_RETURN ,0x0D, KEYEVENTF_KEYUP, 0);
InterruptDone(g_KeySysIntr[2]);
}
//EINT14 - K4 - VK_DOWN - 0x28
if(s2440IOP->rEINTMASK & (DWORD)(0x1<<14))
{
RETAILMSG(1,(TEXT("[K4 - DONW]\r\n")));
keybd_event(VK_DOWN ,0x28, 0, 0);
Sleep(30);
keybd_event(VK_DOWN ,0x28, KEYEVENTF_KEYUP, 0);
InterruptDone(g_KeySysIntr[3]);
}
//EINT15 - K5 - VK_LEFT - 0x25
if(s2440IOP->rEINTMASK & (DWORD)(0x1<<15))
{
RETAILMSG(1,(TEXT("[K5 - LEFT]\r\n")));
keybd_event(VK_LEFT ,0x25, 0, 0);
Sleep(30);
keybd_event(VK_LEFT ,0x25, KEYEVENTF_KEYUP, 0);
InterruptDone(g_KeySysIntr[4]);
}
//EINT19 - K6 - VK_RIGHT - 0x27
if(s2440IOP->rEINTMASK & (DWORD)(0x1<<19))
{
RETAILMSG(1,(TEXT("[K6 - RIGHT]\r\n")));
keybd_event(VK_RIGHT ,0x27, 0, 0);
Sleep(30);
keybd_event(VK_RIGHT ,0x27, KEYEVENTF_KEYUP, 0);
InterruptDone(g_KeySysIntr[5]);
}
}
}
void Virtual_Alloc()
{
}
BOOL WINAPI
DllEntry(HANDLEhinstDLL,
DWORD dwReason,
LPVOID Reserved/* lpvReserved */)
{
}
BOOL KEY_Deinit(DWORD hDeviceContext)
{
}
BOOL KeyGpioInit()
{
RETAILMSG(1,(TEXT("Key_Gpio_Setting----\r\n")));
s2440IOP->rGPGUP = 0xffff;
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 0x0)) | (0x2 << 0x0);// GPG0 == EINT8
s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 0)) | (0x3 << 0);// Falling-edge triggered.
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 6)) | (0x2 << 6);// GPG3 == EINT11
s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 12)) | (0x3 << 12);// Falling-edge triggered.
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 10)) | (0x2 << 10);// GPG5 == EINT13
s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 20)) | (0x3 << 20);// Falling-edge triggered.
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 12)) | (0x2 << 12);// GPG6 == EINT14
s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 24)) | (0x3 << 24);// Falling-edge triggered.
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 14)) | (0x2 << 14);// GPG7 == EINT15
s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 28)) | (0x3 << 28);// Falling-edge triggered.
s2440IOP->rGPGCON = (s2440IOP->rGPGCON & ~(0x3 << 22)) | (0x2 << 22);// GPG11 == EINT19
s2440IOP->rEXTINT2 = (s2440IOP->rEXTINT2 & ~(0x7<< 12)) | (0x3 << 12);// Falling-edge triggered.
return TRUE;
}
DWORD KEY_Init(DWORD dwContext)
{
DWORD threadID; // thread ID
RETAILMSG(1,(TEXT("KEY_Init----\r\n")));
// 1. Virtual Alloc
Virtual_Alloc();
KeyGpioInit();
KeyThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)UserKeyProcessThread,
0,
0,
&threadID);
if (NULL == KeyThread ) {
RETAILMSG(1,(TEXT("ERROR: failed to Create Key Thread!\r\n")));
return FALSE;
}
return TRUE;
}
其中 while(1)循环中
//EINT8 - K1 - VK_TAB - 0x09
if(s2440IOP->rEINTMASK & (DWORD)(0x1<<8))
{
RETAILMSG(1,(TEXT("[Key1 - TAB]\r\n")));
keybd_event(VK_TAB ,0x09, 0, 0);//向应用程序发生按键按下消息
Sleep(30);//延时
keybd_event(VK_TAB ,0x09, KEYEVENTF_KEYUP, 0);//向应用程序发送按键抬起消息
InterruptDone(g_KeySysIntr[0]);//完成中断
}
这部分代码是处理外部中断的。
我想直接套用这个程序,然后通过按下这六个按键来控制GPF0,GPF1,GPF2,GPF3,GPF4,GPF5上的电平。
有几个问题想问一下:
1> 程序中if(s2440IOP->rEINTMASK & (DWORD)(0x1<<8))这条语句是判断按键按下吗(我看了其他的许多按键中断程序,都是用Is_Pushed()函数来判断的)?如果是这样,那么这条语句是否代表中断开启?
2> 我写了一个GPIO的驱动,定义了GPF0,GPF1,GPF2,GPF3,GPF4,GPF5电平的高低,我想在修改这个按键驱动的基础上,达到需求(通过按下这六个按键来控制GPF0,GPF1,GPF2,GPF3,GPF4,GPF5上的电平),是否应该在这个驱动里面待中断发生后,打开GPIO驱动,然后通过DeviceIoControl来控制GPF0,GPF1,GPF2,GPF3,GPF4,GPF5电平?
我尝试着编写了下面代码,但是没能达到要求:
if(s2440IOP->rEINTMASK & (DWORD)(0x1<<8))
{
RETAILMSG(1,(TEXT("[Key1 - PUSHED]\r\n")));
/*keybd_event(VK_TAB ,0x09, 0, 0);//应用程序发生按键按下消息 */
Sleep(30);
HANDLE key1GPIO = CreateFile(_T("GPO1:"), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); //打开GPIO驱动
DeviceIoControl(key1GPIO,IO_CTL_X_PLUSE_ON, NULL, 0, NULL, 0, NULL, NULL);//PLUSE_ON 给IO口高电平,停止
/*keybd_event(VK_TAB ,0x09, KEYEVENTF_KEYUP, 0);//向应用层发送按键抬起消息*/
InterruptDone(g_KeySysIntr[0]);//完成中断
}
GPIO驱动中case IO_CTL_X_PLUSE_ON:
s2440IOP->rGPFDAT=s2440IOP->rGPFDAT|(0x1<<0);//GPF0
break;
设定GPF0输出高电平。我把对IO_CTL_X_PLUSE_ON的预定义做了个头文件,放在userkey文件夹中,经过PB编译后没有错误,编译内核也没有错误,可是按键按下后不能达到要求。
特向各位请教,希望各位指出问题所在和提出解决方法。
[解决办法]
{
HANDLE key1GPIO = CreateFile(_T("GPO1:"), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); //打开GPIO驱动
DeviceIoControl(key1GPIO,IO_CTL_X_PLUSE_ON, NULL, 0, NULL, 0, NULL, NULL); //PLUSE_ON 给IO口高电平,停止
InterruptDone(g_KeySysIntr[0]); //完成中断
}
还要确认你调用DeviceIoControl(key1GPIO,IO_CTL_X_PLUSE_ON, NULL, 0, NULL, 0, NULL, NULL)后是否进来GPO_IoControl这个函数的IO_CTL_X_PLUSE_ON这个case