APP下载

基于Cairo的组合式仪表HMI系统设计

2021-10-28郭健忠

计算机技术与发展 2021年10期
关键词:图层嵌入式内存

郭健忠,耿 屹,谢 斌,闵 锐

(1.武汉科技大学 汽车与交通工程学院,湖北 武汉 430065; 2.武汉保华显示科技有限公司,湖北 武汉 430081)

0 引 言

随着智能网联汽车、高级辅助驾驶等技术的发展,数字仪表作为车况信息显示终端被广泛应用于汽车电子系统中[1-2]。作为数字仪表的一种,组合式仪表由低成本微处理单元(MPU)、5至8英寸液晶显示屏、机械指针或断码屏组合而成,相较于全液晶仪表,其显示效果与信息呈现形式存在一定差距[3]。人机交互界面(HMI)是汽车数字仪表的核心功能之一,承担驾驶员与汽车信息交互的功能[4-5]。传统HMI软件通常借助MiniGUI[6-7]、Qt/Embedded[8]等嵌入式图形用户界面(GUI)框架开发,应用于窗口化而非全屏模式的应用场景,UI界面响应鼠标、键盘等输入信号,未针对汽车HMI以总线信号为触发源的信号环境进行优化。在移植方式上,传统框架需要将自身框架源码跨平台编译至目标平台,移植方式较为繁琐[9]。Cairo图形库具备跨平台、轻量化、可定制性强等特性[10],本设计基于Cairo图形库构建虚拟HMI平台和嵌入式平台,创新跨平台开发方式,简化开发与移植流程,针对低成本嵌入式平台,从多维度设计并优化HMI软件,提高软硬件运行效率,以更低成本实现可靠的功能性及更佳的显示效果。

1 汽车仪表HMI设计与优化

1.1 HMI图层与场景

汽车仪表HMI一般由图1左侧所示的背景图层、仪表盘指针图层、状态指示灯图层和报警/菜单显示图层组成,由于图层结构相对固定,图形库渲染时按照从下至上的顺序对图层进行堆叠渲染。图层由如图1右侧所示的一个或多个场景组成,场景中包含图片、文字以及动画效果等元素,场景中包含的元素内容、显示内容及触发方式均与总线数据逐一对应,例如仪表盘指针图层与背景图层根据总线信号中关于当前驾驶模式的数据,分别显示ECO、SPORT和标准模式场景以提供不同的主题色彩和显示效果;报警/菜单图层则根据总线信号中当前菜单的索引数据和报警数据触发相应的菜单或报警场景。

图1 汽车仪表HMI图层及场景示意图

1.2 场景设计与导出

HMI图层与场景采用Fairy GUI软件进行设计和导出,Fairy GUI是一款用于软件或游戏的UI设计软件,可提供跨平台UI设计解决方案[11]。该软件支持在工程设计树中以包和组件的方式管理HMI图层和场景,可在场景中导入界面元素,为每个场景内元素设定显示坐标、旋转角度、旋转锚点、缩放比例、透明度等信息。设计完成后可通过软件中的发布功能生成包含当前图层和场景布局信息的XML文件,用于后期图形渲染。为简化设计流程,HMI中静态文字、按钮等控件元素均使用支持透明背景(支持Alpha通道)的PNG图片资源,动态文字通过预留空位,在程序中调用Cairo图形库中的矢量字库接口绘制文字。

1.3 场景元素封装

在嵌入式GUI框架中,图片资源通过资源文件路径加载,而资源文件通常储存在存储器不同扇区中,此方式会增加文件随机读写次数,不适用于图片资源较多且读写速度有限的Flash存储器上。汽车HMI单一场景内的元素内容数量较少、重复性小且元素搭配相对固定,因此以场景为单位,封装场景内的元素为单个二进制(bin)文件,将多次随机读写转换为单次顺序读写,可有效提高场景资源文件加载效率,封装后的二进制文件格式及相关描述如表1所示。为进一步提升Flash存储器的读写效率,文件中数据以四字节对齐的方式排列,元素数据域内图片数据按照设计的堆叠顺序依次收尾相连,数据加载时通过文件头中元素地址索引定位。

表1 场景元素封装二进制文件格式

2 双平台图形库环境搭建

Cairo是基于C语言编写的跨平台2D图形库,支持Windows、Linux等主流操作系统和部分嵌入式平台,支持将渲染好的像素数据导出为多种格式的文件或与各平台图形底层结合显示图像,其图形应用程序接口(API)和画面输出效果在任意平台下均保持一致,拥有优秀的跨平台开发特性[12]。基于Cairo图形库搭建虚拟HMI开发平台和嵌入式平台,可确保双平台下HMI软件代码的一致性,便于后期程序跨平台移植。

2.1 虚拟HMI平台环境搭建

虚拟HMI平台本质是在Windows操作系统环境下运行的窗口应用程序,其编译与运行分别依赖静态库cairo.lib和动态库cairo.dll,上述库文件可从Gtk+框架中提取或通过编译图形库源码获得[13-14]。由于Gtk+中的Cairo库文件版本较低,对Win32平台支持性较差,而通过编译最新版本源码生成的库文件具有良好的兼容性并支持完整的新特性。Cairo源码编译依赖PNG图片解码库libpng和像素处理函数库pixman,而libpng库依赖zlib函数库提供对PNG图片数据压缩与解压的支持[15],因此编译顺序如图2所示。编译完成后,将生成的静态库文件添加到工程链接器配置属性中的附加依赖项中,将动态库文件移动至生成的程序执行文件根目录下,即可完成虚拟HMI开发平台运行环境搭建。

图2 Cairo图形库编译顺序

2.2 嵌入式平台

目前市场主流全液晶仪表采用恩智浦i.MX系列[16-17]、瑞芯微RK系列等高性能处理器,此类处理器硬件采购成本、电路设计及电路板印制成本较高,无法满足组合式仪表对成本的限制需求。普通MCU由于性能较弱无法兼顾数据处理与画面显示,采用双芯片设计能有效均衡算力从而降低成本[18]。文中采用如图3所示的S32K144 MCU处理总线数据及IO信号,F1c100s MPU用于画面显示,二者通过高速串口进行数据交互。

图3 双芯片架构示意图

其中全志F1c100s是基于ARM9架构设计默认主频为400 MHz的微处理器,集成DDR内存,可运行XBOOT、精简版Linux等操作系统。

XBOOT是一款功能强大、可移植性强、代码复用率高的嵌入式系统Bootloader,同时也是片上系统应用程序执行引擎,可为应用程序提供启动及运行环境。由于XBOOT系统具备体积小,功能完善的特点,且内置Cairo图形库与文件系统,无需用户额外配置,适合跨平台轻量化HMI开发。XBOOT源码可从开源项目网站上获取,解压后需编辑源码目录中的Makefile文件,添加编译选项,指定目标编译平台和交叉编译器:

CROSS_COMPILE?=arm-eabi-

PLATFORM ?=arm32-f1c100s

再将源码工程添加至集成CDT插件的Ecllipse IDE中编译,将生成的二进制bin文件通过sunxi_tools烧写工具烧写至板载闪存中运行。

3 HMI程序设计

由于跨平台软件开发存在编译速度慢、资源烧写过程繁琐甚至无法调试等问题,极大影响软件开发速度。虚拟HMI平台依托Visual Studio集成开发环境(IDE),具备完善的编译与调试环境,无需烧写资源,使HMI软件开发流程更为简化,从而提高开发效率。

3.1 虚拟HMI平台架构

虚拟HMI平台由图4所示的五个部分组成:(1)窗口程序主框架;(2)虚拟总线数据模块;(3)虚拟按键模块;(4)数据缓冲区;(5)HMI模块。窗口程序主框架负责初始化程序各模块,创建可视化窗口,监听响应系统消息和用户操作和任务调度;虚拟总线数据模块与虚拟按键模块为非模态对话框子程序,负责转换用户鼠标操作为虚拟总线数据并发送至数据缓冲区,HMI模块扫描缓冲区中的数据进行实时画面显示。

3.2 HMI模块

HMI模块包含数据解析、事件队列、XML文件解析和图形抽象四个单元,模块的数据接口与平台类型无关,图形抽象接口可根据当前运行环境适配,因此在虚拟HMI平台中构建的HMI模块可整体移植至目标嵌入式平台,使移植步骤更简化。

3.2.1 HMI模块工作流程

数据解析单元负责扫描缓冲区中数据的异动情况,根据当前数据异动情况向事件队列单元发送相应事件,事件是一个包含当前事件信息的结构体DisplayEvent:

typedef struct __DisplayEvent

{

scr_id_t ScrId; //场景ID,与二进制文件头中ID对应

scr_time_t ScrDisplayTime; //场景显示时长

priority_t ePriority; //事件优先级

bool isInterrupt; //是否能被打断

bool isRedisplay; //打断后是否重新显示

payload_t ePayload; //当前场景数据负载

}DisplayEvent;

事件队列单元中的事件按照优先级从高到底以链表形式排列,事件插入函数依据传入结构体中的ePriority值向链表中插入事件,事件响应函数优先响应链表头部事件,再调用XML解析单元和图形抽象单元绘制场景元素。XML文件解析依赖libxml2库,场景布局数据以键值对的形式存储在XML文件中,解析时将键值对数据逐一拷贝至PngInfo结构体数组中相应的位置,解析流程如图5所示。

typedef struct __PngInfo

{

uint32_t pIndex; //场景元素编号

float x; //x轴坐标

float y; //y轴坐标

float scale_x; //x轴缩放比

float scale_y; //y轴缩放比

int rotation; //旋转角度

float rot_x; //旋转锚点x轴坐标

float rot_y; //旋转锚点y轴坐标

uint8_t* pPngFileData; //文件数据指针

uint8_t* pPngRawData; //元素数据指针

cairo_surface_t PNGSurface; //图形库Surface指针

} PngInfo;

图5 XML解析单元流程

3.2.2 图形抽象单元

图形抽象单元负责场景元素加载、解析和渲染,虚拟HMI平台中的图形抽象单元基于Windows系统下的图形设备接口(GDI)与Cairo图形库搭建,由于Cairo图形库无法直接在应用程序窗口上绘制图形,依赖GDI为Cairo图形库提供设备上下文环境(device context,DC)。使用GetDC()函数可基于当前窗口创建DC,若直接在窗口DC上渲染图形会造成画面撕裂和闪烁,使用双重缓冲区可解决上述问题。调用CreateCompatibleDC()和CreateCompatibleBitmap()函数在内存中分别创建基于窗口DC的兼容DC和兼容位图数据缓冲区,待Cairo图形库绘制完成后,使用BitBlt()函数将兼容DC中的像素数据逐字节拷贝至窗口DC,可在窗口中实现稳定的画面显示。

Cairo图形库为GDI提供了cairo_win32_surface_create()接口,该接口可将兼容DC转换成类型为cairo_surface_t的抽象绘制平面(Surface),后续图形均在此上下文绘制。图形绘制流程由资源加载、图形变换、图形绘制、资源销毁四个阶段组成:

阶段一,资源加载:图片资源从对应场景的bin文件中加载,一种方式是通过libpng库将bin文件数据域中的图片数据解析为像素数据,传入Cairo图形库中的cairo_image_surface_create_for_data()接口创建类型为cairo_t的上下文目标。第二种方式无需显式地让libpng库参与图片加载过程,而是向Cairo图形库中的cairo_image_surface_create_from_png_stream()接口传入事先读取好的图片数据创建上下文目标。以上两种方案均需重载用于读取PNG文件的回调函数,并将函数指针传递至png_set_read_fn()接口调用。

阶段二,图形变换:汽车仪表HMI中涉及到的基本变换操作包含平移、缩放和旋转,变换参数已由XML解析单元解析至PngInfo结构体中,为简化变换流程,将所需的变换步骤封装为如下所示单一函数中:

void Paint_PNG_Element(cairo_t* cr, PngInfo* info)

{

cairo_save(cr);

if (!(info->rotation == 0)) //旋转

{

cairo_translate(cr, info->rot_x, info->rot_y);

cairo_rotate(cr, info->rotation);

cairo_translate(cr, -info->rot_x, -info->rot_y);

}

if (!(info->scale_x == 1.0&&info->scale_y == 1.0)) //缩放并平移

{

cairo_scale(cr, info->scale_x, info->scale_y);

cairo_set_source_surface(cr, info->PNGSurface,

(int)info->x / info->scale_x,

(int)info->y / info->scale_y);

}

else //仅平移

{

cairo_set_source_surface(cr, info->PNGSurface,info->x,info->y);

}

}

阶段三,图形绘制:图形的加载和变换将图片位图数据置于内存中处理,并未与最初创建的Cairo抽象绘制平面绑定,因此可使用cairo_paint()或cairo_paint_with_alph()函数将内存中的数据渲染在上下文上,后者支持透明背景渲染。cairo_paint()不仅可以绘制图片,还可以绘制实时矢量图形和矢量文字,增加了HMI软件设计的灵活性。

阶段四,资源销毁:受嵌入式平台内存或显存因素的制约,当场景内的某一元素不再显示或发生场景切换等情况,需及时销毁当前资源或场景在内存中的数据,释放内存。Cairo图形库提供了cairo_surface_destroy()和cairo_destroy()接口,分别用于销毁内存中的图片数据和抽象绘制平面。

4 跨平台移植

由于XBOOT系统为嵌入式平台提供了包含Cairo图形库在内的完整的运行环境,虚拟HMI平台与嵌入式平台图形环境基本一致,不同之处在于数据解析单元的总线数据来源、图形抽象层与设备底层之间的接口以及部分设备驱动接口。因此移植过程更为简化,仅需将虚拟HMI平台中的代码进行部分修改后拷贝至嵌入式平台工程中编译即可,移植详情如表2所示。

表2 HMI模块各单元移植方式

首先要向工程中注入资源文件,将各场景的bin文件及xml文件分别拷贝至./xboot/src/romdisk/framework/asset/scr和./xboot/src/romdisk/framework/asset/cfg目录下,此目录在编译阶段会自动生成虚拟文件系统,便于程序通过文件路径调用文件。由于XBOOT内存结构及空间申请方式与Linux系统类似,采用双向链表的形式管理,设备上下文环境需要调用list_for_each_entry_safe函数在链表中寻找足够的内存空间,并在此内存空间上创建Cairo图形库的抽象绘制平面作为上下文,具体代码如下,后续绘图阶段代码则与虚拟HMI平台保持一致。

cairo_surface_t * cs;

cairo_t * cr;

struct framebuffer_t * fb;

list_for_each_entry_safe(pos, n, &__device_head[DEVICE_TYPE_FRAMEBUFFER], head)

fb = (struct framebuffer_t *)(pos->priv))

cs = cairo_xboot_surface_create(fb);

cr = cairo_create(cs);

Cairo图形库渲染后的像素数据关联在cs指针中,还需通过cairo_xboot_surface_present()函数将数据传递至硬件底层,交由LVDS驱动传输至显示屏显示。

5 测试验证与软件优化

5.1 测试与试验验证

本节采用虚拟HMI平台与嵌入式平台联合实验的方式验证HMI软件的可行性与可靠性。首先测试HMI软件对总线信号响应的准确度,由于双平台中总线数据解析、事件队列及XML解析单元中代码一致,因此可在虚拟HMI平台中测试验证。根据如表3所示的汽车仪表HMI软件测试用例对HMI软件中指示灯显示状态、优先级打断逻辑、报警场景触发准确性等方面进行全功能测试,结果表明,仪表能准确响应总线信号并显示正确的提示信息,具备可靠的功能性。

表3 汽车仪表HMI软件测试用例部分测试项目

软件性能方面,HMI软件在嵌入式设备上的每秒显示帧数(fps)是画面流畅度的重要评价指标之一,fps值受当前设备内存、FLASH读写速度与MCU算力的制约,在汽车仪表HMI软件中,场景资源的加载、解析及图形变换对fps值影响较大。为测试上述问题对fps值的影响,本节使用包含120张分辨率为480*800动画序列图片的场景作为测试目标,在虚拟HMI中平台测试,目的是记录单帧渲染时长和内存占用情况。对照组采用以文件路径作为形参调用图形库接口对图片逐一加载的方式,方式一和方式二为3.2.2节中提出的两种方式,方式三则是先将场景资源全部解析到内存中,再调用图形库从内存中读取数据,此方式对内存占用较大,不适用嵌入式平台,仅供参考。测试结果如图6和表4所示,方式二相比于传统方式平均单帧渲染时间降低4 ms,平均帧率提升5 fps,而方式三由于渲染时无需加载图片资源,其单帧渲染时间仅为1 ms,但内存占用为常规方式的5.6倍,上述结果说明方式二为更加合理的图片资源加载方式。

图6 单帧渲染时间测试

表4 测试详情

5.2 软硬件联合优化

软件方面,方式三单帧渲染时间极低,但需要图片数据常驻内存,因此可应用于变化不大且需长期显示的场景,例如背景、仪表盘及指针所处的模式场景,其他场景则继续采用方式二加载。经测试,嵌入式平台HMI软件运行在480*800分辨率的主界面下,混合加载模式相较于仅采用方式二的模式,平均帧率由27.2 fps提升至35.7 fps,提升幅度为31.25%。

硬件方面,全志F1c100s主频默认400 MHz,通过修改时钟配置文件,可将主频提升至720 MHz从而提升帧率。由于Flash闪存在HMI软件运行时为只读状态,将SPI驱动变更为双线只读模式,能提升一定的读取速率。经测试验证,平均帧率由软件优化后的35.7 fps提升至42.7 fps,提升幅度为19.6%,软硬件联合优化后的实时帧率满足汽车组合仪表HMI流畅显示的设计需求。

6 结束语

介绍了面向低成本组合式汽车仪表的HMI系统设计,提出了以图层与场景为单位的界面元素结构,搭建了基于Cairo图形库的虚拟HMI平台和嵌入式平台,简化了界面设计、软件编译及调试的繁琐步骤,同时双平台图形环境的一致性使开发效率得以提升,从而降低了软件的研发成本。HMI程序设计针对汽车信号环境进行了优化,通过监听数据缓冲区中的数据异动情况,根据当前触发事件的优先级响应绘图事件,调用XML解析单元和图形抽象单元完成画面绘制。试验表明,组合式仪表能在保证可靠功能性的同时,通过虚拟HMI平台的仿真实验和软硬件的联合优化,大幅提升HMI实时帧率,保证了仪表显示的流畅性,达成了以低成本实现更佳显示效果的设计目的。

猜你喜欢

图层嵌入式内存
基于IMX6ULL的嵌入式根文件系统构建
为《飞舞的空竹龙》加动感
以假乱真窥探湿玻璃后的风景
笔记本内存已经在涨价了,但幅度不大,升级扩容无须等待
“春夏秋冬”的内存
与众不同“跳出”画面更个性
内存搭配DDR4、DDR3L还是DDR3?
高校图书馆开展嵌入式信息素质教育的思考
上网本为什么只有1GB?
嵌入式组件技术的研究及应用