杨晓东 糜元根
南京工业大学信息科学与工程学院 江苏 210009
本系统在用户操作过程中,把交互信息写入本地数据库,并且同时更新远程数据库。系统设计两个数据库的目的也是为了在网络不顺畅的时候,用户也可以及时购电。管理员可以在远程数据库上对用户数据进行统一管理。
为了与用户有很好的交互性,需要设计图形界面便于用户操作。常见的图形界面设计方法是QT和MiniGUI,综合考虑了系统的硬件,本系统采用MiniGUI进行图形界面设计。MiniGUI是由北京飞漫软件技术有限公司主持的自由软件,遵循GPL条款发布。其目的是为实时嵌入式Linux系统建立一个快速、稳定和轻量级的图形用户界面支持系统。本系统采用的MiniGUI 1.3.1版本,可以从http://www. minigui.com上下载。
用于处理事件的窗口例程通常标志了某一个“窗口类”,具有相同窗口例程的窗口实例被认为是属于同一窗口类。
焦点和光标的概念用于管理输入设备和输入事件的发送。鼠标光标是一个绘制在屏幕之上的小位图,指示当前的鼠标位置。以某种非破坏性的方式绘制该位图是窗口系统的责任,不过应用程序可以控制绘制哪一个位图以及是否显示该光标。应用程序还可以捕捉鼠标光标并获取光标事件,即使该光标已经超出该应用程序窗口的显示范围。键盘输入有类似的输入焦点和键盘输入插入符的概念。只有具有输入焦点的窗口才能获取键盘事件。改变窗口的焦点通常由特殊的按键组合或者鼠标光标事件完成。具有输入焦点的窗口通常绘制有一个键盘插入符。该插入符的存在、形式、位置,以及该插入符的控制完全是由窗口的事件处理例程完成的。
应用程序可通过调用一些系统函数来要求重绘窗口或窗口的某一部分,这些事件通常由窗口例程来处理。
1.1.1 事件驱动编程
1.1.2 MiniGUI-Lite和MiniGUI-Threads
MiniGUI是一个图形用户界面支持系统,通常的GUI编程概念均适用于MiniGUI编程,如窗口和事件驱动编程等。
在传统的GUI图形系统模型中,键盘和鼠标动作产生由应用程序不断轮询的事件。这些事件通常发送到具有焦点的窗口,而应用程序把这些事件交由和该窗口相关联的例程来处理。这些窗口例程通常是由应用程序定义的,或者是某些标准例程中的一个。操作系统、其它窗口的事件处理例程和应用程序代码都可以产生事件。
在编写第一个MiniGUI程序之前,我们需要了解一个事实:我们可将MiniGUI配置编译成两个架构上截然不同的版本——MiniGUI-Lite版或MiniGUI-Threads版。
MiniGUI的早期版本(即 MiniGUI-Threads)采用基于POSIX线程的消息传递和窗口管理机制,这种实现提供最大程度上的数据共享,但同时造成了MiniGUI体系结构上的脆弱。
如果某个线程因为非法的数据访问而终止运行,则整个系统将受到影响。为了解决这个问题,使MiniGUI更符合嵌入式系统的应用需求,MiniGUI从0.98开始推出Lite版本。Lite版本的MiniGUI使用进程机制,抛弃了pThread库,从而使得MiniGUI更稳定和更高效率。
在 MiniGUI Lite版本中,我们可以同时运行多个MiniGUI应用程序。首先我们启动一个服务器程序mginit,然后我们可以启动其他作为客户端运行的 MiniGUI应用程序。如果因为某种原因客户终止,服务器不受影响,可以继续运行。
MiniGUI-Lite区别于MiniGUI-Threads的最大不同在于我们可以在MiniGUI-Lite程序中创建多个窗口,但不能启动新的线程建立窗口。除此之外,其他几乎所有的 API都和MiniGUI原有版本是兼容的。
MiniGUI-Threads适合于多窗口、实时性要求很高的系统,比如工业控制系统;而MiniGUI-Lite适合于功能丰富、结构复杂系统,比如PDA等信息产品。而且MiniGUI-Threads可以通过MiniGUI的消息函数,可在不同的线程之间传递消息,相比较而言,本系统采用前者。
1.1.3 窗口及窗口过程
窗口是屏幕上的一个矩形区域。在传统的窗口系统模型中,应用程序的可视部分由一个或多个窗口构成。每一个窗口代表屏幕上的一块绘制区域,窗口系统控制该绘制区域到实际屏幕的映射,也就是控制窗口的位置、大小和可见区域。每个窗口被分配一个屏幕绘制区域来显示本窗口的部分或全部,也许根本没有分配到屏幕区域(该窗口完全被其它的重叠窗口所覆盖和隐藏)。
MiniGUI中有三种窗口类型:主窗口、对话框和控件窗口(子窗口)。每一个MiniGUI应用程序一般都要创建一个主窗口,作为应用程序的主界面或开始界面。主窗口通常包括一些子窗口,这些子窗口通常是控件窗口,也可以是自定义窗口类。应用程序还会创建其它类型的窗口,例如对话框和消息框。对话框本质上就是主窗口,应用程序一般通过对话框提示用户进行输入操作。消息框是用于给用户一些提示或警告的主窗口,属于内建的对话框类型。
一旦窗口建立之后,窗口就会从消息队列当中获取属于自己的消息,然后交由它的窗口过程进行处理。窗口过程函数主要是对属于该窗体的不同消息进行相应的处理。窗口过程函数通常使用switch语句来对各种消息(message)进行处理。
当前,Socket接口是TCP/IP网络最为通用的API,也是在Internet上进行应用开发最为通用的API。它是介于应用层和传输层之间的编程接口,它提供了访问下层通信协议的大量系统调用和相应的数据结构功能。在Linux系统中,Socket是应用程序访问下层网络协议的惟一方法。具体地讲,Socket在用户级实现了两个应用程序之间的网络连接和数据交换,所以Linux中的Socket意味着网络上的通信。
我们在做网络传输数据功能时,采用了客户端/服务器(C/S)网络通信:服务器端守护进程不断的监听、等待连接;客户端向远程服务器发送连接请求,服务器端收到请求后,按照一定的规则建立连接,连接完成后,两个程序之间就建立了一个虚拟的数据通信链路。这些程序可以直接从自己打开的套接口读入和写出数据,而不用关心实际的数据链路。具体实现过程见图1。
图1 基于TCP协议的socket传输流程图
SQLite是2000年开发出来的一种小型嵌入式数据库。它是一个小型的C语言链接库,这个链接库本身就完全包含数据库引擎的功能,可以方便地运用于嵌入式系统中。SQLite提供了对SQL92的大多数支持,支持多表、索引、事务、视图和触发等一系列用户接口以及驱动。简单易用,速度也相当得快,同时提供了丰富的数据库接口。这个库具有很强的内聚性,通过不到25000行的ANSIC代码实现,而且它的源代码完全开放,可以自由地应用于任何领域。
在与MiniGUI的连接中,SQLite的API及其易于使用,完全可以对嵌入式数据库进行基本的操作,如建立表格、查询、修改、插入、删除、排序等,只需要三个用来执行SQL和获取数据的函数。此外它还是可以扩展的,允许自定义函数,然后以Callback(回调函数)的形式传递进去。
本系统的软件设计分为客户端(终端)程序设计和服务器端程序设计,主要是客户端程序设计,服务器端主要是一个接收数据并更新数据库的守护进程程序。
在客户端,登录系统后进入主界面,主界面包括6个功能界面选择按钮,具体系统流程如图2所示。
图2 系统主流程图
数据库服务器端采用 Fedora 7作为服务器操作系统,sqlite3作为数据库,系统启动后自动运行守护进程,这包括:建立套接字、绑定地址、开始监听并等待客户端的连接,收到数据后更新本地数据库,并将操作记录写入设定好的日志文件中,循环执行以上过程。服务器端流程图如图3所示。
图3 服务器端流程图
经测试,本系统完全符合人性化设计,购电方便,操作系统界面友好,简单。每个用户必须凭ID和密码才能登录,同时密码忘记后可以通过短信猫将密码发送到用户账号登记的手机中,从而大大的增强了系统的安全性。在有网络的情况下,本地数据库能与远程数据库及时更新,做到数据实时准确无误。稍微有点遗憾的是,由于本系统过于庞大未能全面展开。
[1] 韩超.嵌入式GUI开发设计—基于MiniGUI[M].北京:电子工业出版社.2009.
[2] 李亚锋,欧文盛. ARM嵌入式Linux系统开发从入门到精通[M].北京:清华大学出版社.2007.