WINCE按键驱动流程
一. 一般使用流接口
二. 在初始函数中使用MmMapIoSpace建立动态映射
pa.QuadPart = SIC2_BASE;
m_pINTCRegs = (INTC_REGS_T *) MmMapIoSpace(pa,
sizeof (INTC_REGS_T), FALSE);
pa.QuadPart = GPIO_BASE;
m_pGPIORegs = (GPIO_REGS_T *) MmMapIoSpace(pa,
sizeof (GPIO_REGS_T), FALSE);
三. 初始化IO,一般设成中断方式
m_pINTCRegs->er |=GPI19_IRQ_MASK;
m_pINTCRegs->atr &= ~GPI19_IRQ_MASK; // Level sensitive
m_pINTCRegs->apr &= ~GPI19_IRQ_MASK; // low sensitive
四. 使用CreateEvent创建事件,并使用KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR取得逻辑中断号,再调用InterruptInitialize把逻辑中断号与前面创建的事件相关连
//Create a connection to the IST event
m_hEvent=CreateEvent(NULL, FALSE, FALSE,NULL);
// Map sysIntr value to the button down interrupt(IRQ)
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &(m_Irq),
sizeof(m_Irq), &(m_sysIntr), sizeof(m_sysIntr), NULL))
{
return 0;
}
//Disconnect any previous event connected to sysintr id
InterruptDisable(m_sysIntr);
//Connect sysintr and events
InterruptInitialize (m_sysIntr, m_hEvent,NULL, 0);
五. 创建一个线程,在线程中使用WaitForSingleObject等待上文中的事件,当有中断发生时,该函数返回,这时就可以做其它的工作了(处理完了要调用InterruptDone通知系统响应了中断).如果中断没发生,这个函数会使该线程挂起
m_hThread= CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)StartThread,this, 0, NULL); // 创建一个线程
六. 用查询或其它方法得到用户的按键后,可以使用keybd_event模拟按钮被按下(对系统来说)
七. 在卸载函数中把前面申请的资源(内存,内核对象)之类的东西释放掉,有借有还,再借不难
//中断处理线程处理程序中的部分代码
while(!pData->abort)
{
//Wait for interrupt events
WaitForSingleObject(pData->hEvent,INFINITE);
if(pData->abort)
break;
//The following delay, judge use to the jitter
//Low-voltage to maintain 50ms, said the key is pressed
Sleep(50);
if(((pGPIORegs->pio_inp_state)&(pData->GPI_STATUS))!=0)
goto end_interrupt;
//Key handling
keybd_event (pData->Virtual_Key,0x25, KEYEVENTF_SILENT, 0); 该函数合成一次击键事件。系统可使用这种合成的击键事件来产生WM_KEYUP或WM_KEYDOWN消息
//High-voltage to maintain 50ms, said the release key
key_release:
while(!((pGPIORegs->pio_inp_state)&(pData->GPI_STATUS)))
continue;
Sleep(50);
if(((pGPIORegs->pio_inp_state)&(pData->GPI_STATUS))==0)
goto key_release;
keybd_event(pData->Virtual_Key,0x25, KEYEVENTF_SILENT | KEYEVENTF_KEYUP, 0);
end_interrupt:
//Let the system know that interrupt handling has been completed
InterruptDone(pData->sysIntr);
}