下面学习一下KEY_Init():
DWORD KEY_Init(DWORD dwContext)
{
DWORD threadID; // thread ID
RETAILMSG(0,(TEXT("KEY_Init----/r/n")));
// 1. Virtual Alloc
Virtual_Alloc(); //分配虚拟地址
KeyGpioInit();
KeyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //创建事件对象,可以实现线程同步
if (!KeyEvent) {
RETAILMSG(1, (TEXT("ERROR: kEYBD: Failed to create event./r/n")));
return FALSE;
}
APIEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!APIEvent) {
RETAILMSG(1, (TEXT("ERROR: kEYBD: Failed to create API event./r/n")));
return FALSE;
}
//创建按键查询的线程,由第五个参数为0 ,则创建即运行
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;
}
static DWORD UserKeyProcessThread(void)
{
UINT32 IRQ;
//创建UserInputEvent事件,用于同步
HANDLE UserInputEvent = CreateEvent(NULL, FALSE, FALSE, szevtUserInput);
while(1)
{
Sleep(80);
BYTE Keys[KEY_COUNT];
bool Changed = false;
GetKeyValues(Keys);
for (int i = 0; i < KEY_COUNT; i++) {
if (Keys[i] != KeyValues[i]) {
KeyValues[i] = Keys[i];
Changed = true;
}
}
if (!Changed) {
continue;
}
如果有按键,那么就为两个事件进行标识
//WaitForSingleObject(KeyEvent, INFINITE);
SetEvent(UserInputEvent);
SetEvent(APIEvent);
}
}
接下来,就看一下,这个APIEVENT同步事件的作用
DWORD KEY_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
RETAILMSG(0,(TEXT("USERKEY: KEY_Read/r/n")));
……
//等待APIEvent被标识,标识后既可以将按键值赋给PBUFFER,从而在上位软件中读取到
DWORD ret = WaitForSingleObject(APIEvent, INFINITE);
if (ret != WAIT_OBJECT_0) {
SetLastError(WAIT_TIMEOUT);
return -1;
}
if (ShutDownRead) {
//RETAILMSG(1,(TEXT("USERKEY: be asked to close/r/n")));
SetLastError(ERROR_HANDLE_EOF);
return -1;
}
RETAILMSG(0,(TEXT("USERKEY: Reset count is %d/r/n"), Count));
BYTE Keys[KEY_COUNT];
GetKeyValues(Keys);
memcpy(pBuffer, Keys, total);
return total;
}