相关服务

  • 《现代电子技术》2006年第24期摘录:李杰等:基于嵌入式Linux的

如发现有乱码,请点击下面链接浏览原文
正文摘录:

李杰等:基于嵌入式Linux的矩阵键盘设计与实现层。本段主要讨论键盘驱动的实现。I。inux系统下驱动程序可以静态编译到内核中,也可编译为模块方式动态加载到内核中,这样可以提高内核稳定性并减小其占用的内存空间。本文选择将键盘驱动以动态模式加载到内核中。对于Linux系统下的字符设备驱动模块,首先要进行初始化。在此步骤中注册一个字符设备,分配主设备号和从设备号,初始化一个环形队列并且定义一个键盘控制的数据结构,其中包括键值、键的状态和长按标志。应用程序对设备驱动的调用实际是对相应设备文件进行操作。在文件系统中先要建立键盘设备的文件节点,利用mknod命令将此节点与对应设备建立联系。应用程序打开/dev/kdc:这个设备文件时,就会调用驱动中的open函数,此函数会对键盘所用到的行列GPI()口进行配置。很多情况下,open函数所做的工作才算是真正的初始化,这表明系统要使用该设备了。打开的设备在内核中由file结构标识,内核使用file—oper。ation结构访问驱动程序的函数[2]。文件可以认为是一个“对象”,操作他的函数是“方法”,这些方法主要负责系统调用的实现,比如read,write等0j。在本驱动中open函数的工作如下:将4根行GPI()口设置为输出低,4根列GPI()口设置为下降沿触发的中断源,然后在内核中启动一个线程KT(KeyboardThread),专门用于处理键盘事件,其实也就是向系统申请了软硬件资源。如图2所示。≮扫描矩阵,得到键值送入环形等待队列图2驱动工作流程初始化完毕后,当无键盘事件时,KT线程阻塞。一旦有按键被按下,某列GPI()口则会产生下降沿触发的中断,进入中断例程。中断例程中只是唤醒阻塞的KT线程,而键盘矩阵扫描和读取键值等对键盘按下事件的处理均通过KT线程来实现。由于在PXA255处理器中,GPI()中2~80口(共79)共用一个中断请求,armLinux在对此中断进行处理时,进入中断例程后会屏蔽该线上的其他中断,直到退出中断例程,以防止其他GPI()口上的中断对此次中断处理产生干扰。。]。因此不难想到当用这8279个GPI()口作为中断源时,如果某个中断例程处理的时间太长就可能导致其他中断无法响应,从而产生丢中断的严重后果。在本方案中使用KT线程来处理,避免了在中断例程中耽搁较长时间,影响其他外部中断请求。由于Linux系统中内核态都是一些线程在运行,大多IJinux字符设备驱动中都会通过kerneltl,read()函数来申请内核线程,用以处理相应的中断事件。KT线程的使用不会影响其他程序运行且能保证较好对键盘事件进行实时响应。3.2矩阵扫描算法实现下面分析线程唤醒后扫描键盘矩阵得到键值和键盘状态的过程。如图3所示:图3矩阵扫描流程图先进行键盘去抖动判断,以往很多嵌入式系统中都采用忙等待,大约延时8~10ms再判断是否键还按着。但嵌入式I,inux是一个多任务操作系统,忙等待会消耗cPu资源从而对系统性能产生一定的影响。因此使用I。inux提供的定时器机制,当线程唤醒后,先设置一个10ms定时器,然后线程进入睡眠状态,CPU则可以处理其他进程的响应。定时器时间到,线程被唤醒,进入矩阵键盘扫描程序。按照顺序先将某行GPI()口状态设为低电平,然后依次去读取4根列GPI()口状态,如某列GPI()口电平为低,就表示此行此列有键按下,根据行号和列号从对应的二维数组(也就是键值映射表)中找到该键的键值。这里还使用了一个数组kdcpressed[],他里面保存每个按键的按下(1)和抬起(O)标志,在扫描过程中得到各键(跟数组的索引一一对应)的当前状态,然后填入kdc-pressed口。3.3多键齐按和长按键功能支持以往很多矩阵键盘都不支持多键齐按功能,但对类似一F磊否\一阻打是\一

阅读此文(图):   点击此处在线翻阅