您的位置:首页 > 其它

WinCE下非标准键盘的驱动程序设计

2012-09-28 09:31 274 查看
原文地址:http://space.itpub.net/16803921/viewspace-608084

键盘作为收入设备,在嵌入式系统中应用广泛。它与PC键盘不同,嵌入式系统中的键盘千差万别,随实际应用的场景不同而不同。今天在这里介绍就是一种非标准键盘的驱动程序设计。在一些应用中,可能只会用到有限的几个按键。为了节省硬件成本,并充分利用既有的硬件资源,通常将这些按键连接到MCU的外部中断引脚上。如S3C2410有一百多个GPIO,几十个外部中断,我们就可以用几个外部中断来实现系统的按键功能。

虽然嵌入式系统中的键盘形形色色,各不相同,但驱动的框架基本一致。从工作模式的角度来看,一般有中断方式和扫描方式。在中断服务线程中读取按键的扫描码,并将其转换为虚拟按键信息发送给系统。采用扫描方式的过程与此类似。但如前所述的非标准键盘驱动就可不必采用该框架,而使用普通的中断处理方式,在中断服务线程中模拟相应的按键信息,调用函数keybd_event()即可。

下面以S3C2410的外部中断4为例,简单介绍一下整个处理过程。

UINT32 Irq1 = IRQ_EINT4;

2

UINT32 SysIntr1 = SYSINTR_UNDEFINED;

3

HANDLE IntrEvent1 = NULL;

4

BOOL bThreadExit1 = FALSE;

5

UINT IntrThreadProc1(LPVOID);

6

//模拟按键

7

void SimulateKey(BYTE bVk)

8

{

9

keybd_event(bVk,0,0,0);

10

keybd_event(bVk,0,KEYEVENTF_KEYUP,0);

11

}

12

KEY_Init()中的关键代码

13

//初始化中断

14

EnableInterrupt();

15

//创建中断服务线程

16

if(!CreateThread(0, 0, (LPTHREAD_START_ROUTINE)IntrThreadProc1,0,0,NULL))

17

{

18

RETAILMSG(1, (TEXT("***KEYDrv: KEY_Init fail(1).\r\n")));

19

return FALSE;

20

}

21

KEY_Deinit()中的关键代码:

22

//设置退出线程的标志

23

bThreadExit1 = TRUE;

24

//模拟一个中断事件

25

SetInterruptEvent(SysIntr1);

26

//中断服务线程

27

UINT IntrThreadProc1(LPVOID ptr)

28

{

29

IntrEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);

30


31

if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq1, sizeof(UINT32), &SysIntr1, sizeof(UINT32), NULL))

32

{

33

RETAILMSG(1, (TEXT("ERROR:IntrThreadProc1 Failed to request sysintr.\r\n")));

34

return(0);

35

}

36


37

//关联SYSINTR和之前创建的事件

38

if (!(InterruptInitialize(SysIntr1, IntrEvent1, 0, 0)))

39

{

40

RETAILMSG(1, (TEXT("ERROR: IntrThreadProc1 InterruptInitialize failed.\r\n")));

41

}

42


43

while(1)

44

{

45

WaitForSingleObject(IntrEvent1, INFINITE);

46


47

if(bThreadExit1)

48

{

49

break;

50

}

51


52

SimulateKey(VK_F1);

53

Sleep(1);

54

InterruptDone(SysIntr1);

55

}

56

//取消IRQ与SYSINTR之间的关联

57

KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&SysIntr1, sizeof(UINT32),NULL,0, NULL);

58

//取消Event与PwrButtonSysIntr之间的关联

59

InterruptDisable(SysIntr1);

60

CloseHandle(IntrEvent1);

61

RETAILMSG(1, (TEXT("IntrThreadProc1 IST Exit.\r\n")));

62

return 0;

63

}

64


在该中断服务线程中模拟了F1按键按下抬起的过程,所以当外部中断4被触发时,系统会接收到F1键的信息,上层应用程序可以对此做进一步的处理。如果硬件系统中只有两三个这样的按键,采用该方法还是比较方便的。如果按键较多,则可以定义一个结构,将啰嗦的代码精简一下。
另外,如果中断不能正常工作,可以按照以下几个步骤逐一排查。
1. 硬件中断有没有被触发。这里可以借助于示波器查看中断引脚的信号。
2. 驱动中有没有正确配置中断的工作模式。一般来说,中断与IO复用,在使用中断时需要配置。配置完了以后,还需要防止被别的程序修改。
3. 如果有中断信号且配置完全正确,也没有被别人修改,则需要考虑当前中断是否已经被别的驱动注册。WinCE中,硬件中断可被多次注册而不会出错,但却不能正常工作了。这一点在WinCE
6.0中断驱动程序分析中曾做过分析。
4. 如果以上步骤都没有问题,则需要考虑中断服务例程中有没有对该中断作出正确的处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: