UINT32 SysIntr1 = SYSINTR_UNDEFINED;
HANDLE IntrEvent1 = NULL;
BOOL bThreadExit1 = FALSE;
UINT IntrThreadProc1(LPVOID);
//模拟按键
void SimulateKey(BYTE bVk)
{
keybd_event(bVk,0,0,0);
keybd_event(bVk,0,KEYEVENTF_KEYUP,0);
}
KEY_Init()中的关键代码:
//初始化中断
EnableInterrupt();
//创建中断服务线程
if(!CreateThread(0, 0, (LPTHREAD_START_ROUTINE)IntrThreadProc1,0,0,NULL))
{
RETAILMSG(1, (TEXT("***KEYDrv: KEY_Init fail(1).\r\n")));
return FALSE;
}
KEY_Deinit()中的关键代码:
//设置退出线程的标志
bThreadExit1 = TRUE;
//模拟一个中断事件
SetInterruptEvent(SysIntr1);
//中断服务线程
UINT IntrThreadProc1(LPVOID ptr)
{
IntrEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq1, sizeof(UINT32), &SysIntr1, sizeof(UINT32), NULL))
{
RETAILMSG(1, (TEXT("ERROR:IntrThreadProc1 Failed to request sysintr.\r\n")));
return(0);
}
//关联SYSINTR和之前创建的事件
if (!(InterruptInitialize(SysIntr1, IntrEvent1, 0, 0)))
{
RETAILMSG(1, (TEXT("ERROR: IntrThreadProc1 InterruptInitialize failed.\r\n")));
}
while(1)
{
WaitForSingleObject(IntrEvent1, INFINITE);
if(bThreadExit1)
{
break;
}
SimulateKey(VK_F1);
Sleep(1);
InterruptDone(SysIntr1);
}
//取消IRQ与SYSINTR之间的关联
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&SysIntr1, sizeof(UINT32),NULL,0, NULL);
//取消Event与PwrButtonSysIntr之间的关联
InterruptDisable(SysIntr1);
CloseHandle(IntrEvent1);
RETAILMSG(1, (TEXT("IntrThreadProc1 IST Exit.\r\n")));
return 0;
}
在该中断服务线程中模拟了F1按键按下抬起的过程,所以当外部中断4被触发时,系统会接收到F1键的信息,上层应用程序可以对此做进一步的处理。如果硬件系统中只有两三个这样的按键,采用该方法还是比较方便的。如果按键较多,则可以定义一个结构,将啰嗦的代码精简一下。
另外,如果中断不能正常工作,可以按照以下几个步骤逐一排查。
1. 硬件中断有没有被触发。这里可以借助于示波器查看中断引脚的信号。
2. 驱动中有没有正确配置中断的工作模式。一般来说,中断与IO复用,在使用中断时需要配置。配置完了以后,还需要防止被别的程序修改。
3. 如果有中断信号且配置完全正确,也没有被别人修改,则需要考虑当前中断是否已经被别的驱动注册。WinCE中,硬件中断可被多次注册而不会出错,但却不能正常工作了。这一点在WinCE 6.0中断驱动程序分析中曾做过分析。
4. 如果以上步骤都没有问题,则需要考虑中断服务例程中有没有对该中断作出正确的处理。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/16803921/viewspace-608084/ ,如需转载,请注明出处,否则将追究法律责任。