UEFI开发探索47 – UEFI上移植GUILite

请保留-> 【原文: http://yiiyee.cn/blog/author/luobing/】

上一篇的博客中,已经搭建了C++的编程框架,虽然不是所有C++特性都支持了,比如new和delete,以及虚析构函数等,但是用来移植GuiLite已经足够了。下面就开始着手这一工作。

1 代码选择

GuiLite的例子比较丰富,从控件到动画、甚至3D的实现,都可以找到。浏览了一圈后,我选择从HelloTimer开始动手。

这是在STM32F103上运行的代码:

图1 STM32F103例程: HelloTimer

当然,GuiLite中针对此例程,也提供了Windows MFC和Linux版本的代码。我对MFC比较熟悉,学习GuiLite的代码也是从MFC的代码开始看起的。

之所以选择用单片机的代码来进行移植,主要是基于两个考虑:

1) UEFI相比于操作系统来说,更接近于嵌入式的环境,很多操作系统的机制并没有提供。比如进程的机制,并没有现成的架构可以使用,必须自己实现;

2) STM32F103的代码中,使用的C函数入口,调用C++的代码,UEFI也是如此。相对于可直接使用原生态C++代码的MFC和Linux,单片机的代码更具参考性。

如图1,主要需要移植的代码,用红框圈起来了。除了核心代码GuiLite.h需要做一些改动,以及main函数中的代码需要重新编写外,其他包括Uicode.cpp、grass_bmp.cpp等代码,基本上不需要做太多改动。

2 移植与代码修改

我是采用逐步添加代码的方式进行移植的,主要采用了以下几个步骤:

步骤1: 框架代码搭建

在以前的UEFI代码上,将GuiLite的GuiLite.h添加进去,解决编译过程中的若干问题。我所写的UEFI代码,包含了图形编程、键盘处理、文件和外设访问等。为免枝节太多,只取图形处理部分的代码用来构建框架。

图2 代码分类

将HelloTimer(可到GuiLite的仓库中下载)中的代码拷贝过来,图2为移植成功后的所有代码文件,主要可分为三类:

1) UEFI下的接口函数

包括Common.c、Common.h、Graphic.c、Graphic.h、Window.c和Window.h。这些代码在之前的博客中都解释过,通用的函数以及图形处理函数;

2) C++框架代码

包括crt0data.cpp、Cppglobal.h,在GuiLite.cpp的主函数中有调用方法;

3) GuiLite库相关的代码

包括GuiLite.h、Uicode.cpp以及除GuiLite.cpp外的其他所有cpp文件。文件夹中的bmp文件不参与编译,数据已经提取到源文件中了,只是方便查看放在了一起。

步骤2: 编译GuiLite.h

在GuiLite.cpp中添加#include “GuiLite.h”,并在GuiLite.inf的[Sources]段中添加GuiLite.h。

打开命令行编译器,输入命令:

build -p RobinPkg\Robinpkg.dsc -m RobinPkg\Application\GuiLite\GuiLite.inf

会发现很多警告以及错误。

主要的警告是数据转换的问题,比如int型转为short型,会导致数据截断。可以通过修改编译选项或者强制转换来解决,这里我采用了后一种方法。

错误的提示是虚析构函数,会调用delete函数,此函数无法定位,将其改为普通的析构函数即可。

至于GuiLite中与UEFI的库函数同名的问题,比如宏MAX和宏MIN,改个名字即可。

步骤3:编译其他GuiLite库的函数

将UIcode.cpp等函数加入编译,在GuiLite.inf的[Sources]段中添加这些源文件。主函数其实只需要调用函数startHelloTimer即可,所以将从GuiLite.cpp中移除GuiLite.h,将其包含在UIcode.cpp中。

编译后,提示的错误较少,主要是发现_cos、_sin等数学函数找不到。在GuiLite.inf的[LibraryClassess]段中,添加LibMath,编译通过。

将UEFI接口函数的源文件也添加进去,主要在GuiLite.cpp中包含头文件的时候,需要加关键字extern “C”。

至此,框架代码就搭建完成了。

步骤4:添加工作代码

需要添加的工作代码不多,主要是实现两个接口函数:draw_pixel和fill_rect,画点和画矩形块的函数。

GuiLite库中的颜色,是以一个UINT型表示的,将其转换为UEFI下的颜色即可。而画点和矩形块的代码,在之前的图形库中已经实现了,直接调用接口,具体实现可以查看GuiLite.cpp中的实现。

添加其他运行代码,包括设置显示模式,设置背景等,移植工作即告结束。

3 运行效果

编译代码,运行效果如下:

图4 移植后的运行效果

在GuiLite库中提供的例程中,如果是针对STM32的代码,能够按照上述的方法很方便地移植过来。

至于想移植Windows/Linux例程,还有两个工作要做:

一是实现多进程。这可以通过UEFI的event机制来实现;

二是人机接口的处理,包括鼠标和键盘。这些代码在之前的博客中已经详细讨论过了,所要做的无非整合到现在的代码中而已。

百度云链接:https://pan.baidu.com/s/1gccSosw8_UAGTI5gZPnLCA
提取码:dx23
文件在 FF RobinPkg/ RobinPkg /Applications/GuiLite

126 total views, 6 views today

《UEFI开发探索47 – UEFI上移植GUILite》有一个想法

发表评论

电子邮件地址不会被公开。