APP下载

嵌入式图形用户界面系统的设计与实现

2012-07-25刘新德冯仁剑

计算机工程与设计 2012年7期
关键词:链表图形图像字符

熊 杰,刘新德,冯仁剑

(北京航空航天大学 仪器科学与光电工程学院,北京100191)

0 引 言

图形用户界面 (graphical user interface,GUI)的引入为嵌入式设备提供了图形化的监控和控制界面,提升了嵌入式系统的整体功能并降低了复杂性[1]。针对嵌入式系统,现有的GUI开发主要有自下而上逐步开发和使用嵌入式GUI系统两种方式[2]。自下而上的GUI开发方式易于实现,但没有将GUI作为一个软件层从应用程序中剥离,导致开发效率不高,代码复用性差。嵌入式GUI系统将显示逻辑和数据处理逻辑划分开,使得图形界面开发相对独立,且避免了代码重复,便于实现应用程序开发。

目前,国内外针对嵌入式应用研究开发了一些GUI系统。Microwindows是Century Software公司开发的将GUI引入到小型设备平台的项目[3]。Microwindows的图形引擎开发比较完善,采用标准客户/服务器结构,具有一定灵活性。但该结构占用更多系统资源,降低了系统效率。Trolltech公司在QT的基础上开发实现的QT/Embedded[4],使用C++开发,功能完善。但其代码所占用空间较大,且依赖于Linux操作系统,移植性差。MiniGUI是一种为嵌入式系统提供图形用户界面支持的中间件技术,早期由魏永明先生主持开发[5]。MiniGUI的窗口系统和应用开发接口完善,但基于Linux开发,难以移植到非POSIX标准的目标平台,且过多注重于窗口模型的接口抽象,开发过于繁琐。

为解决工业控制设备中的图形显示问题,有必要针对上述嵌入式GUI系统存在的平台依赖性和轻型性等方面的不足,设计并实现一种轻量级嵌入式图形用户界面LIGUI系统。LIGUI采用双向链表结构组织窗口,避免复杂的窗口剪切和操作;利用输入输出抽象层屏蔽具体硬件平台的不一致,实现系统的移植;提供应用编程接口和配置选项,易裁剪和配置;核心层采用微内核的设计思想,具有轻量级的特点。

1 LIGUI体系结构设计

LIGUI系统采用分层体系结构,每层负责内部的具体实现,底层通过接口为上层提供服务,实现将层次内部的修改隔离,不影响上层调用底层完成相应功能。

如图1所示,LIGUI总体上分为3层,分别为硬件抽象层,GUI核心层和应用接口层。

图1 LIGUI系统体系结构

其中,硬件抽象层为上层模块提供一致接口,解决移植问题;GUI核心层完成图形图像绘制,窗口的组织和消息管理;应用接口层为用户提供应用编程接口和配置选项,可以实现系统扩展。

1.1 硬件抽象层

由于嵌入式应用硬件平台的多样性,为实现LIGUI系统在不同底层设备之间的移植,抽象了输入输出设备的功能,并且提供一致的接口。针对不同的输入输出设备编写硬件驱动程序,在此基础上将输入输出抽象层独立出来,封装底层系统和硬件设备的功能函数,使得上层的界面绘制和输入处理在访问不同硬件设备时,无需考虑系统和设备差异带来的影响。硬件抽象层包括输入抽象层和输出抽象层。

1.1.1 输入抽象层

输入抽象层将输入设备的功能抽象为统一的输入接口[6]。任何独立按键、矩阵键盘、虚拟键盘的按下动作都可以抽象出键值和敲击次数;对于鼠标移动和触摸屏的点击输入,可以提取坐标值和按压状态信息。

1.1.2 输出抽象层

输出抽象层的主要功能是为图形图像的绘制输出提供显示设备接口,上层图形程序的编写只需调用接口数据结构提供的函数,而不用考虑针对不同底层显示设备的具体实现。

显示输出最终都要对应到单个像素点的操作,所以在数据结构中定义屏幕像素点的信息,抽象出SetPixel和GetPixel接口。显示设备接口用结构体LCDAPI来表示。

typedef struct{

void (*InitLcd)();

void (*SetPixel)(Pixel pixel,int x,int y);

void (*GetPixel)(Pixel*pPixel,int x,int y);

int(*GetXSize)();

int(*GetYSize)();

U8(*GetBPP)();

void (*InitPalette)(U8bpp);

}LCDAPI;

提供读取显示设备的属性信息接口,包括屏幕尺寸GetXSize和GetYSize,每个像素点的位数GetBPP,以及初始化调色板InitPalette。

1.2 应用接口层

应用接口层负责给用户提供系统的应用编程接口,方便系统扩展。用户程序通过调用应用接口层封装的接口函数完成界面设计以及数据逻辑的处理,LIGUI负责输入事件响应,消息的接受和分发,以及显示的更新。

应用编程接口为用户提供如下对象的操作:

作图原语集:完成LIGUI的绘图功能;

窗口类对象:实现对窗口的组织和操作;

控件类对象:完成对控件的管理和使用。

应用接口层提供可配置选项,可以实现对LIGUI系统的裁剪和配置,以满足具体应用环境的需求。

2 LIGUI系统内核设计与实现

核心层实现LIGUI的关键功能,采用模块化设计,模块之间低耦合,内部结构的修改不影响其接口,可以有效支持裁剪,满足系统轻量级的需求[7]。核心层包括图形图像模块、窗口管理模块和消息系统。

图形图像模块提供图形、文本和各种图像的绘制,窗口与消息模块完成窗口组织和操作,输入输出事件消息和窗口消息的分发。

2.1 图形图像模块

图形图像模块实现图形图像和文本的绘制输出,调用输出抽象层提供的显示设备接口,在单个像素点绘制的基础上完成图形图像的绘制。向上层以作图原语集的形式为应用提供调用接口。

2.1.1 基本图形绘制

向上层LIGUI对象提供基本绘图原语的图形服务,完成基本几何图形的绘制和填充,如点、直线、圆、矩形、椭圆、多边形等。

支持与设备无关的图形操作,所有绘图函数都以显示设备接口SetPixel为基础,从绘制一个像素点出发,而线段是由点连接组成,多边形的绘制、填充也是由点和线段组合而成的,进而完成全部显示区域的绘制。

对于图形图像绘制而言,直线和圆弧作为描述所有图形的基础,其效率直接影响到整个LIGUI系统的显示效率。采用改进的Bresenham算法绘制直线和圆弧,充分利用图形斜率的几何特性和点与点之间的相关性,一次可计算出若干个点,提高了绘制效率[8]。

2.1.2 文本输出

文本输出功能向屏幕显示字符和汉字,完成字符在字符集中的查找和绘制输出。

为提高显示效率和节省资源空间,LIGUI采用点阵字体,单独用数组来定义每个字符的点阵,然后将每一个字符的信息用CHAR_INFO结构体来表示。

typedef struct{

U8XSize;

U8YSize;

U8BytesPerLine;

const U8*pData;

}CHAR_INFO;

结构体中定义的字符信息包括字符点阵的高和宽,每行的字节数,以及字符点阵数据指针。

将所有字符信息存入一个数组中构成字符集。由于汉字的机内码不连续,是区间分布的,所以将所有汉字分成若干个字符集区段,各个字符集区段以链表组织起来。如下的FONT_INFO为字符集区段的数据结构,包括字符集区段中首末字符的索引FirstChar和LastChar,首个字符信息的指针pCharInfo和指向下一个字符集区段的指针pNext。

typedef struct{

U16FirstChar;

U16LastChar;

const CHAR_INFO*pCharInfo;

const FONT_INFO*pNext;

}FONT_INFO;

利用汉字的机内码对字符集链表进行索引,先找到要显示字符所在的字符集区段,返回字符集区段的指针,再根据字符相对字符集区段中第一个字符地址的偏移量,找到要显示字符的字符信息。

2.1.3 图像模块

LIGUI支持显示BMP格式的图像文件,BMP文件本身就包含了设备无关位图格式,经文件调用读入内存,再结合显示设备特性转换成设备相关位图[9]。

同时,LIGUI支持其它图像格式绘制的接口,其文件解码都使用第三方标准库来完成,然后将位图选入到图形设备上下文中,以便上层应用程序进行绘图操作。

2.2 窗口管理模块

窗口管理模块负责窗口组织、窗口绘制和窗口操作,是LIGUI系统组织图形图像输出,处理外设输入的基础。

由于嵌入式应用的显示屏一般不大,窗口可以独占整个屏幕,不必考虑相互剪切的位置关系。LIGUI系统的窗口组织采用双向链表结构,如图2所示。

图2 窗口组织结构

窗口创建时即建立一个节点,窗口中的控件继承了窗口的特性,并且加入窗口节点。节点与节点之间组成一个链表。当删除窗口时,将窗口从窗口链表中移除,并递归销毁其所有子控件。窗口链表还能表示窗口之间的覆盖关系,链表后端的窗口覆盖前端的窗口,所以对窗口进行前置、后置操作即相当于在窗口链表上向前或向后移动窗口节点。

LIGUI用WIN_Obj结构体来描述窗口,这个结构中记录了窗口对象的基本性质和窗口函数等属性。

typedef struct{

int hWin;

int x0,y0,x1,y1;

U8*title;

WIN_Obj*pPre;

WIN_Obj*pNext;

int hFocussedChild;

int WidgetNum;

void(*WinManage)(MSG_Obj*pMsg);

int StatusFlag;

}WIN_Obj;

其中,hWin是系统中窗口对象全局唯一的标识,即窗口对象的句柄;x0,y0,x1,y1是窗口矩形区域的坐标值,存储窗口的位置和大小;title指向窗口标题字符串;pPre和pNext为指向链表中上一个窗口节点和下一个节点的指针;hFocussedChild为处于焦点的子控件的句柄,Widget-Num为窗口子控件的数目;WinManage是窗口过程函数指针,完成各种消息的响应处理;StatusFlag存储窗口的状态信息。

2.3 消息系统

LIGUI系统采用事件驱动机制。消息系统是事件驱动的图形用户界面的关键,保障整个系统流程有序进行,消息由事件产生[10],LIGUI的事件包括输入设备事件,窗口操作事件,以及系统定时、用户自定义等其它事件。

事件的产生具有随机性,LIGUI用消息表示各种事件。在外设驱动和输入抽象层提供的硬件接口基础上,用消息结构封装实现用户输入事件,转化为输入消息;系统运行过程中引起的窗口状态改变,会产生与窗口操作相关的逻辑消息;同时,用户可以自定义消息和响应处理。

将不同类型的消息用一个消息结构表示,并且定义类型字段来区分各种消息类型。如下MSG_Obj为消息对象结构体,用于表示事件消息。

typedef struct{

int MsgID;

int hWinTag;

int hWinSrc;

int MsgData;

void*p;

}MSG_Obj;

其中,用MsgID作为类型字段来区分不同的消息类型;hWinTag和hWinSrc分别为接受消息的目标窗口句柄和消息源窗口句柄;MsgData用于存储消息具体数据,如果数据超过整形范围可以用数据指针p表示。

2.3.1 消息系统结构

消息系统结构如图3所示,包括消息队列、消息循环和窗口过程等。

图3 消息系统结构

同步消息经过消息循环直接交给窗口过程函数处理,异步消息进入消息队列等待处理。

消息队列组织异步消息,负责事件压缩和过滤重复无用的事件消息。

消息循环从消息队列读取消息,发送至目标窗口,窗口过程函数将消息结构作为参数,执行相应的消息响应过程。

2.3.2 消息循环

消息循环是消息系统和图形用户界面应用程序的核心部分,是将从消息队列轮询获得的消息分发至目标窗口的循环过程[11]。消息循环流程如图4所示。

图4 消息循环

消息循环不断轮询消息队列,若队列为空,则执行空消息处理,若不为空且不是退出消息,则调用消息发送函数进行分发和投递,送达目的窗口,即调用指定窗口的窗口过程函数,并传递消息为其参数。目标窗口的窗口过程负责解释所接收的消息,由MsgID确定具体的消息类型,进行分类处理。处理结束后,重新进入消息循环,当收到退出消息时,退出消息循环。

LIGUI系统采用的这种消息机制支持用户自定义消息,利用自定义的消息传递数据,并且在窗口过程对自定义消息类型进行处理,满足了嵌入式GUI系统对扩展性的需求。

3 应用实例

LIGUI系统现已应用在太阳能控制器配套的手持设备中,用于对太阳能控制器进行参数设定和管理。手持控制器如图5所示。

图5 手持控制器

手持控制器采用基于Cortex-M3内核的STM32F103VBT6处理器,外扩Flash存储器采用SST25VF016B芯片,用于存储字库和位图的点阵文件,其它外设包括液晶显示屏、红外收发器、矩阵键盘、蜂鸣器、LED指示灯和RS232/485通信口。

手持控制器作为太阳能控制器的图形化显示和操作控制终端,采用2.6寸TFT彩色液晶,像素点总数为320×240。其图形用户界面的显示基于LIGUI体系结构实现,采用层次化、模块化的结构设计来组织各参数设置界面之间的逻辑关系,界面显示及切换流畅,使用方便、灵活。其界面结构图如图6所示。

图6 界面结构

实现手持控制器的界面显示,LIGUI核心部分代码所占用静态存储空间不足30KB。通过调用LIGUI系统提供的应用编程接口和修改配置选项,编程开发者只需编写底层硬件驱动和进行数据逻辑处理,开发周期短,效率高。

4 结束语

采用分层次和模块化的结构体系,设计并实现了一种轻量级嵌入式图形用户界面LIGUI系统。系统通过硬件抽象层来隔离不同底层设备;采用高效的算法进行图形图像绘制;在应用接口层为用户提供已封装的应用编程接口,提高了开发编程效率。

将实现的LIGUI系统作为图形显示模块应用于手持控制设备,解决了自底层到顶层的GUI开发方法导致的开发效率低、代码复用性差的问题。实际应用表明,LIGUI系统具有轻型的特点,占用资源少,且功能齐全,能够支持运行在低端配置的系统。系统配置选项提供窗口、控件等模块的裁剪,可以实现具体嵌入式环境下的定制和扩展。

[1]Bjelica M Z,Teslic N,Papp I,et al.A characterization to evaluate graphical user interface frameworks for television receivers[C].The 9th International Conference on Telecommunication in Modern Satellite,Cable,and Broadcasting Services(TELSIKS),2009:285-288.

[2]Scoditti A,Stuerzlinger W.A new layout method for graphical user interfaces [C].The IEEE Toronto International Con-ference on Science and Technology for Humanity.2009:642-647.

[3]Greg Haerr.The Nano-X Window system [EB/OL].http://www.microwindows.org,2010.

[4]Trolltech Inc Qt/Embedded Whitepaper [EB/OL].http://www.trolltech.com/files/pdf/qt-4.6-whitepaper,2009.

[5]Beijing Feynman Software Technology Co,Ltd.MiniGUI technology white paper [EB/OL].http://www.minigui.org/fileadmin/minigui_org_downloads/MiniGUITechWhitePaper-2.0-4E.pdf,2007.

[6]Bode S,Riebisch M.Usability-focused architectural design for graphical user interface components [C].The International Conference on Computational Intelligence for Modelling Control& Automation,2008:1246-1251.

[7]Lamberti F,Sanna A.Extensible GUIs for remote application control on mobile devices [J].IEEE Computer Graphics and Applications,2008,28 (4):50-57.

[8]LOU Jiantao,WANG Xiuhe.Anti-aliasing line drawing algorithm based on symmetry [J].Computer Engineering and Applications,2011,47 (1):173-175 (in Chinese). [楼剑涛,王秀和.基于对称的反走样直线生成算法 [J].计算机工程与应用,2011,47 (1):173-175.]

[9]Luostarinen R,Manner J,M tt J,et al.User-centered design of graphical user interfaces [C].Military Communications Conference,2010:50-55.

[10]Yoshida M.A succinct graphical user interface programming model for low-end embedded devices [C].The 13th IEEE International Symposium on Consumer Electronics,2009:920-921.

[11]HE Xiang,MENG Xiaohua.Design and implementation of humancomputer interface in embedded intelligent home system [J].Computer Engineering and Design,2010,31 (10):2166-2168 (in Chinese).[贺翔,孟小华.嵌入式智能家居终端人机界面设计与实现 [J].计算机工程与设计,2010,31 (10):2166-2168.]

猜你喜欢

链表图形图像字符
Photoshop图形图像处理线上线下混合式教学模式探究
论高级用字阶段汉字系统选择字符的几个原则
如何用链表实现一元多项式相加
字符代表几
一种USB接口字符液晶控制器设计
图片轻松变身ASCⅡ艺术画
跟麦咭学编程
浅析计算机图形图像处理技术偏技术
基于MTF规则的非阻塞自组织链表
网页设计与图形图像处理技术探析