李 宽, 张丽芸, 陈玉冲
(1. 上海船舶运输科学研究所 舰船自动化系统事业部, 上海 200135;2. 渤海造船厂集团设计院, 辽宁 葫芦岛 125004)
随着航海事业的不断发展,机舱监控系统在提高船舶的自动化水平、保证船舶安全航行等方面起着越来越重要的作用。随着机舱自动化程度的不断提高,实时嵌入式操作系统VxWorks在现代机舱监控系统中的应用越来越广泛。机舱监控系统是由多种监控设备组合而成的复杂的人机系统,需机电人员对大量信息进行快速处理,因此对人机交互界面的要求较高。机舱监控系统需对机舱设备的参数、运行状态和故障报警等信息进行显示和操作,其图形界面在满足传统图形用户界面方案要求的同时,还应具有很高的实时性和可扩展性。美国 WRS 公司开发的媒体库(Wind Media Library,WindML)满足这些要求,且具有占用内存少、可移植性强和高性能等特点。
VxWorks 是由美国风河公司开发的具有微内核、高可靠性、高实时性和可裁减等特点的嵌入式实时操作系统。VxWorks 提供有图形开发组件WindML,在VxWorks一般的界面开发应用中,可使用WindML进行图形界面设计。WindML可为运行在嵌入式系统上的多媒体应用程序提供支持,能用来开发可定制的标准化设备驱动程序的框架。
WindML包含软件开发工具包(SDK)和驱动开发工具包(DDK)2个组件,其中:SDK用来实现应用程序的开发;DDK用来实现驱动程序的开发。WindML能满足嵌入式计算机的所有图形要求,保证开发人员在VxWorks实时操作系统上建造功能齐全、丰富多彩、可嵌入式的图形界面。[1]
图形显示由底层图片、文字、数字和符号等共同组成,原理见图1。
图1 图形显示原理
WindML本身不支持汉字显示,可通过调用点阵字库等方法来解决该问题。在中文环境下,输入的是汉字的内码,若要显示汉字,需进行点阵寻址,找到该汉字内码的字模信息在汉字库中的位置,取出该字模信息进行点阵显示。
WindML的图形界面基于像素,用颜色匹配表说明位图中的颜色。首先在颜色匹配表上设置一种颜色的红、绿、蓝亮度值,然后用位图阵列中的每个像素值索引值代表该点在颜色匹配表中的颜色。
在显示图形之前,须先调用WindML的API函数uglInitialize()进行初始化,并产生一个图形环境。在WindML中,一般会在使用一组画图函数之前用uglBatchStart()通过互斥信号量锁定图形上下文、图形设备和缓冲,以防止多线程之间产生资源冲突。在画图操作完成之后,只有用 uglBatchEnd()释放被锁定的资源,其他画图函数才可使用。[2]
在船舶监控系统中,由于需实时采集、显示机舱各设备的状态和报警信息等,每次采集到数据和各界面互相切换时都要实时刷新画面,而刷新时会出现画面闪烁和剧烈抖动等现象。
画面闪烁的根本原因是相邻两帧图像之间存在巨大的差异。当需显示新的图形或使原来显示的图形发生变化时,需刷新背景,用背景颜色的画刷将背景重新刷一遍,原图形将被覆盖,此时画上新图形即可完成图形的刷新显示或动态显示。但是,由于背景颜色(一般是白色)与图形颜色之间存在反差,在不断地重复刷新、显示的过程中会产生闪烁。闪烁本质上就是反差,反差越大,闪烁越厉害。因此,当窗口由于切换界面或数据更新需重绘时,首先清除显示区背景色,然后才调用OnPaint函数进行重绘。背景色与绘图内容的反差经常很大,导致背景色与显示图形在短时间内反复切换,造成显示窗口出现闪烁现象。
针对刷新时画面经常出现闪烁、抖动现象的问题,初期处理方式是以位图背景的形式将图形界面中的固定信息保存起来,调用uglDefault—BitmapSet()来实现,在该背景上动态刷新变化的测点信息、报警等。在该方式下刷新画面时数据量会减少,画面的闪烁现象有所改善,但因采集到的监测数据、设备的运行状态等是实时变化的[3],且图形缓冲显示方式不变,小频率或少量的数据刷新依然会引起画面闪烁、抖动现象。
传统的绘图方式是采用单缓冲技术,而要解决图形界面开发过程中刷新图像时遇到的闪烁、抖动问题,需依靠双缓存方式下的双缓冲图形刷新技术来实现。
在系统中,所有设备都有一个被称为设备描述表的内存缓冲区与其对应。传统的绘图方式(单缓冲)是将图形绘制在唯一的内存缓冲区中,由图形设备接口自动将内存缓冲区中的图像复制到显存中显示。双缓冲图形刷新技术在内存中有2片缓存区,分别为前端缓冲区和预先使用函数uglPageDrawSet( )手动建立的与前端缓冲区兼容的后端缓冲区。在绘图过程中,首先将下一帧要显示的图像绘制到后端缓冲区,然后将后端缓冲区中的图像复制到前端缓冲区,最后由图形设备接口自动将前端缓冲区中待显示的图像复制到显存中,完成图形显示。
单缓冲技术和双缓冲技术基本原理见图2。
a) 单缓冲技术b) 双缓冲技术
图2单缓冲技术和双缓冲技术基本原理
在图形界面开发过程中,在同一图形界面背景下,背景图、标题栏、单位和量程等图像内容不变,需不断进行更新的只有实时监测的数据。结合前述双缓冲技术,可首先将固定不变的内容在不可见的后台屏幕上分层绘制,然后将其他各层的内容透明粘贴到背景层的相应位置上,最后再将其复制到屏幕显示区域进行显示。由于固定不变的图层无需重复绘制,因此可加快界面刷新速度。
1) 使用pentiumM 系列主板搭建硬件环境,并准备好VxWorks5.5.1 + WindML3.0 的软件调试环境;
2) 新建一个 bootable 类型的 VxWorks 工程;
3) 将 gmch.o 库文件添加到创建的工程路径下;
4) 将 windML_INTEL_GMCH_DB.cfg 文件放置在C:Tornado221host esourcewindMLconfigdatabase 路径下(本文假设VxWorks 开发环境安装在 C:Tornado221 路径下);
5) 将 gmchcfg.h 文件放置在C:Tornado221 argethugldrivergraphicsintel 路径下(本文假设. VxWorks 开发环境安装在 C:Tornado221 路径下);
6) 对 WindML3.0 进行配置(见图3)。
图3 WindML3.0配置界面
图4 双缓冲流程图
在具体实现中,首先创建前后双缓冲页, 调用uglPageDrawSet ( )函数设置活动的双缓冲页,使监测数据、设备状态和报警等过程在Off_Screen(后台)实现。在绘制当前数据信息时,调用函数uglPageDrawSet( )另外指定绘制下一图形操作的页面(缓冲)。在绘制完成之后,通过 uglPagevisableSet( )将后台的图像拷贝到前台,实现双缓冲图形的界面切换。双缓冲流程图见图4。
部分实现代码如下:
dispPage[0] = UGL_PAGE_ZERO_ID;
dispPage[1] = uglPageCreate(devId);//创建双缓冲页
uglPageDrawSet(devId, dispPage[1]);//设置活动页
sprintf(pageName, "%s%d%s","/ata0a/rPage",fileNumber,".jpg");
uglJpegToDDBFromFile (jpegId, pageFile, &jpegDdbPageId, UGL_NULL, 0, 0);
uglBitmapSizeGet(jpegDdbPageId, &jpegWidth1, &jpegHeight1);//图片加载
uglTextDraw(gc, dispAna[i].xPoint, dispAna[i].yPoint, -1, LDMDispAna[i]);//字符显示
uglTextDrawW(gc, dispAna[i].xPoint, dispAna[i].yPoint, dispAna[i].dispLen, (UGL_WCHAR *)dispAna[i].dispName[dispAna[i].value] );//汉字显示
uglBitmapBlt(gc, jpegDdbPageId, 0, 0, jpegWidth1 - 1, jpegHeight1 - 1, UGL_DEFAULT_ID, 0, 0);//位图绘制
if(pageIndex == 1)
{
uglPageVisibleSet(devId, dispPage[1]);
uglPageDrawSet(devId, dispPage[0]);
pageIndex = 0;
}
else
{
uglPageVisibleSet(devId, dispPage[0]);
uglPageDrawSet(devId, dispPage[1]);
pageIndex = 1;
}//双缓冲界面切换
由于采用双缓冲技术时需在内存中新建一个临时缓存区,因此新建一个临时位图对象作为画布并绑定临时缓存区。绘图在该缓存区中进行,当所有图形绘制完成之后,将临时缓存区中的位图对象贴到显示缓存区中,由于内存中的图形与屏幕显示的图形差别很小,可消除刷新屏幕时出现的闪烁、抖动现象。
显示单元监控界面效果见图5。
图5 显示单元监控界面效果
随着监控系统技术的不断发展,对监控系统实用性、可靠性和安全性的要求会越来越高,恶劣环境下的机舱图形界面开发技术将是今后一段时期的发展重点。本文对VxWorks图形显示原理、闪屏分析、双缓冲技术及具体应用进行介绍,VxWorks提供的多媒体组件WindML双缓冲技术已成功应用于实际工程开发中,取得了良好的效果。