摘要:分析了嵌入式实时操作系统VxWorks及媒体库WindML的结构和特点。应用WindML提供的API函数,给出了VxWorks操作系统下键盘输入响应及图形界面输出的程序实现。 一 前言 随着多媒体信息技术、互连网、消费类电子产品的发展,嵌入式操作系统由于其占用内存少、可裁减、稳定性好的特点正得到越来越广泛的应用。VxWorks是一种由美国WRS(Wind River Systems Inc.)公司开发的典型的嵌入式实时多任务操作系统(RTOS),具有高可靠性、高实时性和对于异步、并行的事件可以在严格的时限内作出响应等特点。基于VxWorks的系统的输入、输出一般可应用WRS公司提供的媒体库——WindML(Wind Media Library)进行开发。本文结合VxWorks在随动监控系统中的应用,讨论应用WindML进行事件响应以及屏幕输出的技术和机制。 二 实时操作系统VxWorks简介 VxWorks是由美国WRS(Wind River Systems Inc.)公司开发的一套微内核、高可靠性、可裁减的嵌入式实时操作系统。VxWorks实时内核Wind提供了基本的多任务环境及对任务的管理。多任务使得许多程序在表面上表现为并发执行,而事实上内核是根据基本的调度算法使他们分段执行。每个明显独立的程序被设置成为一个任务。每个任务拥有自己的上下文,其中包含内核调度使该任务执行的时候它所看到的CPU环境和系统资源。 VxWorks 提供256个任务优先级,默认采用基于优先级的抢占式调度算法,也可以选用基于时间片的轮转调度算法。任务间切换、任务上下文的保存可以在极短时间内完成。同时,VxWorks提供了丰富的任务间通信机制,主要包括:共享内存、信号量、消息队列和管道、套接字、信号等。VxWorks主要组成部分见图1。 图1 VxWorks 体系结构 三 WindML结构 WindML是WRS公司提供的VxWorks 库的一部分,用来为各种不同的操作系统和开发标准用户设备驱动程序的框架,提供基本的图形、图象和音频的支持。WindML API函数库提供对多种CPU结构和操作系统适用的图形硬件接口。同时WindML还提供操作输入设备和处理输入设备事件的功能。 WindML由两部分组成:软件开发包(SDK)和硬件开发包(DDK)。SDK提供应用程序代码和底层硬件驱动程序的接口,包括图形、输入句柄、多媒体、字体、和内存管理的API函数,使开发人员可以对不同硬件平台开发与底层硬件无关的便携代码。DDK则对通用硬件设置提供完整的驱动程序。其层次结构见图2。 图2 WindML层次结构 四.输入输出的程序实现 在第一次应用WindML库之前,必须对目标机的WindML库进行设置。WindML的设置有两种方式,可以通过Tornado下的WindML设置工具;也可以通过直接编辑头文件和源文件(target/src/ugl/config/uglInit.h 和target/src/ugl/config/uglInit.c)进行设置。直接编辑的方式可完成设置工具未提供的用户特定的设置。 下面针对键盘输入响应和屏幕字符、图形输出的程序实现方法加以讨论,给出例程。 1. 键盘响应的程序实现 第一步,初始化定义数据结构 static UGL_EVENT_SERVICE_ID eventServiceId; // 定义事件服务ID static UGL_EVENT_HANDLER_ID eventHandlerId; // 定义事件处理ID static UGL_EVENT_Q_ID qId; // 定义事件消息队列ID static UGL_EVENT event; // 定义事件 static UGL_STATUS status; // 定义UGL状态 第二步,获得输入设备ID,产生输入队列 uglDriverFind (UGL_EVENT_SERVICE_TYPE, 0, (UGL_UINT32 *)&eventServiceId ); // 获得输入事件服务设备驱动 qId = uglEventQCreate (eventServiceId, 100); // 产生事件消息队列 第三步,根据键盘输入,响应键盘 UGL_FOREVER { status = uglEventGet (qId, &event, sizeof (event), UGL_WAIT_FOREVER); if (status != UGL_STATUS_Q_EMPTY) { UGL_INPUT_EVENT * pInputEvent = (UGL_INPUT_EVENT *)&event; //定义输入事件结构指针并赋值 c=pInputEvent->type.keybord.key; swich(c) { …… case ALT_H: …… case ALT_V: …… …… } } }
2. 字符、图形界面的显示 字符和图形在显示之前都必须首先初始化WindML。WindML初始化通过调用API函数uglInitialize()实现。然后,需要获得输出和字体驱动和服务ID号,可以通过调用uglDriverFind()获得。对于图形显示,还需要产生一个图形环境。对于字符输出,应先设置字体驱动程序,由函数uglFontDriverInfo()完成。由于许多嵌入式系统只提供少数的有限字体选择,因此一般还需要应用uglFontFind()函数找到系统提供的与所要显示字体最相匹配的字体。找到后由uglFontCreate()函数生成该字体。具体程序实现如下: UGL_LOCAL void windMLDemo () { …… static UGL_FONT_DRIVER_ID fontDrvId; // 定义数据结构 static UGL_FONT_ID fontDialog ; UGL_FONT_DEF FontDef ; UGL_GC_ID gc; // ************** // static UGL_CHAR * text = "input and output example."; gc = uglGcCreate(devId); // 生成图形环境 /* 获得字体驱动 */ uglDriverFind (UGL_FONT_ENGINE_TYPE, 0, (UGL_UINT32 *)&fontDrvId); uglFontDriverInfo(fontDrvId, UGL_FONT_TEXT_ORIGIN, &textOrigin); /* 找到、生成匹配字体 */ uglFontFindString(fontDrvId, "familyName=Lucida; pixelSize = 12", &FontDef); if ((fontDialog = uglFontCreate(fontDrvId, &systemFontDef)) == UGL_NULL) { printf("Font not found. Exiting./n"); return; } uglFontSet(gc, fontDialog); // 设置字符样式 uglTextDraw(gc, displayWidth ,displayHeight , -1, text); // 显示输出字符 uglBatchStart(gc); uglForegroundColorSet(gc, colorTable[BLUE].uglColor); // 设置颜色 uglLine(gc, 10, 10,200,200); // 画线 uglEllipse(gc, left, top, right, bottom, 0, 0, 0, 0); // 画椭圆 uglRectangle(gc, left, top , right, bottom); // 画矩形 uglBatchEnd(gc); …… } 五.结束语 应用WRS公司提供的媒体库——WindML(Wind Media Library)进行事件响应和图形界面的开发是嵌入式系统VxWorks下输入、输出开发的主要方法。应用本文给出的例程可以快速的实现VxWorks系统下图形用户界面的开发。该方法已经在基于VxWorks开发的某型舰炮的随动监控系统中得到了良好的应用。 参考文献 [1] 孔祥营,柏桂枝编著. 嵌入式实时操作系统VxWorks及其开发环境Tornado. 北京: 中国电力出版社,2002 [2] VxWorks programmer's Guide 5.3.1.,Wind River systems Inc. ,1997 [3] Tornado User's Guide, Wind River Systems Inc.,1999 [4] WindML2.0 Programmer’s Guide[Z], Wind River Systems Inc.,2000
|