您的位置 首页 软件

嵌入式Linux体系的键盘驱动完成

Linux由于其具有内核强大且稳定,易于扩展和裁减,丰富的硬件支持等诸多优点,在嵌入式系统中得到了广泛的应用。很多嵌入式Linux系统,特别是一些具有与用户强交互的嵌入式系统,往往需要配备.

1导言

Linux因为其具有内核强壮且安稳,易于扩展和削减,丰厚的硬件支撑等许多长处,在嵌入式体系中得到了广泛的运用。许多嵌入式Linux体系,特别是一些具有与用户强交互的嵌入式体系,往往需求装备一个特别键盘,此时开发者需求根据实际状况,为自己的特别键盘编写驱动程序。

2Linux键盘驱动简介

Linux中的大多数驱动程序都采用了层次型的体系结构,键盘驱动程序也不破例。在Linux中,键盘驱动被划分红两层来完结。其间,上层是一个通用的键盘笼统层,完结键盘驱动中不依赖于底层详细硬件的一些功用,而且担任为底层供给服务;基层则是硬件处理层,与详细硬件密切相关,首要担任对硬件进行直接操作。键盘驱动程序的上层公共部分都在driver/keyboard。c中。该文件中最重要的便是内核用EXPORT_SYMBOL这个宏导出的handle_scancode函数。handle_scancode完结的功用是:首要将扫描码转化成键码,接着根据shift,alt等扩展键的按下状况将键码转化成方针码,一般状况下是ASCII码,最终将该ASCII码放到终端设备的缓冲区中,而且调度一个tasklet担任将其在显示器上回显出来。能够看出,这个函数完结的是键盘驱动程序中最中心的一些作业,而这些中心的逻辑功用是不依赖于底层硬件的,所以能够将其独立出来,而且导出给底层的硬件处理函数调用。在这个文件中还界说了其它几个回调函数,它们由键盘驱动程序中的上层公共部分调用,并由底层硬件处理函数完结。比方kbd_init_hw,kbd_translate,kbd_unexpected_up等等。其间kbd_translate由handle_scancode调用,担任将扫描码转化成键码;键盘驱动程序的底层硬件处理部分则根据不同的硬件有不同的完结。例如PC渠道上规范键盘的底层硬件处理函数都会集在driver/Pc_keyb。c中。这个文件包含了键盘中止处理函数keyboard_interrupt,扫描码到键码转化函数pckbd_translate等其他一些与底层硬件密切相关的函数。

在这种体系结构下,要增加一块特别键盘到体系中就显得分外明晰。开发者只需为其编写驱动程序中的底层硬件处理函数,就能够将该键盘驱动起来。一般说来,底层硬件处理函数中最重要的作业便是在键盘中止处理中获取被按下键的扫描码,而且以它为参数调用handle_scancode,该扫描码能够自己界说,但它有必要仅有地标识出被按下键在键盘上的方位。此外,开发者还需求供给对应的从自界说扫描码到键码的转化函数kbd_translate。详细的键码转化,将方针码放到终端的输入缓冲区,以及回显等作业都由handle_scancode担任完结。在此咱们也能够看出,内核导出函数handle_scancode在整个键盘驱动程序中,起着将上层通用笼统层和底层硬件处理层粘和起来的关键作用。

3运用实例

下面咱们将以一个详细的运用实例来阐明在嵌入式Linux体系中给一个特别键盘编写驱动程序的详细进程。

3。1硬件模块描绘

本体系的构建选用了三星公司的S3C2410开发板作为硬件渠道。特别键盘的硬件模块首要由两个SN74hc164芯片和一个4行16列的矩阵扫描电路构成。SN74hc164是一个8位的串形输入并形输出移位寄存器,它的内部由8个D触发器串联而成。其作业原理简略说来是这样的,SN74hc164芯片在时钟CLK脉冲的上升沿将A,B引脚上的串形输入在8个时钟脉冲今后并行输出到输出引脚QA到QH。其真值表见图1所示。

两个SN74hc164芯片先串联后,将它们的CLK引脚和CLR引脚别离接到S3C2410开发板的GPB2和GPB4端口上,而且将第一个SN74hc164芯片的A,B引脚接到开发板的GPB1端口上,这三个GPIO端口装备成输出端口。这样咱们就借助于两个SN74hc164寄存器,完结了只占用3个GPIO端口,给矩阵扫描电路的16列供给输入,然后既节省了本钱,又防止了GPIO资源的糟蹋。但这一起也给键盘驱动程序的完结带来了必定的费事,驱动程序首要要将SN74hc164驱动起来,然后才干对矩阵电路的16列进行操控。该矩阵电路的4个行引脚别离被接到S3C2410的GPG6,GPG7,GPG8,GPG9端口上,而且这四个端口被装备成中止源。无键按下时直接读为高电位,运用时经过SN74hc164芯片先将键盘的16列置低电位,任何一个键被按下,相应的行GPG端口就会有从高到低的电压跳变,然后触发一次中止。

3。2软件模块描绘

初始化部分。这部分包含硬件层和软件层上的初始化。在本例中,需求先对矩阵电路和SN74hc164芯片所运用到的GPIO端口作装备,以使CPU能够对它们进行操控和拜访。为了要将某个GPIO端口装备成输入输出或者是中止源,需求在对应的GPIO操控寄存器中设置正确的值,详细的值能够经过查阅S3C2410开发板手册来取得。比方,为了将GPB1设置成SN74hc164的输入端,需求将GPBCON这个操控字中2,3两位设置成二进制的01,为了将GPG6设置成电压低跳变中止源,需求将GPGCON中12,13两位设置成二进制的10。在完结了硬件初始化操作今后,便是软件层上的初始化了。首要将键盘中止处理函数注册到体系,然后设置好一个定时器结构,以便在中止发生时将其挂到内核的定时器行列中去,该定时器将触发对键盘的扫描操作。最终经过SN74hc164将矩阵电路的16列置零。

中止处理部分。如前所述,这部分软件应该完结的作业便是扫描特别键盘,确认哪个键被按下,而且拿到安稳的扫描码,然后调用内核导出函数handle_scancode。在这个运用中,该特别键盘的布局与PC规范键盘的布局比较相似,所以咱们直接将PC键盘上对应键的体系扫描码作为咱们特别键盘上各个键的扫描码,一起咱们将PC键盘驱动程序中扫描码到键码的转化函数pckbd_translate作为咱们的kbd_translate函数。

确认哪一个键被按下的算法如下。在中止到来时,咱们现已能够根据中止号确认被按下的键在哪一行,咱们还需求确认被按下的键在哪一列。为此,咱们先给串联的两个SN74hc164芯片送一个CLR信号,清零,然后送16个1,使得特别键盘的列均为高电位,此时咱们在键盘的行端口读到的都是高电位。在16个时钟脉冲下,给SN74hc164芯片送入1个0和15个1,使得0在每一列上都仅有呈现一次,于此一起在键盘行端口进行扫描。当被按下键地点列置0时,其地点行就会读到一个低电位。运用这种“走0法”,咱们就能够确认出键盘上哪个键被按下了。可是这种简略的扫描算法还不行,因为在这种类型的矩阵扫描键盘中,键的每次按下和抬起都会有10~20ms(这段时间的长短由硬件特性决议)的毛刺颤动存在,如图2所示,所以为了获取安稳的按键信息,有必要要想办法去掉这种颤动,才干防止将用户的一次按键误当作几回按键来处理。去毛刺的一种常见的办法是在有键盘中止抵达时,并不当即去扫描键盘,而是先等候一段时间,等越过毛刺颤动今后再去扫描键盘,其伪代码如下所示:

等候一段时间,越过颤动;

扫描键盘;

if键盘上没有键被按下

完毕回来;

if键盘上有键被按下

再次等候一段时间然后查看相同的键是否依然处于被按下状况;

if相同的键任然是按下

将读到的扫描码回来;

else

直接回来;

这种解决方案当然可行,可是它运用了忙等的办法去毛刺,在忙等期间,体系做不了任何有用的作业。这关于核算资源自身就很有限的嵌入式Linux体系来说,是一种奢华的糟蹋。本运用中,咱们规划了一种合适嵌入式体系的去毛刺解决方案,运用作用杰出。

因为Linux内核供给了定时器行列,所以咱们能够运用这种机制来防止忙等,前进体系的功用。当键盘上有键被按下时,键盘中止处理程序首要封闭中止源,进入轮询形式,将一个timerlist目标挂入定时器行列今后就完毕了。挂入内核的定时器准时地被触发,它所触发的函数完结以下一些作业:先对整个键盘上一切的键进行一次扫描,而且将扫描得到的成果保存到一个静态2维数组变量snap_shot_matrix[16][4]中。该变量描绘的是在本次键盘扫描的这个时间,键盘上一切键的按下状况。假如某个键没有被按下,即处于松开状况,那么将snap_shot_matrix中对应的值置为0,假如某个键处于按下状况,那么将snap_shot_matrix中对应的值作自增1操作,若该值在自增1今后大于某个预先指定的数,咱们就能够以为这是一个安稳值,而且将另一个巨细为16*4的2维数组变量current_matrix对应坐标中的值置1,不然置0。这个变量描绘的便是当时键盘上按键状况的安稳值了。也便是说咱们首要把在本次扫描中得到的采样数据作处理今后保存到snap_shot_matrix中,然后根据该变量中的值,过滤得到current_matrix,经过这样一个进程来做去毛刺处理。在得到了本次扫描的安稳值current_matrix今后,咱们将其与前次得到的安稳值previous_matrix作比较,然后确认与前次扫描时比较,此时键盘上的按键状况是否发生了改变,以及此时键盘上是否有键按下。假如发现键盘上没有任何键被按下,则翻开键盘中止,再次切回到中止形式。假如键盘上有键被按下,而且是不同于前次扫描到的被按下键,咱们马上调用按键处理函数process_key,它会调用键盘驱动中的上层函数handle_scancode。假如键盘上按下的键便是前次按下的那个键,咱们将递加一个计数器,当这个计数器到达某个指定值今后,咱们就发动所谓的Autorepeat功用,即用户一向按着某个键,驱动程序主动重复发生键盘输入。该计数器在被按下键发生改变时置0。可是只需键盘上依然有键处于被按下状况,咱们就将当时读到的键盘安稳值current_matrix拷贝到previous_matrix中去,而且再次将前面描绘的定时器目标挂到内核定时器行列中,过一段时间今后再次扫描整个键盘,直至键盘上没有键被按下。

4完毕语

跟着信息社会以及核算机软硬件技能的前进,嵌入式信息产品的规划和运用得到了敏捷的开展,需求为自己的嵌入式Linux体系增加特别键盘驱动的需求也越来越遍及。本文在介绍了Linux中键盘驱动程序的全体结构今后,以S3C2410开发板上的一个特别键盘为比如,要点描绘了在嵌入式Linux环境下,为特别键盘编写驱动程序时需求完结的作业,为相似的开发供给了一种思路和参阅。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/ruanjian/188546.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部