嵌入式用户界面(通用7篇)
嵌入式用户界面 篇1
随着信息技术的发展,嵌入式设备越来越多地走进人们的日常生活。MPlayer是一款可在各主流操作系统上使用的多媒体播放器,也支持嵌入式Linux平台。它是一款功能强大的多媒体播放器,支持所有主流的多媒体文件格式。美中不足的是,它的操作是基于命令行界面的,在嵌入式Linux平台下还没有一款图形用户界面,操作起来十分不方便。针对这个问题,决定为其开发一款基于Qt框架的图形用户界面[1,2]。Qt是一个跨平台的C++应用程序开发框架,广泛用于开发GUI程序。在基于S3C6410微处理器和嵌入式Linux操作系统的软硬件平台上设计和实现了一款GUI软件,该GUI软件可以实现对MPlayer常用的控制功能,基本满足了使用需要。本文即阐述了这款图形用户界面的设计和实现过程。
1 Qt编程相关技术
1.1 图形用户界面
Qt的图形用户界面的基础是QWidget。Qt中所有类型的GUI组件如按钮、标签、滑动条等都派生自QWidget,而QWidget本身则为QObject的子类。Widget负责接收鼠标、键盘、触摸屏和来自窗口系统的其他事件,并在屏幕上描绘了自身显示。每一个GUI组件都是一个Widget,Widget还可以作为容器,在其内包含其他Widget。
QWidget不是一个抽象类型,并且可以被放置在一个已存在的用户界面中。若是Widget没有指定父Widget,当它显示时就是一个独立的视窗或是一个顶层Widget。Qt提供一种托管机制,当Widget于创建时指定父对象,就可把自己的生命周期交给上层对象管理,当上层对象被释放时,自己也被释放,确保对象不再使用时都会被删除。
1.2 信号与槽
信号与槽机制[3]是Qt的核心机制,同时也是Qt特有的机制。Qt利用信号与槽(signals/slots)机制取代传统的callback来进行对象之间的沟通。当操作事件发生的时候,对象会发提交一个信号(signal);而槽(slot)则是一个函数接受特定信号并且运行槽本身设置的动作。信号与槽之间,则通过QObject的静态方法connect来链接。信号在任何运行点上皆可发射,甚至可以在槽里再发射另一个信号,信号与槽的链接不限定为一对一的链接,一个信号可以链接到多个槽或多个信号链接到同一个槽,甚至信号也可连接到信号。
1.3 布局管理
布局管理类型[4]用于描述一个应用程序的用户界面中的Widget是如何放置的。当视窗缩放时,布局管理器会自动调整Widget的大小、位置或是字号,确保它们相对的排列和用户界面整体仍然保有可用性。
Qt自带的布局管理类型有:QHBox Layout、QVBox Layout和QGrid Layout。这些类型继承自QLayout,但QLayout非继承自QWidget而是直接源于QObject。它们负责Widget的几何管理。想要创建更复杂的布局管理,可以继承QLayout来自定义布局管理类型。
QHBox Layout:配置Widget成横向一列;
QVBox Layout:配置Widget成垂直一行;
QGrid Layout:配置Widget在平面网格。
2 开发平台的搭建
本文的研究目的是设计实现一款嵌入式Linux平台[5,6]下的MPlayer图形用户界面,需要主机PC平台和嵌入式开发板平台。主机平台上安装的操作系统是Ubuntu 12.04,这是一款主流的GNU/Linux操作系统。开发软件为Qt Creator,它是Qt官方提供的一款轻量级的Qt/C++IDE开发环境。嵌入式开发板平台采用ArmLinux体系结构,硬件平台以S3C6410处理器[2]为核心,操作系统版本为Linux-3.0.1。要想在嵌入式平台上运行Qt程序,必须将Qt库移植到嵌入式平台中。在Qt官网上下载Qt libraries源码包,按如下配置选项对Qt Libraries进行配置:
配置完成后进行编译,这样编译出来的就是ArmLinux平台下支持触摸屏的Qt运行库。将编译完成后的Qt库放入嵌入式开发板的文件系统中,并将Qt的环境变量添加到系统环境变量中。至此,开发平台搭建成功。
3 图形用户界面的实现
GUI程序启动后显示主界面,主界面按功能分为两个部分:播放显示区和播放控制区,其中播放显示区占了屏幕的绝大部分。播放控制区内分布着时间显示标签、播放进度条、音量调节条和所有的播放控制按钮。主界面启动后,当按下按钮或拖动滑动条时,就会实现相应的功能。
3.1 主界面
主界面类main Widget继承自QWidget,利用构造函数对类对象进行初始化。主界面的实现原理是在一个父Widget上添加按钮、标签、滑动条等部件作为子Widget。类main Widget的构造函数部分代码如下:
3.2 选择文件功能
播放开始前必须先选择播放文件。当还没有选择好播放文件时,按下开始按钮,会打开选择文件对话框。选择文件对话框继承自QDialog,对话框上的主要部件为播放文件列表、“添加”和“移除”按钮。点击“添加”按钮会进入文件目录选择文件,选中的文件会添加到播放文件列表中,点击“移除”按钮会移除播放列表中被选中的文件。双击播放列表中的一个文件或选中一个文件后按下对话框上的播放按钮,就会开始播放。选择文件对话框如图1所示。
3.3 播放文件功能
播放文件时,图形用户界面程序通过新建一个QProcess进程来调用作为后端的MPlayer进行播放。QProcess类可以启动一个外部程序并与之进行通信。MPlayer[7]启动后,QProcess进程通过标准输入输出与之进行通信交互。播放文件功能的实现代码为
在播放进行中,QProcess可以通过标准输入对MPlayer发出指令,也可以通过标准输出获取播放文件的信息。用户可以通过图形用户界面上的各个功能按钮实现暂停/播放、停止、快进(退)、上(下)一个、播放列表的显示(隐藏)和音量调节等功能。按钮控制的实现原理是信号与槽机制,点击按钮会触发此按钮的clicked()信号,clicked()信号被触发后,与之链接的槽函数会被执行,只要在槽函数中加入相应的功能代码,就会实现相应的控制功能。下面以快进功能为例,介绍按钮功能的实现方法。
在定义快进按钮的时候链接快进按钮的clicked()信号和快进功能槽函数forward():
connect(forward Button,SIGNAL(clicked()),this,SLOT(forward()));
MPlayer快进10 s的命令为“seek 10 0”,要想实现快进10 s功能,就要在槽函数forward()中通过QProcess将这条命令发送给MPlayer。QProcess通过write()函数在标准输入发送命令。forward()函数源码如下:
3.4 显示时间功能
GUI程序不仅能通过QProcess向MPlayer写入命令,还能通过QProcess获取播放文件的媒体信息。在创建播放进程play Process的同时,将play Process的readyRead-Standard Output()信号与槽函数dataRecieve()链接。playProcess进程通过标准输入向MPlayer发送获取媒体信息的命令,MPlayer接收命令后会将媒体信息返回到标准输出中,当标准输出中的数据信息可读时,会触发play Process的readyRead Standard Output()信号,与其关联的槽函数dataRecieve()会被执行。dataRecieve()读取标准输出中的数据信息后,经过转化显示在GUI界面上。利用这个原理可以实现当前播放时间和文件时间长度的显示。
获取文件时长的命令为“get_time_length”,当playProcess启动MPlayer以后,随即通过play Process->write("get_time_lengthn")指令向MPlayer发送命令获取时长。MPlayer返回的时长信息以“ANS_LENGTH”开头,随后为以秒为单位的时间数据。槽函数dataRecieve()读取信息后会把以秒为单位的时间数据转化成“分:秒”的形式显示在GUI界面上。
当前时间的显示需要每秒更新1次。通过在MPlayer启动时建立1个QTimer类定时器,定时时间为1 s。每隔1 s定时器就会触发一次时间截止信号timeout(),与timeout()信号链接的槽函数timeok()会让play Process发送一条获取当前时间的指令“get_time_pos”给MPlayer,返回的当前时间以“ANS_TIME_POSITION”开头。这样,dataRecieve()就能每隔1秒更新1次GUI界面上当前时间标签。
3.5 中文字体支持
首先将文泉驿字体wenquanyi_120_50.qpf放到开发板上Qt目录中的lib/fonts文件夹下,“120”表示是12号字体,“50”表示细体。有了字体文件后,就可以在GUI界面的主程序中选择使用中文字体,其实现代码为:
4 软件运行测试
全部程序编写完成以后,首先进行qmake让其自动生成Makefile文件,再进行make就生成了开发板上的可执行文件,将可执行文件和图标文件一起放到开发板的相应文件夹下。经过在开发板平台上的运行测试,结果表明,该图形用户界面在嵌入式Linux平台上能稳定运行,各项设计的功能都能实现且性能良好。运行测试效果图如图2所示。
5 结束语
本文设计并实现了一款嵌入式Linux平台下的MPlayer图形用户界面,该图形用户界面基于Qt框架开发,利用了MPlayer的slave模式并通过QProcess进程控制MPlayer,实现了选择文件、播放控制等常用功能,成功地解决了MPlayer在嵌入式Linux平台下没有图形用户界面的问题,具有很高的实用性。经过测试,该界面程序运行稳定、操作良好,满足了设计要求。
摘要:针对多媒体播放器MPlayer在嵌入式Linux平台上没有图形用户界面的现状,为其设计了一款基于Qt的图形用户界面。首先介绍了Qt编程相关知识,然后详细介绍了图形用户界面软件的设计和实现。该图形用户界面具有选择文件、播放控制、时间显示、音量调节等功能。实验结果表明,该图形用户界面可以稳定地运行在嵌入式Linux平台下,且所设计的功能都能很好地实现。
关键词:嵌入式Linux,MPlayer,Qt,图形用户界面
参考文献
[1]于帮伟,邓华秋.基于Qt/Embedded的嵌入式数字监控系统控制界面的实现[J].电视技术,2011,35(24):25-28.
[2]雷丰中,刘鹏.基于S3C6410的多媒体系统设计[J].电视技术,2011,35(11):24-27.
[3]Qt Project Group.Qt开发官方参考文档[EB/OL].[2013-05-25].http://qt-project.org/doc/qt-4.8/.
[4]蔡志明,卢传富,李立夏.精通Qt4编程[M].北京:电子工业出版社,2011.
[5]吴燕燕.基于ARM9平台上Qt/Embedded的移植与开发[J].液晶与显示,2013,28(2):261-264.
[6]闵华松,王娜,谭金鑫.嵌入式多媒体播放器通用控制系统设计与实现[J].计算机工程与科学,2009,31(2):153-155.
[7]MPlayer-电影播放器[EB/OL].[2013-05-25].http://www.mplayerhq.hu.
嵌入式用户界面 篇2
1层次状态机
1.1层次状态机的相关概念
层次状态机(Hierarchical State Machine)是一种应用非常广泛的软件设计模式。它是进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件[1]。在面向对象的软件系统中,一个对象无论多么简单或者多么复杂,都必然会经历一个从开始创建到最终消亡的完整过程,这通常被称为对象的生命周期。一般说来,对象在其生命期内是不可能完全孤立的,它必须通过发送消息来影响其它对象,或者通过接受消息来改变自身。
嵌入式系统具有明显的消息驱动特点,其中较大的挑战就是如何准确地对消息进行快速反应,并执行相对应的正确的代码。这种快速准确地反映取决于消息本身以及消息所处于的上下文环境,消息的序列直接驱动和构成了系统的运作。层次状态机正是十分适合设计这种消息驱动系统的形式方法[2]。它主要用来描述对象、子系统、系统的生命周期。通过层次状态机可以了解到一个对象能到达的所有状态以及对象收到的事件对对象状态的影响等。状态机指定对象的行为以及不同状态行为的差异。同时,它还能说明事件是如何改变一个对象的状态。因此它非常适用于嵌入式软件开发。为便于理解,下面简单给出层次状态机中的一些相关概念。
状态:状态是对象的生命周期中满足某种条件,执行某些动作或等待某些事件发生的一个阶段。
事件:事件是一个在时空中显示出现的特定现象或信号,它可以触发状态转换。
转换:转换是从一个状态结点到另一个状态结点的移动。
行为继承:状态嵌套允许子状态继承来自超状态中的某些行为操作,因此它被称为行为继承[3]。
2.2层次状态机的特点
层次状态机在经典有限状态机的基础上引入了层次式状态。状态层次嵌套的主要特性来自抽象与层次的结合。这是一种降低复杂性的传统途径,也就是软件中的继承。在面向对象中,类继承概念描述了类和对象之间的关系。类继承描述在类中的is-a关系。而在嵌套状态中,只需用is-in状态关系代替is-a类关系,即它们是等同的分类法[3]。在实现中行为继承有意地把自己仅限于被动事件处理器,即它处理事件需要外部的驱动[4]。并且它也不仅仅 依靠于外部驱动,同时也取决于系统当前状态,一个对象的行为可以被分解到若干个状态中,当某个状态接收到外部激励,其中的某些行为随之发生,状态随之传递,用户的需求亦得到满足,若当前状态的行为无法满足当前激励的需求时,当前状态就会返回到它的超状态中去寻求帮助,这样的行为继承方式可以使代码更加简洁,增强了复用性,节省了更多的存储空间。基本结构如图1所示。
图中系统开启初始进入状态S1,在S1状态下接收到触发事件T1,继而转换到它的子状态S11,在S11状态下,通过触发不同的事件T2或T4, 它会转换到同级子状态S12或发生自转换保持现在的状态。而状态S12在接收到触发事件T3或T5会分别转换回到S11状态或退回到其父状态S1,直至最终关闭系统退出后状态结束。该图描述了最简单的系统状态在外部事件触发下发生的基本状态转换。用户按照各自特别的需求触发不同的事件,系统接收事件后基于不同的状态产生不同的功能以满足用户需要。
2电子监控器录制控制功能层次状态模型
2.1系统部分功能描述
监控器录制控制功能首先由用户手动设置起始时间和结束时间,而后进入自动录制状态,计时器到起始和结束时间后自动进行录制,在此之前可以进行时间的校准功能。具体层次状态模型见图2。系统包括调节(regulate)、选择(select)、开关(on/off)、用于设定时钟以及自动开始-停止定时器的设定(set)、用于自动录制的自动(auto)、以及用于时间增量范围控制的定时(timed)等按键。图中许多事件与按下的相同名称的按钮相互对应,还有一些按钮具有切换功能,由于仅借此录制功能讨论层次状态机的设计方法,故并未给出全部功能按键及其状态表示。在正常状态下,界面显示系统当前时间,文字信息窗口显示“正常”信息。随时间的变化,系统所显示的时间也在不断的改变,当需要进行时间设定时,在正常状态下按下开关键后,进入手动(manual)调节状态,此时系统可进行多种设定,按动调节(regulate)按键系统进入时间校对设定状态,此时信息窗口显示“日期”信息,日期天数显示部分闪动,按动上升(up)键时天数进行加1操作,操作完成后若按动选择(select)键则进入调时状态,若按动设定(set)键则保存调整后的数据进入正常显示状态,调时状态显示“调时”信息,时钟数值显示闪动,按动上升键时调整时钟显示数值,同样按动设定键返回到正常状态,按动选择键进入调分状态,调分状态显示“调分”信息,分钟数值显示闪动,按动上升键时调整分钟的显示数值,在0~59的范围内,按动设定键返回到正常状态。按动调节键则跳回到初始手动状态,继而再接收相应触发进入录制初始和终止时间设定、监控选择、超时状态显示、自动录制等功能状态。设置方法大致相同,其中终止时间状态图部分与初始时间功能设置类似,因而未全部画出。
2.2状态结构分析及实现
层次式状态包含许多行为,并且状态之间彼此存在数据链接以表达其状态嵌套关系,它能够提供行为以及通过返回超状态提供急需的结构链接。本例中画出了十九个状态,但并未给出系统的全部状态。现以时间设定状态结构说明层次状态方法的程序实现。系统上电初始进入手动状态,它即为系统的父状态或超状态,其它各子状态由此跃迁。每进入一个状态首先要进行该状态的初始化工作,系统需要定义进入退出及初始化动作信号enum{Q_ENTRY_SIG = 1,Q_EXIT_SIG,Q_INIT_SIG,Q_USER_SIG},状态处理器可以用一般的switch语句规定适当的用例来处理这些信号,可以自由地执行对应于这些信号的任何动作。但它不应在进入/退出动作中进行任何状态转换;反之,它应总是调用Q_INIT()宏,以指明对应于Q_INIT_SIG信号的初始直接子状态。其中初始化函数的宏定义为#define Q_INIT(target) (((QHsm*)me)->state = (QState)(target)),而在接收到状态转换信号即触发事件enum{H_S_SIG = USER_SIG,REGULATE_SIG,SELECT_SIG,SET_SIG,UP_SIG,AUTO_SIG,TIMED_SIG,TIMEOUT_SIG}中的信号时,完成当前要求动作,而后开始调用状态转换函数Q_TRAN(target)针对不同信号进入不同状态,其中转换函数定义#define Q_TRAN(target) QHsmTran((QHsm *)me, (QState)(target)),其中若接收到UP_SIG信号,状态并未发生跳转,称为自转换。图中不同的状态接收不同的信号后执行例如数值加1、与目标时刻值比较、更新显示当前时间等一系列操作,若该状态下完成既定操作且不需要状态转换,则最后返回0表达操作成功;若当前操作完成且需要进入下一状态,则调用状态转换函数切换状态,最后返回0;若在当前状态下用户操作未得到满足,则退回到其父状态下重复执行,即返回指向上一层次状态函数的指针。以调时状态函数程序为例:
以上简要介绍了层次状态方法在嵌入式用户界面控制程序设计中的关键要点:诸如构造系统中的各种状态、建立状态之间的层次嵌套链接、定义不同状态层次中的行为、以及状态转换和状态触发信号枚举、行为继承方法等等。通过状态嵌套,允许子状态只定义与超状态不同的行为,促进了行为的共享和重用,因此,行为继承也是层次状态机方法的核心。
4结束语
嵌入式系统中的用户界面具有典型的反应式系统特点,本文通过具体实例阐述了层次状态机的构造方法,并将它应用到嵌入式系统用户界面软件程序设计中,讨论了行为继承的实现方法,与面向对象中的类继承思想有相似之处,但由于C++语言自身的局限性[5],考虑到某些实时性能要求很高的硬实时系统中C语言的实时性能更高一些,因此本文采用了C语言来实现了其行为继承特性。在嵌入式软件设计中恰当的使用该方法可以使编程更加简化,层次更加分明[6]。减少代码占用空间,提高系统的实时性能。
参考文献
[1]Miro,Semak.Paul montgomery,state-oriented programming.Embedded Systeme Programming.2002,(6):22~43
[2]李润博,李明树,基于状态机的UML行为继承关系.计算机科学,2004,(31):16~19
[3]何伟,金远平,金鑫,层次状态机可复用软件框架的设计与应用.计算机应用与软件,2007,(10):34~36
[4]吉峰,白瑞林,基于UML和μC/OS-II的嵌入式系统设计.微计算机应用,2005,26(04):495~498
[5]Miro.Semak.the object-oriented nature of the behavioral abstractions.C/C++Users Journal.2003,(5).
嵌入式数控系统人机界面开发 篇3
关键词:人机界面,ARM,Linux,Qt/Embedded,交叉编译
0 引言
数控系统中一个重要组成部分就是优秀的人机界面模块。数控系统中, 应用程序是特定的, 要求编译工具必须定制;硬件资源有其有限性、专用性的特点, 要合理分配和管理;人机交互的方式上, 需要设计有针对性的交互软件。
本文就高性能处理器S3C6410, 利用开源嵌入式Linux操作系统, 对数控系统中人机交互系统进行了一定研究及开发, 主要完成了嵌入式UI开发环境的搭建、输入输出设备的驱动移植、人机交互界面的设计, 其中UI开发环境的搭建又包括两方面内容:PC开发环境搭建, 即PC主机上交叉编译环境及Qt开发环境的建立;嵌入式系统运行环境搭建, 即开发板上内核移植、文件系统、Qt应用库文件及环境变量配置等内容。
本设计主要在操作系统层、用户程序层进行论述, 对嵌入式操作系统移植、文件系统制作、驱动程序加载等方面做了一定的分析与实践。同时基于硬件及操作系统环境将Qt库移植到开发板上, 然后在Qt库的基础上设计与实现交互程序, 如图1所示。
其中作为软件载体的UT-S3C6410目标板为基于ARM内核技术的运算和信息处理平台。嵌入式Linux操作系统则以其精简、稳定、开源等诸多优点, 在顺利运行Qt程序的同时使得开发过程简便许多。最终搭建的系统最突出的特点在于其可移植性强、开放性强。
1 PC开发环境搭建
设计的主要开发任务是在PC主机上完成的, 而嵌入式平台仅是目标测试平台。PC主机上的开发环境主要包括交叉编译工具和Qt开发环境。为了对嵌入式系统进行交叉编译, 并考虑到兼容性等问题, 在PC主机上安装Linux操作系统 (此为Ubuntu10.10) , 主要的搭建工作都在Linux环境下完成。
交叉编译即一种计算机环境中运行的编译程序编译出在另外一种环境下运行的代码的编译过程。要实现针对特定两种计算机的交叉编译, 特制的交叉编译工具必不可少。建立针对ARM的交叉编译链, 与其他的体系结构相类似, 过程大致有以下几个步骤[1]:
(1) 下载源文件 (包括binutils、gcc、glibc、linux kernel) 、补丁和建立编译的目录
(2) 建立内核头文件
(3) 建立二进制工具 (binutils)
(4) 建立初始编译器 (bootstrap gcc)
(5) 建立c库 (glibc)
(6) 建立全套编译器 (full gcc)
通过交叉编译工具制作得到合适的编译工具之后, 还需要在PC主机Linux系统下安装该编译工具并修改环境变量使之生效, 可以使用export指令查看添加是否成功。
完成交叉编译工具的安装之后, 就可以开始安装需要使用到的开发工具了, 本设计主要的开发工具为开源的Qt界面开发套件。Qt工具的安装包括了Qt Creator、Qt Designer和Qt/Embedded的安装, 其中Qt/Embedded的编译比较复杂, 但它提供了将应用程序使用于目标嵌入式平台的编译工具和必要支持库, 所以必须在主机上安装。
首先进入主机工作目录, 在Linux终端下修改使用的交叉编译工具, 然后对Qt/Embedded的源代码进行交叉编译:
2 嵌入式运行环境搭建
如图2所示, 一个完整的嵌入式Linux系统组成包括:bootloader、boot parameters、kernel、root filesystem。嵌入式运行环境的搭建包括内核配置、根文件系统制作、库文件移植等内容。嵌入式系统上电启动直至进入内核文件系统的过程中, 我们从启动装载程序 (bootloader) 开始逐一搭建。
嵌入式系统运行平台千差万别, 必须要使用适合于自身平台的内核及工具软件。本设计中建立开发环境使用到的部分工具如下[2]:
(1) 交叉编译器:cross-4.2.2-eabi
(2) 内核版本:linux2.6.28
(3) Bootloader版本:u-boot-1.1.6
(4) 根文件系统:yaffs2
Bootloader代码是芯片复位后进入操作系统之前执行的一段代码, 主要用于完成由硬件启动到操作系统启动的过渡, 从而为操作系统提供基本的运行环境, 如初始化CPU、堆栈、存储器系统等, 其功能类似于PC机的BIOS程序, 本设计中选用比较流行的u-boot版本。而Linux从技术上来说是一个内核 (kernel) , 提供硬件抽象层、磁盘及文件系统控制、多任务等功能, 向外部提供了对计算机设备的核心管理调用。Linux是开源的, 其内核源码可以在www.kernel.org网站上下载到。
制作适用于目标平台的bootloader和kernel同样需要使用到之前安装的交叉编译工具。内核制作时, 可根据自身平台的资源和应用要求修改内核配置参数 (本设计主要须添加LCD) 。最后将编译得到的二进制映像文件烧写到目标平台中。
之后还须制作必要的根文件系统。文件系统是包括在一个磁盘 (包括光盘、软盘、闪盘及其它存储设备) 或分区的目录结构[3]。Linux引入了虚拟文件系统VFS (Virtual File System) , 为各类文件系统提供一个统一的操作界面和应用编程接口, 它将低层数据结构映射到高层数据结构, 决定目录项中存储文件的哪些信息等。Linux启动时, 第一个必须挂载的是根文件系统, 之后可以自动或手动挂载其他的文件系统。
通过借助Busybox工具可以完成文件系统的制作, 大致步骤如下:
(1) 配置Busybox, 配置制作的文件系统
(2) 编译Busy Box, 生成bin、sbin、linuxrc文件夹
(3) 创建文件系统其它目录 (boot、dev、etc、home、lib、mnt、proc、root、sys、tmp、var、usr)
(4) 建立、复制文件系统所需的文件 (包括console和null节点文件、fstab和inittab文件、rc S文件)
(5) 复制lib库文件, 完成文件系统制作
制作完成文件系统之后还须将文件系统烧写到目标平台的存储设备内, 并设置启动参数使之开机后能自动加载该文件系统。
最后需要将程序在目标平台运行必要的支持库文件下载到目标平台中。本设计中将编译好的tslib库和Qt Embedded-arm下/lib、/plugin文件夹下载到目标平台文件系统相同路径下, 同时修改目标平台的环境变量, 包括库链接路径、触摸屏设备、字体文件等。
3 Qt交互界面设计
Qt/Embedded是著名的Qt库开发商Troll Tech发布的面向嵌入式系统的Qt版本。同样基于客户/服务器体系结构, Qt/Embedded延续了Qt在X上的强大功能, 在底层摒弃了X lib, 针对高端嵌入式图形领域的应用而设计, 仅采用Framebuffer作为底层图形接口, 支持键盘、GPM鼠标、触摸屏以及用户自定义的设备等。Frame Buffer是出现在Linux 2.2.xx内核当中的一种驱动程序接口, 而Qt/Embedded就是采用Framebuffer作为底层图形接口的。
Qt包含了许多支持嵌入式系统开发的工具, 其中有两个完全集成在一起实用工具:qmake和Qt designer (图形设计器) [4]。qmake是一个为编译Qt/Embedded库和应用而提供的Makefile生成器。它能够根据一个工程文件 (.pro) 产生不同平台下的Makefile文件。qmake支持跨平台开发和影子生成, 易于在不同的配置之间切换。Qt图形设计器可以使开发者可视化地设计对话框而不需编写代码, 图3所示为Qt开发流程图。
如图4所示, 信号和插槽机制是Qt的核心机制[5]。信号和插槽是Qt自行定义的一种通信机制, 它独立于标准的C/C++语言, 因此要正确地处理信号和插槽, 必须借助一个称为moc (Meta Object Compiler) 的Qt工具, 该工具是一个C++预处理程序, 它为高层次的事件处理自动生成所需要的附加代码。所谓GUI就是要对用户的动作做出响应, 程序中必须把事件和相关代码联系起来, 这样才能对事件做出响应。信号与插槽机制则是一种强有力的对象间通信机制, 完全可以取代原始的回调和消息映射机制。在Qt中信号和插槽取代了函数地址指针, 使得通信程序更为简洁明了, 而且不会像回调函数那样产生core dumps。
一般情况下, 数控系统人机界面需要实现对特定类型文件的读取, 将其以图形形式显示, 并且能够提供基本图形来组建比较复杂的图形来满足用户的加工需求。同时, 通过交互界面, 数控切割机的运行参数情况可以由用户来设置保存以及实时显示。针对这些基本需求, 如图5所示, 本设计中在主界面下创建4个子界面入口, 分别为:
文件导入:该子界面下可以选择打开指定格式的文档, 将文档中指定的图形在绘图区域绘制出来, 并提供了运行管理界面的入口;
图形选择:此界面提供直线、弧线、矩形等六种基本图形作为构图元素, 可以设置这些基本图形的参数来绘制所需要的图形, 也提供了运行界面的入口;
参数设置:数控系统中所需设置的参数众多, 此界面中罗列了三块十余个可设置参数, 并可以将设置好的参数保存, 下次启动时将自动载入保存过的参数设置;
运行管理:此界面主要设计用来启停数控切割机的运行, 目前为对模拟运行的操作, 其中将部分参数显示出来, 并将所要切割的图形显示出来, 返回显示走线过程中当前坐标的位置, 如图6所示。
4 结束语
本文在ARM11高性能处理器的基础上, 使用嵌入式Linux操作系统平台, 详细地阐述了嵌入式开发平台的构建过程, 包括交叉编译环境、PC主机平台、嵌入式应用平台和嵌入式应用程序支持库等。最后依靠Qt/Embedded工具, 初步完成了一款针对数控系统的人机界面的实现。
参考文献
嵌入式用户界面 篇4
Linux自出现以来,以其开放源代码、较好的网络性能、精简高效的内核、较高的可定制性、支持多种体系结构等特性,被广泛地应用于嵌入式领域。在嵌入式领域中,可靠性被提高到了最重要的位置。而驱动程序是影响系统可靠性的最大隐患。Stanford大学的一项针对Linux内核的研究显示驱动程序出现BUG的频率比内核中其它部分的代码高出2~7倍[1]。传统的驱动程序与操作系统内核同驻于系统地址空间,拥有内核的所有权限,一旦驱动程序出现BUG,可能导致整个系统崩溃。在提高系统可靠性方面,目前已有的研究都专注于通过把有错误的设备驱动程序与内核隔离[2]。然而,这些研究都忽略了驱动程序可靠性问题中最重要的一个方面:在内核态编程要比在用户态编程困难得多,由于难以调试,因此也更容易出现未知的BUG,导致系统可靠性下降。
本文基于ARM平台,设计并实现了DM9000网卡的用户态驱动程序。与传统的网卡驱动程序相比,本设计由于将大部分代码外移到用户空间,从而大大提高了系统可靠性,同时也有着良好的性能,并且与现有的Linux内核相兼容。
1 用户态驱动程序体系结构
用户态驱动意味着将驱动程序代码转移到用户态运行,从而达到与内核地址空间隔离,提高系统可靠性的目的。目前对用户态驱动的研究主要有微内核系统和微软的UMDF[3]。这两种方法都无法在嵌入式Linux系统中实现。Microdriver[4,5]试图在传统内核态驱动和用户态驱动之间进行折衷,将一部分代码留在内核态以获得性能及兼容性。
Microdriver是性能和可靠性的折中方案,它根据性能相关和优先级分离驱动程序代码。Microdriver将传统的内核态驱动程序依据性能相关与否以及优先级,分离为运行于内核态的k-driver和运行于用户态的u-driver两个部分。它的体系结构如图1所示。其中实线是性能攸关代码执行路径,虚线是性能无关代码执行路径。
设备驱动的内核部分k-driver包括驱动中性能攸关和经常使用的功能模块,如中断处理和一些性能有关操作(如发送接收网络报文),用户态部分u-driver用单独的进程实现,供内核态模块调用。这两个模块一起提供了完整的传统驱动程序的功能。Microdriver的最大特点是与传统操作系统的体系结构兼容。
2 DM9000网卡用户态驱动的实现
综合性能、兼容性等因素,这里借鉴Microdriver的设计思想来实现DM9000网卡在ARM平台的用户态驱动。
2.1 功能模块划分
本设计根据需要划分为k-driver、u-driver、k-mod、u-lib四个模块,对每个模块介绍如下:
(1) k-driver,包括性能相关的热点代码和数据通道,例如输入/输出、中断处理函数、一些高优先级函数(软中断、tasklet和工作队列)等。k-driver以Linux的可加载动态模块(Loadable Kernel Module)的方式运行于内核态,以保证高性能。
(2) u-driver,包括驱动程序中一些与性能无关的非关键操作以及一些优先级较低的代码,例如设备初始化、设备配置、设备控制、错误处理等。u-driver以一个普通进程的形式运行于用户态,以保证充分的故障隔离。
(3) k-mod,注册为一个设备驱动程序并实现了字符设备接口用来与u-lib通信。它实现的功能包括与u-driver进行通信、追踪k-driver与u-driver间共享的数据结构等。
(4) u-lib,实现为一个链接到u-driver的多线程库,它面向u-driver的接口与k-mod面向内核的接口类似。它实现的功能包括请求k-driver提供服务、执行来自k-mod的函数调用请求等。
2.2 I/O访问方式
用户态的u-driver需要能够直接访问DM9000的寄存器或I/O端口。在传统的X86架构处理器平台,存在着两个相关的系统调用:iopl()和ioperm(),通过这两个系统调用即可允许调用进程获得访问设备对应的I/O端口或寄存器的权限。但在嵌入式系统常用的ARM平台,不存在这两个系统调用,但是,可以将设备的寄存器或端口映射到某段物理内存空间上。/dev/mem是物理内存的全映像[6],可以用来访问物理内存,那么只需将DM9000网卡的寄存器或内存映射到物理地址空间,根据映射的地址,使用mmap()系统调用,u-driver可以直接访问和操作DM9000网卡的寄存器[7]。
2.3 通信方案
k-driver和u-driver必须协同工作才能完成传统的内核态驱动的功能。内核态和用户态的运行库提供了这一服务。运行于内核态的k-mod注册为一个设备驱动程序并实现了字符设备接口。运行于用户态的u-lib实现为一个链接到k-driver的多线程库。本设计采用ioctl()系统调用机制,实现k-mod和u-lib之间的通信。图2为本设计所采用的通信方案流程图,其中实线为数据路径,虚线为控制路径。
k-driver调用u-driver中的函数时,通过调用k-mod来传送请求给u-driver,u-driver预分配一个缓冲区来接收数据,缓冲区的大小设置为u-driver与k-driver能传输的数据的上限,接下来,k-mod激活在内核中等待的主线程,复制数据到u-driver地址空间中的缓冲区,并通知u-lib调用u-driver中正确的函数。收到来自k-driver的请求之后,u-lib发送请求给一个工作线程,并回复内核等待接下来的请求。
u-driver也可以向下调用,不论是调用k-driver中的函数还是内核中的其它函数,都可以通过ioctl()系统调用来实现,k-mod中的一个ioctl管理器收到请求并调用合适的内核函数。u-driver向下调用的请求主要有以下几种[8]:(1)VIRT2PHY,计算u-driver模块中虚拟地址对应的物理地址;(2)UP_INFO,向内核空间提交当前用户态驱动进程信息;(3)DMA_PHY,获取k-driver中DMA缓冲区的物理地址;(4)OPEN、CLOSE等系统调用。
将硬件产生的中断通知给用户程序,这里通过将中断映射到文件描述符来实现这一功能。在Linux系统的/proc文件系统下,每一个中断都对应一个目录[9],目录下包含一些属性文件。通过在中断号对应的目录下增加一个新的属性文件,用来标识是否产生了该中断号对应的中断。当u-driver对该文件执行read()操作时,内核在对应的信号量上执行down()操作,阻塞该read()操作直到中断的产生。硬件产生中断时,首先在内核中断处理函数中屏蔽该中断,然后增加中断映射的文件描述符中的计数,最后在对应的信号量上执行up()操作,使之前阻塞的read()操作返回,返回值为文件描述符中的中断计数,如果返回值大于0,说明产生了硬件中断,则转而去执行u-driver中定义的中断处理函数。
2.4 DMA缓冲区分配方案
为减少数据拷贝次数,u-driver要能够直接访问DMA缓冲区的内容,即实现用户态的DMA缓冲区[10]。这可以通过Linux内核的设备文件/dev/mem和mmap()系统调用来实现。通过open()系统调用打开/dev/mem文件,接着,把k-driver申请的内存的物理地址传送到用户空间,最后通过mmap()将这段物理内存映射到当前进程的地址空间。其中,分配共享内存的关键代码如下:
kaddr = kmalloc(size);
phy_addr = addr – PAGE_OFFSET;
fd = open(“/dev/mem”, O_RDWR);
uaddr = mmap(phy_addr, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
图3为本设计中所采用的DMA缓冲区分配方案的数据拷贝路径图,其中实线是本设计方案的数据拷贝路径,虚线是传统内核态驱动程序的数据拷贝路径。
3 测试
3.1 开发环境搭建
嵌入式开发一般采用宿主机/目标机模式。本设计的开发环境为:宿主机为PC机,网卡为Intel 82579LM千兆网卡,安装Debian 6.0系统,内核版本为2.6.32.5,目标机为S3C2440开发板,网卡为DM9000,在该目标机上移植了2.6.32.2版本的Linux内核,宿主机和目标机之间采用串口和以太网连接,便于调试。
3.2 测试方法
为了衡量用户态驱动对性能的影响,这里使用netperf工具集测试Linux内核自带驱动和本设计实现的用户态驱动程序的性能(吞吐量和CPU占用率)。在目标机分别安装两种驱动程序,在宿主机与目标机之间测试TCP吞吐量。所有的netperf测试都使用默认的接收和发送缓存大小,即接收为87,380字节,发送为16,384字节。测试界面如图4所示。
3.3 测试结果
网络吞吐量如表1所示,目标机作为client,宿主机运行netserver。
CPU占用率如表2所示,统计了作为client端的S3C2440 CPU的占用情况。
测试结果表明了本设计实现的用户态驱动程序对性能的影响十分微小,网络吞吐量与内核态驱动基本相当,CPU占用率方面略有上升,影响不大,达到了预期效果。
4 结束语
Linux作为目前在嵌入式领域使用最为广泛的操作系统,进一步提高其可靠性是目前的研究热点。本文从工程应用出发,研究并设计了ARM平台网卡的用户态驱动程序。实验证明本文设计的用户态驱动程序完全能满足性能要求,同时有效地减少了运行于内核态的驱动代码,大大提高了整个系统的可靠性。通过设计该驱动程序,总结出一种在嵌入式Linux操作系统下编写用户态驱动程序的方法,对类似的其他设备的用户态驱动开发有很大的借鉴意义。
摘要:为了进一步提高嵌入式Linux系统的可靠性,设计和实现了DM9000网卡在ARM平台的用户态驱动程序。通过将影响I/O性能的数据处理操作留在内核态全速运行,而将管理操作例如初始化和配置运行在速度相对较慢的用户态,从而获得了较高的性能和兼容性。实验结果证明,文中设计实现的用户态驱动程序能够满足实际应用的性能需求,同时降低了内核态的代码量,达到了提高整个系统可靠性的目的。
关键词:嵌入式系统,Linux,驱动程序,可靠性
参考文献
[1]颜跃进,秦莹,孔金珠,等.操作系统设备驱动可靠性研究综述[J].计算机工程与科学,2009,31(5):121-125.
[2]Swift M M,Bershad B N,Levy H M.Improving the reliability ofcommodity operating systems[J].ACM TOCS,2005,23(1).
[3]Microsoft.Architecture of the user-mode driver framework[Z].2006.Version 0.7.
[4]Ganapathy V,Renzelmann M J,Balakrishnan A,et al.The designand implementation of microdrivers[J].ASPLOS'08,ACM,2008:168-178.
[5]Ganapathy V,Balakrishnan A,Swift M M,et al.Microdrivers:ANew Architecture for Device Drivers[J].Proc.Of the 11th USE-NIX Workshop on Hot Topics in Operating Systems,USENIX Asso-ciation,2007:1-6.
[6]Corbet J,Rubini A,Kroah-Hartman G.Linux Device Driver[M].O'Reilly Media,2005.
[7]DM9000A Ethernet Controller with General Processor Interface DataSheet[M].Davicom semiconductor Inc,2005.
[8]刘军卫,李曦,陈香兰,等.用户态驱动框架的研究与实现[J].计算机系统应用,2011,20(11):67-71,90.
[9]Love R.Linux Kernel Development[M].机械工业出版社,2011.
嵌入式用户界面 篇5
数控机床管理人员了解主轴和程序运行时间等信息, 可改进提高机床效率, 维修人员了解电机温度和电流等机床状态信息, 可为机床故障诊断和预知维修提供依据。为此开发SINUMERIK 840D系统嵌入式管理维护界面, 提取NC和PLC信息并加工成对机床使用人员有用信息, 并把这些信息以画面方式清晰显示。
840D系统具有HMI Programming Package、Wiccflexible和用户扩展接口等开发界面工具。前几种方法开发的界面, 调试时较困难, 可移植性差, 基本需要一设备一调试。用户扩展接口是840D系统的附加工具, 开发不需另外软件和额外费用, 用它开发的界面可以和数控界面无缝融合, 在各个机床之间可移植性强。用户扩展接口以数控界面为基础, 通过调用一系列指令, 实现用户界面定制、外部图像导入以及变量定义。用户界面可方便嵌入到840D系统界面中, 使用者可在加工中随时了解机床维修信息。1个扩展用户接口界面包含表头 (Header) 、标题行 (Display line) 、屏幕窗体元素 (Form element) 、对话行 (Dialog line) 、图表 (Graphic) 、水平8个软键、垂直8个软键等元素。用户可通过编程对这些元素进行定制, 接口界面中的变量可接受来自NC、PLC的信息。多个界面可嵌套定义, 形成树形结构, 界面之间切换非常方便。
二、管理维护界面的定制
50分厂数控机床多为切屑机床, 管理者主要关注主轴切屑时间、程序运行时间以及机床辅助工作时间等信息;主轴电机温度、电流和负载变化情况则是机床维护者关注信息。下面以这些信息作为对象, 介绍开发管理维护界面。
1. 文件的存放位置和文件名的确定
定义新界面的数据被存储于1个配置文件中, 它以.COM作为文件后缀, 此文件被系统自动解释和执行, 结果自动在屏幕显示。文件名的确定不是任意的, 而是具有一定规则, 这和机床工作方式相关, 如要将界面嵌入到840D手动工作方式 (JOG方式) 界面中, 那么定义新界面的数据应该存放在MA_JOG.COM中, 如要将界面嵌入到自动工作方式界面中, 数据应存放在MA_AUTO.COM中。同理, 文件还可存放在MA_MDI.COM、MA_PARA.COM等文件中。为随时查看界面中的信息, 该项目决定把界面同时嵌入到手动、自动工作界面中, 这样就同时需要两个配置文件MA_JOG.COM和MA_AUTO.COM。
2. 界面的定制
(1) 软键的定义。定义840D数控界面中的空白键, 给它赋予新的键名。按下此键时, 进入设计界面, 软键定义编程如下。
(2) 屏幕窗体的设计。包括窗体名称的确定, 窗体主体位置的确定 (窗体距屏幕顶部、左端的距离) , 窗体宽度、高度的确定, 窗体中插入图表的名称及位置确定, 窗体内分栏数的确定。定义窗体的指令格式M (Identifer/[Header]/[Graphic]/[Dimension]/[System or user variable]/[Graphic position]/[Attributer]) , 即M (标识符/[窗体标题]/[待插入图表名]/[窗体位置]/[用NC或PLC变量获取光标位置]/[待插入图表的位置]/[定义显示的栏数]) , 其中带[]的参数为可选项。
(3) 屏幕窗体元素的设计。包括窗体元素名称、位置和色彩的确定, 窗体元素数据类型的确定, 与窗体元素相关的NC/PLC变量的确定, 输入、输出区域位置和色彩的确定等项目。定义窗体元素的指令格式DEF Identifer= (Variable type/[limit values or toggle field or table identifer]/[Default]/[Texts]/[Attributes]/[Help display]/[System or user variable]/[Position of short text]/[colors]/[Help]) , 即DEF标识符= (变量类型/[变量的极限值]/[缺省]/[文本]/[属性]/[帮助显示]/[系统或用户变量]/[短文本位置]/[输入输出区域位置]/[输入输出区域色彩]/[帮助]) , 其中带[]的参数为可选项。
根据项目需求, 管理维护界面定制的程序代码如下, 管理维修界面效果见图1。
三、PLC程序编制
界面定制完成后, 需要选择与界面中变量相关的信号, 将它们加工成有用信息在界面显示。管理信息必须根据用户要求, 选用相应信号, 通过编制PLC程序来实现监控。主轴运转时间监控, 选用驱动信号DB36.DBX61.4和DB36.DBX94.4, 将它们的非信号相与作为采样信号。程序运行时间监控, 选用通道信号DB21.DBX35.0作为采样信号。辅助工作时间定义为主轴不运转, 程序不运行, 选用信号DB36.DBX61.4、DB36DBX94.4和DB21.DBX35.0为采样信号。要求上述3个时间能长期统计, 断电后统计结果不丢失, 开机后能继续累加。但是STEP7软件计时器最大计时为2h46min30s, 不能进行累加计时。该项目通过编制时间片脉冲程序与PLC系统计数功能SFB1相配合, 计时范围可达216h。机床状态信息纷繁复杂, 这些信息显示可根据具体项目采用不同方法。电机电流、负载和功率显示, 可在定义变量时, 通过编程的方法直接读入;电机温度的检测, 可通过STEP软件的FB2功能块把这些参数读入到PLC中, 然后转换成能在界面中显示的数据。为实现上述功能, 编制以下PLC程序块: (1) FC200——产生连续的时间脉冲; (2) SFB1——系统功能块, 用于时间段的计数; (3) FC201——统计主轴运行时间、程序运行时间和辅助工作时间; (4) FC205——读取NC参数信息; (5) DB121、DB122和DB123——调用SFB1时的背景数据块; (6) DB132——调用功能块FB2时所需的背景数据块; (7) DB128、DB133——HMI与PLC交换数据的接口。相关PLC程序在此略去。
四、调试和备份
程序编制完成以后, 实测各项目, 要达到精确计时, 就要观察变量中间值。观察24h内变量MW6、MW7的中间值与理论值的差值, 误差为6s, 误差率=12/ (24×3600) =0.007%, 可满足设备精确计时要求。读取机床主轴信息时, 初次引用的机床变量为$AA_LOAD[AX6] (AX6是主轴的驱动编号) , 变量[AX6]引用不正确, 界面显示“SPINDLE_LOAD########%”, 这是由于控制系统找不到$AA_LOAD[AX6]对应的参数, 用默认符号#填充对应的数值位。通过正确的引用主轴变量$AA_LOAD[SP], 界面中子项目“主轴负载百分比”显示“SPINDLE_LOAD 12.14637%”, 正确显示。
调试完成后, 需要备份系统, 分别备份MMC和PLC, 也可对PLC备份以后, 对硬盘作整体备份。画面制作程序存储在F:DHCUS.DIR目录下的MA_JOG.COM、MA_AUTO.COM文件中。这样若硬盘损坏, 只需更换硬盘, 然后将备份的数据恢复即可, 而不用重新编制HMI界面程序和PLC控制程序。
较之传统的加装外部计时器的方法, 该方法能根据系统相关信息, 精确统计出机床运行效率, 而且计时时间长、不需额外投资, 可在使用SINUMERIK 840D系统的设备间方便互相移植。
摘要:在SINUMERIK 840D数控系统, 利用用户扩展接口的方法, 开发嵌入式管理维护界面, 介绍编制PLC程序, 现场调试效果良好。
嵌入式用户界面 篇6
推荐系统在电子商务、社会网络和信息检索等领域中都有着广泛的应用[1]。在推荐系统中,数据往往被表示成一个用户行为矩阵。用户行为矩阵的纵坐标表示用户,矩阵的横坐标表示商品、用户或者网页等,矩阵中的每一个元素表示对应的纵坐标和横坐标之间的关系,如用户购买商品的数量,用户和用户之间的连接关系,以及用户对网页的访问行为等。随着网络服务的运行,用户行为矩阵中积累了大量的历史行为数据,通过对历史行为的分析可以对矩阵中的空元素进行预测,从而预测用户未来的行为[2]。
传统的推荐系统主要从矩阵和网络两个视角对用户的未来行为进行分析和预测。从用户行为矩阵的视角来看,推荐系统根据矩阵中已有的数据对矩阵建立模型,然后对矩阵中值为空的元素进行预测,典型的建模方法为矩阵分解与补全[3,4,5];此外,还可以采用启发式方法对矩阵中值为空的元素进行预测,如协同过滤的相关方法[6,7,8]。从网络的视角来看,用户行为矩阵可以看作一个二部图,如电子商务中的用户-商品二部图;在社会网络中,该二部图退化为简单的网络。在二部图中,推荐系统根据网络中已有的连接,估计不存在连接的两个点之间建立连接的概率,并以此预测用户未来的行为,常用的方法是网络中的随机游走[9,10,11]。
上述方法从原理上都可以理解为对矩阵中值为空的元素进行预测,然后针对每一个用户(纵坐标)将预测后的横坐标进行排序,并返回排名靠前的若干个纵坐标项。这种方法存在如下三个缺点:
(1)假设矩阵中的数据同时到达。在预测空元素时应用所有的历史数据而没有考虑数据间的时序关系,然而用户实际的行为往往存在着短期行为倾向。
(2)推荐结果只返回那些值为空的项。上述方法在向用户进行推荐时往往只返回值为空的项(即未购买过的商品),然而用户的实际购物过程中存在着大量的重复购买行为,因而推荐结果中也应该包含那些值不为空的项。
(3)不能适应数据的动态更新。由于对矩阵建模时的数据是固定的,因而当新的用户行为数据到来时不能对预测的结果进行动态的更新。
为了应对上述的前两个问题,研究人员提出了时间敏感的推荐系统[12]。文献[13]在用户-商品矩阵的基础上将用户对商品的浏览记录作为上下文,在进行特征提取后引入时间维度构成三维张量。在特征提取过程中,采用固定的特征集合;在时间序列预测上,以天为时间单位,在一定的时间滑动窗口上对历史数据进行加权求和,并提出一种特征级时间序列分析方法(Feature-level Time Series Analysis,FTSA)。FTSA虽然考虑了推荐系统中用户的短期行为倾向问题,但是特征集合的选取需要根据阈值进行判定,而特征集合的选取又决定着预测结果的准确性,因此该方法具有一定的局限性。
本文以文献[13]提出的思想为基础,对用户和商品特征采用嵌入式向量表示,并采用循环神经网络[14]对时序数据进行建模和预测。在特征向量的嵌入式表达计算过程中,将用户和商品用相同的潜在特征集合来表示,并通过用户浏览记录中对商品的购买与否进行有监督的学习。在特征向量的嵌入式计算完成后,可以得到用户和商品特征向量的长期行为倾向。在时序数据的预测过程中,采用循环神经网络对每个用户的时序行为进行建模,并得到用户的短期行为倾向。
1 循环神经网络
循环神经网络是时序数据分析的重要方法之一,它通过网络中的循环结构可以记录时序数据的历史信息,循环神经网络的示意图如图1所示。
在图1中向量x为循环神经网络的输入数据;y为输出值;向量h为网络的隐藏层数据;W,P和β为网络的参数。在循环神经网络中,隐藏层ht的输入数据为xt和ht-1。采用Logistic函数作为激活函数,则ht为:
式中:指数函数exp(-zt)应用到向量zt的每一个分量;W为输入层到隐藏层的权重矩阵;P为隐藏层到下一个隐藏层的权重矩阵。在输出端,采用Logistic回归进行结果预测,则yt的计算公式为:
式中β为隐藏层的各分量在最终预测结果中的权重向量。
2 基于嵌入式向量和循环神经网络的用户行为预测方法
推荐系统中包含着用户和商品两类实体,本文通过潜在变量将用户和商品嵌入到相同的潜在向量空间。在给定用户历史行为记录时,采用循环神经网络对每个用户的时序行为进行分析建模,并对未来的行为进行预测。
2.1 用户和商品的嵌入式向量生成
假设推荐系统的用户集合为U,商品集合为V,用户和商品的数量分别为|U|=n和|V|=m,用户对商品的购买矩阵为R,R中的元素ru,v表示用户u共计购买v的数量。
在生成用户和商品的嵌入式向量时,采用相同的潜在特征空间。对每个用户生成嵌入式向量时,用该用户对商品集合的购买记录来描述该用户,即R中的行向量;同理,用所有用户对某商品的购买记录来描述该商品,即R中的列向量。由于用户数量和商品数量往往是不等的,所以将用户和商品映射到相同的特征空间。
本文采用如图2所示的模型对用户和商品进行嵌入式向量计算。
对于用户u和商品v(采用Logistic函数)分别根据矩阵W1和W2映射为具有相同维度的向量h1和h2:
式中:指数函数exp(⋅)应用到参数向量的每一个分量;h1和h2分别为u和v最终的嵌入式向量表示。为了对参数W1和W2进行估计,采用监督的机器学习方法。在图2中,采用三维张量W3对h1和h2的关系进行学习,并采用线性回归方法依据u对v的购买与否对参数W3进行学习,具体描述为如下公式:
在整个参数学习过程中,以用户的浏览记录(包含消费行为记录)为训练数据集。如果u浏览了v并且购买了,那么y为1;如果未购买,那么y为0。在h1和h2的关系构建过程中,本文采用三维张量,而并没有采用二维矩阵的全连接网络。如果采用二维矩阵的全连接网络,那么在已知输出结果y的情况下,u和v是条件独立的,因此不能描述u和v之间的关系。采用三维张量时,如果输出结果y已知,那么u和v的关系仍然可以由张量W3进行描述。最后,根据公式(7)所示的目标函数对模型进行求解。
式中:yt为真实值;为预测值;为损失函数;和λ分别为规格化项及所占的权重。
在图2中,h1和h2分别为u和v的嵌入式向量;h3为u和v的联合嵌入式向量。由于训练过程采用的数据集为所有浏览记录,因此h1,h2和h3反应的是u和v的长期特征。
2.2 用户行为预测
在得到用户和商品的嵌入式向量表示后,依据用户对商品的浏览记录对每个用户的时序行为进行建模,从而刻画用户的短期行为特征。
采用循环神经网络对用户的行为进行建模的预测模型如图3所示。对于每个用户u,其对商品的浏览记录(包含消费行为记录)按照时间进行排序后可以得到序列v1,v2,⋯,vt-1,vt,⋯,对应的结果为y1,y2,⋯,yt-1,yt,⋯。在当前时刻t,基于浏览历史y1,⋯,yt-1,对循环神经网络中的参数W4,W5和β进行学习,然后预测用户对V中所有商品的购买概率。
上述过程可用如下公式进行描述:
式(11)所示的目标函数中各符号的定义与式(7)相同。在式(9)中,指数函数exp(-zt)应用到向量zt的每一个分量。在t时刻,以用户u的历史信息v1,⋯,vt-1和y1,⋯,yt-1为训练数据对每个用户建立时序模型。在进行商品推荐时,对每个商品v∈V预测用户u对该商品的购买率,并将购买率高的商品推荐给用户u。
2.3 嵌入式向量及时序预测模型的动态更新
嵌入式向量h1和h2分别描述用户u和商品v的长期特征,当新的浏览记录(包含消费行为记录)产生时,需要对图2所示的嵌入式向量生成模型进行动态更新。
本文的研究重点是用户和商品的嵌入式向量生成以及用户行为的时序模型,而不是增量学习算法[15]的研究,故采用简单的基于随机梯度下降的学习算法。在采用随机梯度下降方法进行参数学习的过程中,以原来的参数为基础进一步进行迭代,并在迭代过程中提高新纪录的出现比例。该方法在实际运行过程中可以在很少的迭代次数内收敛,详见第3.3节。
嵌入式向量h1和h2分别描述用户u和商品v的长期特征,然而在推荐结果的预测过程中,推荐结果往往更依赖于用户的短期行为特征。当新的浏览记录(u,v,y)到来时,对用户u的时序模型参数W4,W5和β进行更新,该更新过程只需要进行一次迭代运算,因此运行效率高。
3 实验结果与分析
3.1 实验设置
数据集:实验采用京东[14]和Last.fm[16]两个公开的数据集。京东为中国著名的电子商务网站,该数据集包含京东网站2013年10月—12月的部分数据;Last.fm为音乐和视频评论网站,数据集中包含2005年2月—2009年6月的相关数据。这两个数据集的统计信息见表1。
对比算法:在实验中将本文提出的基于嵌入式向量和循环神经网络的方法记为EVRNN(Embedded Vector and Recurrent Neural Networks),并将该方法与基于矩阵的经典方法进行矩阵分解[3]和KNN(K-Nearest Neighbors)[7],将基于网络的随机游走[10]方法,以及特征级时间序列分析方法FTSA[13]进行了对比。此外,实验中还实现了传统的非嵌入式向量的循环神经网络方法RNN。
评价指标:实验采用推荐系统常用的F值作为评价推荐方法性能的度量指标。在推荐系统中,推荐结果的查准率(Precision)为返回结果中正确结果的比例;推荐结果的召回率(Recall)为返回的正确结果的个数占系统中所有正确结果的比例;F值为查准率和召回率的调和平均值,其计算公式为:
3.2 准确性分析
矩阵分解、FTSA、RNN和EVRNN这四种方法都通过潜在的特征向量对原始数据进行描述,因此实验通过改变特征数量的个数来观察不同方法的F值变化情况,并对比不同方法的推荐性能。图4和图5分别为上述四种方法在京东和Last.fm两个数据集下的测试结果。在这两幅图中,四种方法的F值都随着特征数量的增加先增加再减小。这是因为在机器学习模型中,模型的描述能力随着特征数量的增加而逐渐增强,当模型的描述能力增加到一定程度时,由于训练数据不足导致算法出现过拟合现象,因而模型参数(这里指特征数量)的选择与具体的数据集相关。在这四种方法中,FTSA和矩阵分解两种方法的F值在开始时很小,并且在特征数量为70或者80时达到最大值;RNN方法的F值变化较平缓,其最大值小于FTSA和矩阵分解两种方法;EVRNN方法的F值在初始时就比较大,并且在特征数量为20或者30时迅速达到最大值。从四种方法达到最大值所对应的特征数量来看,EVRNN方法采用的嵌入式向量仅需很少的特征便可以描述原数据间的关系,并且与传统的RNN方法相比较明显地提高了推荐结果的F值。
为了进一步直观展示不同方法的推荐结果F值,对矩阵分解、FTSA、RNN和EVRNN四种方法分别选取曲线最高点所对应的特征数量。此外,对于KNN和随机游走两种方法,分别选取对应方法的默认设置,图6为六种方法在两个数据集下的性能对比。从该图可以明显看出,EVRNN方法在两个数据集上的F值明显高于其他5种方法,因此可以得到最好的推荐结果。
3.3 运行效率分析
在相同的实验环境下,通过实验对比了上述六种方法进行离线计算所用的运行时间。在离线计算过程中,对于KNN方法,计算了所有用户的K个最相近的邻居用户;对于其他五种方法,通过训练数据对模型的参数进行学习,从而得到所需的预测模型。表2列出了六种方法的离线运行时间。在表2中,EVRNN方法虽然具有最好的预测结果,但是所需的运行时间也是最长的。与预测能力次之的FTSA方法相比较,EVRNN方法在京东和Last.fm两个数据集上分别多运行了0.7 min和0.3 min,即分别多出了1.5%和3.6%的运行时间,这在时间上是可以容忍的。
最后,分析了EVRNN方法在每次新纪录到达时模型的更新时间,实验结果见图7。这里的模型更新时间包括嵌入式向量生成模型的更新和用户行为时序预测模型的更新时间。当EVRNN方法的特征数量逐渐增加时,模型的更新时间近似呈线性增长。EVRNN方法的特征数量与训练数据集的大小有关,通过增加特征数量可以观察该方法的可扩展能力。当新的记录到达时,嵌入式向量生成模型由原来的稳态参数转换为新的稳态参数,由于稳态参数的变化很小,因此仅需很少的迭代次数;对于用户行为时序预测模型,一个新记录的到来仅需对模型的参数进行一次迭代更新,因而所需的运行时间也是很短的。
4 结语
本文提出了一种基于嵌入式向量和循环神经网络的用户行为预测方法。通过对用户-商品行为矩阵数据的有监督学习,将用户和商品映射到相同的潜在特征空间,并得到用户和商品的长期特征。通过采用循环神经网络对用户的时序行为进行建模,得到了用户的短期行为特征。该方法综合考虑了用户的长期和短期行为特征,能更好地对数据集进行建模,因而具有更好的预测效果。最后,通过两个真实的数据集验证了本文提出方法的有效性。
在新数据导致的模型动态更新中,本文采用简单的随机梯度下降方法对嵌入式向量模型的参数进行更新。然而,当新数据到达的频率提高时,可能出现嵌入式向量模型还没有到达稳态,此时用户的时序行为模型所使用的用户和商品嵌入式向量是过时的,或者处于阻塞状态。在下一步的研究工作中,通过研究嵌入式向量模型的增量式更新,从而提高本文方法的健壮性,进而适应数据高速动态增长的推荐环境。
摘要:为了进一步描述时间因素对用户行为的影响,进而提高推荐系统的推荐效果,综合考虑了用户的长期行为特征和短期行为特征提出一种基于嵌入式向量和循环神经网络的用户行为预测方法。依据推荐系统中的所有用户行为数据,将用户和商品嵌入到相同的特征空间,并通过嵌入式向量反应用户的长期行为特征。针对每个用户,依据其历史行为的时间序列,基于循环神经网络建立该用户的行为预测模型,从而描述该用户的短期行为特征。实验结果表明,提出的方法与特征级时间序列分析等方法相比具有更好的推荐效果。
嵌入式用户界面 篇7
关键词:嵌入式GUI,Linux,QT,S3C2440
1 引言
微型生化分析仪是以一块几平方厘米或者十几平方厘米的芯片为载体,在其中进行基本的生物和化学领域中的生物化学反应,分离检测等的操作,并用分析仪中的电子设备对检测数据进行分析,存储,输出等操作。该产品适用于食品检测、水质分析、医疗检测等领域,并具有很好的发展前景。而为了该产品的实现便携,小型化,操作友好性强等特征,设计一个美观的操作界面成为其必不可少的要求之一。QT作为嵌入式设备广泛采用的GUI应用程序,具有体积小巧,稳定性强,实时性强,可量身订做等特点[1]。因此,伴随ARM处理器以及Linux系统的使用越来越广泛,开源代码的图形库QT开发的优势显得尤为明显[2]。
本设计以mini2440为硬件载体,linux-2.6.3.2为软件环境,并考虑软件的功能性和运行的流畅度等特征,采用了qt4.6.3进行界面开发。实现了mini2440和外部设备的串口数据通信,并能够利用串口打印机进行数据的打印,实现U盘数据存储等特征。
2 系统结构分析
本设计采用mini2440硬件平台上移植linux-2.6.3.2系统,并编写QT-4.6.3应用程序在系统上运行,设定开机自动运行该应用程序。系统的软件结构如图1。
3 软件开发和运行环境的搭建
实现mini2440上QT软件的开发,除了要在电脑中搭建好开发环境外,还要在开发板中为程序的运行好建立运行环境。这里我们选择的版本是QT-4.6.3,所以首先要完成QT-4.6.3的移植工作。包括将编译好的库文件拷贝到开发板指定的目录下,并为QT做好环境变量的设置等[3]。
QT-4.6.3的移植主要需要完成以下工作:
环境:在电脑中安装好fedora14系统(建议在VMware Workstation中安装),安装好交叉编译工具链:arm-none-linux-gcc-4.3.2,并在系统中安装samba服务器。
软件准备:下载Linux下的安装包qt-every whe re-opensource-src-4.6.3.tar.gz和用于Linux/X11 32位的Qt Creator-1.3.1二进制软件安装包,该二进制安装包名称如下:qt-creator-linux-x86-opensource-1.3.1.bin。
移植步骤如下:
(1)利用samba服务器将两个安装包qt-every where-opensource-src-4.6.3.tar.gz和qt-creatorlinux-x86-opensource-1.3.1.bin上传到fedora系统,并使用命令tar–xzvf qt-everywhere-opensourcesrc-4.6.3.tar.gz对安装包进行解压。
(2)为了使开发的qt程序既能在电脑端Linux系统中进行仿真,又能进行交叉编译生成arm版的二进制文件,需要在fedora中编译X86和embedded版qt-4.6.3。
(3)安装qt-creator-linux-x86-opensource-1.3.1.bin,方便使用qt-creator进行qt的开发。
(4)拷贝编译成功的qt的lib文件到开发板中,注意拷贝到开发板中的路径要和fedora14中的路径相同,否则开发板中运行QT程序时会提示找不到库文件。
4 应用程序软件设计
4.1 软件功能需求分析
该微型生化分析仪结构如图2,由DSP完成对机械结构的控制,并将命令通过串口传送给mini2440,由mini2440返回控制指令。并且通过mini2440界面控制,能够完成采集信号的存储和打印功能。
因此,需要设计的应用软件的主要功能有,通过串口实现指令的接收和发送,对接收的数据进行处理和筛选后在界面上进行显示,实现数据的打印或存储。在程序的设计中,使用了QT的文件处理、数据库、表格显示,时间处理等相关类。并调用了系统指令实现了关机等功能。
4.2 软件详细设计
4.2.1 信号与槽机制
信号和槽机制是QT的核心机制[4]。它是一种高级接口,应用于对象之间的通信。作为一种独立于C++语言的机制,需要借助于QT工具moc进行预处理,生成所需要的附加代码[5]。信号与槽函数的关联函数为bool QObject::connect(const QObject*sender,const char*signal,const QObject*receiver,const char*member),当sender发送信号时,将调用接收函数。一个对象可以与多个槽关联,也可以多个信号与同一个槽关联方式[6]。信号与槽的关联方式如图3。
该软件设计中添加很多按钮,并需要实现界面的切换,下面关联实现了点击按钮调用窗口切换函数的功能,部分程序如下:
4.2.2 串口通信的实现
串口通信的实现并没有涉及QT的部分,由于mini2440系统中串口的驱动程序已经移植好,所以只需要对串口进行初始化,包括设定串口通信的波特率、奇偶校验、停止位数据位等[7]。这里我们设置串口的通信速率是115200,数据位是8位,停止位是1位,无奇偶校验。具体程序如下:
4.2.3 数据库的使用
由于该生化分析仪要对检测的数据进行存储等功能,并且SQLite3数据库功能强大、接口简单、速度快、体积小[8],非常适合嵌入式设备,所以这里进行了数据库SQLITE的移植,具体过程如下:
(1)下载sqlite源码sqlite-3.6.22.tar.gz,复制到Linux系统中并进行解压,输入如下指令:
(2)创建build目录并在这个目录中进行交叉编译,输入如下指令:
mkdir buildcd build
(3)在build目录中运行sqlite-3.6.22中的con figure脚本生成Makefile文件,如下:
../configure--host=arm-linux--prefix=/root/sqlite-3.6.22/build/target
(4)执行make和make install命令,并且在编译和安装完后将生成的bin下的文件下载到开发板/usr/bin目录中,将lib下的文件下载到开发板/usr/lib中,include目录下的是编程中会用到的C语言API的头文件。
数据库使用以及界面显示的部分代码如下:
4.2.4 关机和时间设定功能的实现
关机功能的实现可以调用Linux下的shutdown命令,shutdown命令的语法规则如下[9]:
shutdown[-cf Fhknr(参数名称)][-t秒数]时间[警告信息]
因此,程序中我们可以写为system(“shutdown–s–t 0”);-s表示关机,-t表示设置关机时间[10],这里表示为0秒后实现关机功能。
对于时间的设定,程序中可以调用类QDate和QTime,并使用系统命令hwclock来设置系统时间。具体方法为:使用代码QDate Date=ui->date Edit->date();来返回界面中设定的日期,并使用QTime time=ui->time Edit->time();来返回界面中设置的时间值。并使用QDate::to String()函数来将上面的值转换成字符串形式,最后使用system(“hwclock–w”)来完成系统时间的设定。
5 程序测试
程序编写好后,可以在qt-creator中通过调整project选项来进行计算机端的仿真或者进行交叉编译,生成arm可执行的二进制文件后移植到开发板中。
该程序需要完成检测芯片仓的开启和关闭工作,并完成参数的设定,数据的存储,打印,系统时间设定,以及关机功能等,运行编译好的qt程序,部分测试结果如图4。
6 结束语
该微型生化分析仪界面设计可以配合分析仪其它部分完成检测工作,解决需要实现的功能,并且稳定性好,可靠性高,后续可进行程序的改进和继续开发,并可以带来良好的操作体验,具有很高的实用价值。
参考文献
[1]陈爽,秦攀科,贺荣,杨晨.Linux与Qt程序设计[M].北京:清华大学出版社,2011.12.
[2][加拿大]BLANCHETTE Jasmin,[英]SUMMERFIELD Mark.C++GUI Qt4编程[M].第二版.闫锋欣译.北京:电子工业出版社,2013.5.
[3]蔡志明,卢传富,李立夏.精通QT4编程[M].北京:电子工业出版社,2008.
[4]倪继利.Qt及Linux操作系统窗口设计[M].北京:电子工业出版社,2006.
[5]刘小春,张有为,向伟.嵌入式Linux下Qt/Em bedded应用关键技术研究[J].微计算机信息.2007,(35):62-63.
[6]任善全,吕强,钱培德等.一个基于Qt/Em bedded的嵌入式Linux应用程序的实现[J].计算机应用与软件.2006,(2):105-107.
[7][美]EZUST A,EZUST P.C++设计模式-基于Qt4开源跨平台开发框架[M].李仁见,战晓明译.北京:清华大学出版社,2007
[8]孙天泽,袁文菊,张海峰.嵌入式设计及Linux驱动开发指南[M].北京:电子工业出版社,2005.2.
[9]韦东山.嵌入式Linux应用开发完全手册[M].北京:人民邮电出版社,2008.