当前位置:首页 > 嵌入式 > 嵌入式软件
[导读]嵌入式Linux中基于Qt/Embedded的键盘接口设计

摘要:采用S3C2440处理器和嵌入式Linux操作系统,选择目前比较常用的Qt/Embedded作为图形界面的开发语言,设计了嵌入式系统中的键盘接口。在介绍硬件平台的基础上,给出了嵌入式Linux下键盘设备驱动程序的工作过程及实现方法,简单介绍了Qt/Embedded的架构和字符输入策略,详细设计了Qt键盘驱动插件和应用程序。实验表明,键盘驱动采用Qt的插件系统,具有更好的独立性和移植性。
关键词:嵌入式Linux;Qt/Embedded;键盘驱动;S3C2440

引言
    随着嵌入式系统的不断发展,特别是嵌入式处理器运算能力的不断增强,嵌入式系统被广泛应用于信息家电、移动通信、手持信息设备以及工业控制等众多领域。与此同时,用户对于嵌入式系统图形用户界面的需求也不断提高。嵌入式Linux作为一种流行的嵌入式系统平台,它所具备的稳定、高效、易裁剪、易移植、硬件支持广泛等优点,结合其源码开放的特征,使得Linux在嵌入式操作系统中的地位日益重要。Qt/Embedded是一个完整的自包含GUI和基于 Linux的嵌入式平台开发工具,因其面向对象、跨平台、界面设计更美观和友好而得到广泛的应用。Qt/Embedded具有客户/服务器模型,直接向帧缓冲写入数据,摒弃了X窗口系统,节省了内存。同时,将外部输入设备抽象为键盘和鼠标输入事件,底层接口支持键盘、GPM鼠标、触摸屏,以及用户自己定义的设备等。

1 硬件设计
    电路采用三星S3C2440处理器,实现了4×4矩阵键盘的输入。矩阵键盘使用了处理器的4个GPIO和4个中断,以中断方式获取键值,对应的中断引脚分别是EINT3、EINT9、EINT11、EINT13。GPIO引脚与矩阵键盘的行相连接作为输入端,中断引脚与矩阵键盘的列相连作为矩阵键盘的输出端。开始时GPIO端输出为低电平,当有按键被按下时,按键所在列输出低电平产生中断,这时可以判断按键所在的列。然后向每一行依次输入高电平,如果列的输出端由低电平变成高电平,则可以确定按键所在的行,这时键值被唯一锁定。具体电路如图1所示。

2 LinuX下键盘接口驱动
    键盘设备属于字符设备,键盘驱动应该符合字符设备驱动的编写模式。Linux采用内核模块机制,当系统运行的时候驱动程序可以以模块的形式动态地加载和卸载,既方便了驱动的调试,又缩短了开发周期。在驱动中必须实现static int_init my_kb_init(void)函数和stat-
ic void_exit my_kb_exit(void)函数。static int_init my_kb_init(void)函数在内核加载键盘驱动时被调用,注册模块为以后调用模块函数预先做准备,同时完成字符设备的注册,分配主设备号,设置中断类型,安装中断函数,并且将所有中断禁止。static void_exit my_kb_ exit(void)函数在卸载模块时被调用,用于撤销初始化函数所做的一切,否则在系统重新引导之前一些东西会残留在系统中,导致模块重新加载失败。


    键盘驱动中主要包括以下几个子模块:中断处理子模块、键盘扫描子模块、消抖处理和组合键子模块、重复按键子模块等。驱动工作流程如图2所示。


    按键的识别主要是在中断处理子模块中完成的。当系统有按键被按下时,驱动程序先关掉中断,然后扫描键盘,确定哪个键按下,键盘按下和抬起都有中断发生,这样可以为用户提供按下和抬起标志,以判断按键是单键按下还是多键齐按。在消抖处理和组合键子模块中,加入Linux内核定时器,键盘定时扫描,消除抖动得到稳定键值。重复按键子模块是根据Linux内部的定时器,设置自动重复开始延时和自动重复延时,键盘按下后根据延时来完成按键事件,键值存入队列供应用程序读取。[!--empirenews.page--]

3 Qt/Embedded键盘输入策略
3.1 Qt/Embedded架构简介
    Qt/Embedded Linux应用程序需要一个正在运行着的服务器应用或者是本身就是一个服务器应用程序。任何一个Qt/Embedded Linux应用程序都可以扮演服务器的角色。当多于一个应用程序运行的时候,应用程序作为客户端与服务器程序相连接。
    服务器进程和客户端进程有不同的分工:服务器进程管理着鼠标指针的处理、字符的输入和屏幕的输出。另外服务器还控制着屏幕光标的输出和屏幕保护程序。客户端进程完成所有应用程序的具体操作。一个QWSServer类的实例代表一个服务器应用,一个QWSClient类的实例代表着一个客户端应用。每一方面都有一些类完成各种操作。
    所有系统产生的事件包括键盘事件和鼠标事件都被传递到服务器应用中,然后服务器将这些事件分发到客户端应用中。
3.2 客户端/服务器的通信
    如图3所示,正在运行着的程序通过增加和删除窗口不断地改变屏幕的显示。服务器在对应的QWSWindow对象中维护着每一个顶层窗口的信息。每当服务器接收到一个事件时,它都会查询它的顶层窗口列表找到包含该事件位置的窗口。每一个窗口都有一个创建它们的客户端应用的ID,将这个ID返回给服务器。最后服务器将这个事件封装成一个QWSEvent类的实例,传递给相应的客户端。


    另外还可以通过QWSServer::KeyboardFilter类实现按键事件的全局的底层过滤器。这种方法可以实现电源管理中的一键挂起,而不用在所有的应用程序中都对这个按键事件进行过滤。
    如图4所示,服务器通过UNIX域套接字与客户端进行通信。客户端从服务器接收事件,这些事件通过重新实现QApplication的qwsEvent-Filter()函数可以被直接检索访问。


    客户端相互之间(和服务器)通过QCopChannel类通信。QCOP用于在多个通道间传送信息,是一个多对多的通信协议。每个通道用名字作为识别 ID,任何一个想要和它通信的通道都能监听它。QCOP协议既允许在相同的地址空间内的客户端之间进行通信,也允许在不同的进程的客户端之间进行通信。
3.3 字符输入层
    如图5所示,当一个服务器应用程序开始运行时使用Qt的插件系统加载键盘驱动,驱动是一个QWSKeyboardHandler类的实例。


    键盘驱动从设备接收键盘事件,并把事件封装成一个QWSEvent类的实例,然后把这个类传送给服务器。定制键盘可以通过子类QWSKeybo- ardHandler类创建一个键盘驱动插件来实现。默认的QKbdDriverFactory类将自动检测到这个插件然后把驱动加载到正在运行的服务器应用中。

4 键盘驱动插件的实现
    本文通过Qt的插件系统实现了矩阵键盘的接口驱动。插件是一种遵循一定规范的应用程序接口编写出来的程序。在现代计算机语言中,应用环境复杂多变,常常要面临着适应这样那样的未知需求的挑战,为了使程序设计语言具有良好的可扩展性,使之能够适应复杂的应用环境,同时也出于降低设计复杂性的考虑,采用插件机制是一个很不错的方法。通过采用插件系统,把扩展功能从框架中剥离出来,可以降低框架的复杂度,让框架更容易实现。扩展功能与框架之间以一种松耦合的方式集成,允许在保持接口不变的情况下,实现彼此的独立变化。
    Qt提供了两种插件:一种是高层的插件,用来扩展Qt自身,如自定义数据库驱动、图像格式、文本编解码器、自定义风格等;一种是底层的插件,用来扩展Qt应用程序。[!--empirenews.page--]
    一个键盘插件的实现,通常至少需要两个类:一个是插件封装器类,它实现了插件的通用API函数;另外一个是一个或多个处理器类,每个处理器类都实现了一种用于特殊类型插件的API。通过封装器类才能访问这些处理器类。下面是具体的实现过程:
    首先要实现一个自己的MyKeyDriverPlugin类,这个类继承了QKbdDriverPlugin类,需要重新实现QKbdDriverPlugin::keys()函数和QKbdDriverPlugin::create()函数。

    keys()函数返回一个键盘插件的键值,这个键值不能和其他的键值相冲突。create()函数返回一个给定键值的QWSKeyboardHandler派生类的实例。

    在.cpp文件的最后,必须添加一个下面这样的宏:Q_EXPORT_PLUGIN2(keyboard,MyKeyDriverPlugin)
    第一个参数项是目标库名字去除任意扩展符、前缀或者版本号之后的基本名。第二个参数则是插件的类名。
    第二个要实现的类是处理类MyKeyboardHandler,这个类需要继承QWSKeyboardHandler类。当键盘驱动捕获到键盘数据时,系统会通过套接字监听键盘信息,并在MykeyboardHandler::readKbdData()中对捕捉到的扫描数据进行处理并封装,然后向服务器端发送键盘事件。
    ①打开键盘设备并初始化,一般调用open()函数。

    ②监控键盘设备,调用QScoketNotifier监控键盘设备kbdFd。


    ③发生键盘事件时读取键盘事件,读取键盘事件后将键值、按下等信息翻译成Qt内部键盘事件的格式,并通过调用processKeyEvent将事件分发出去。

5 键盘插件在应用程序中的使用
    将键盘插件编译后生成一个libkeyboard.so的动态库,这个动态库的名字是由Q_EXPORT_PLUGIN2宏的第一个参数决定的。派生插件默认存储在标准插件目录下的子目录中,如果它们没有存储在正确的目录下Qt不会找到这些插件,所以要在使用的文件系统中创建Qt的标准插件目录。
    要想应用程序在启动的时候能够正确加载键盘插件还要设置嵌入式Linux系统中的环境变量:
    QWS_KEYBOARD=MyKeyHandler:/dev/kbd
    MyKeyHandler对应着key()函数中的键值,kbd是在/dev文件夹下的键盘设备文件。Qt应用程序开始运行后要根据 QWS_KEYBOARD这个环境变量创建一个MyKeyboardHandler类。窗口部件响应服务器分发的键盘事件还要重新实现如下函数。

}
 

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

Micro热插拔技术作为现代电子设备中常见的一种接口设计,其便捷性和灵活性得到了广泛应用。然而,关于Micro热插拔是否需要断电的问题,一直存在争议。本文将详细探讨Micro热插拔的原理、优缺点,以及在不同情况下是否需要...

关键字: Micro热插拔技术 现代电子设备 接口设计

刚入门嵌入式,选入门级RZ/G2L开发板,采用邮票孔形式封装了RZ/G2L核心板。

关键字: 开发板 嵌入式LINUX 嵌入式系统

在单片机应用系统中,常常需要人机对话,因而功能开关、拨码器、键盘、显示器和打印机等输入/输出设备就必不可少,本文将介绍一些外部设备及它们与单片机的接口技术。

关键字: 单片机 键盘接口 LED显示器接口

其一,是把系统所需的外设和单片机连接起来,使单片机系统能与外界进行信息交换。如通过键盘、A/D 转换器等外部设备向单片机送入数据、命令等有关信息,去控制单片机运行;通过显示器、发光二极管、打印机等设备把单片机处理的结果送...

关键字: 单片机 外部总线 接口设计

摘 要 :视频监控系统是计算机应用中的重要领域之一。数字化摄像头网络化之后,监控系统正在不断引入新的功能,为使现有监控系统能更好地应对复杂环境,满足不同监控要求,就需要追加新功能,在系统架构与设计上进行调整。因此,如何将...

关键字: 智能监控 系统架构 模块化设计 接口设计 数据传输 深度相机

整理自网络,排版:付斌 对嵌入式系统工程师及嵌入式硬件工程师而言,2020年将是振奋人心的一年。随着物联网应用的普及,MCU市场将再次繁荣。因此,市场上对嵌入式系统工程师人才的需求也将出现新高。这些都是底层编程领域中即将...

关键字: 嵌入式 软硬件 BSP 嵌入式LINUX

[导读] 前文分析了Linux设备驱动的驱动模型,本文来聊聊Platform_driver/Platform_device这个类。做嵌入式Linux的驱动,这个也是绕不开的,所以来学习分析总结一下。 阅读本文,建议先读:...

关键字: DEVICE PLATFORM 嵌入式LINUX LINUX驱动

随着Internet的飞速发展,网络应用越来越广泛,对各种工业控制设备的网络功能要求也越来越高。当前的要求是希望工业控制设备能够支持TCP/IP以及其它Internet协议,从而能够通过用户熟悉

关键字: 区块链 应用程序 嵌入式系统 嵌入式LINUX

推荐语 最近在充电,没来得及输出笔记。本次先给大家带来一位前辈的嵌入式Linux学习经验及一些学习资料清单,跟着大佬走不迷路。这份资料清单有点长。。。 下转原文: 嵌入式 Arm Linux 入门必读书籍推荐 前段时间有...

关键字: 嵌入式LINUX 内核 KERNEL 命令行

开号两月有余,将推送的文章做些总结方便阅读。文章数量还不多,但每天文章都是非常认真撰写的,文中所含观点大都是工作多年的经验总结,现在无偿分享给朋友们,或许能帮助到朋友们。 之一:数字滤波器系列,建议深度阅读,嵌入式开发进...

关键字: BSP U-BOOT 嵌入式LINUX ROOT
关闭
关闭