APP下载

基于WinCE 6.0的开机Logo设计与实现

2012-05-04程克非付学恕

计算机工程与设计 2012年6期
关键词:缓冲区代码嵌入式

程克非,付学恕,涂 刚

(1.重庆邮电大学 计算机学院,重庆400065;2.华中科技大学 计算机学院,湖北 武汉430074)

0 引 言

微软的 Microsoft Visual Studio 2005和Platform Builder开发工具使得开发和定制 WinCE 6.0变得简单而且功能强大。由于WinCE 6.0具有可定制、多平台、实时性、网络功能、多媒体和多语言等诸多优点,其应用极为广泛[1]。在嵌入式操作系统中Bootloader是系统上电后首先执行的代码,对于原生WinCE 6.0系统来说,从打开电源到系统完全启动期间,LCD(液晶显示屏)没有任何视频或图像输出,导致其用户体验有所欠缺。而此前的研究成果基本可以分为两类:一类是在开机时显示单一色彩的图片或一些字符,使开机界面不够美观;另一类则是直接采用一个超大数组存放图片数据而使得移植困难。本文正是基于以上原因,在认真分析和研究了以前的成果基础上,通过对WinCE 6.0的Bootloader代码进行分析和设计,将符合LCD分辨率的开机Logo数据直接固化在Flash上并在Bootloader启动时读出,使得系统开机后马上就有漂亮的彩色图像输出,同时更换Logo也变得简单方便,从而满足用户对嵌入式产品要求的友好界面及美观性。基于该方法实现的WinCE 6.0系统的手持式第二代居民身份证阅读器使用的显示屏是信利(Truly)半导体有限公司的4.8英寸分辨率为800×480的TFT LCD。

1 WinCE 6.0系统Bootloader分析

Bootloader是用来管理目标设备启动过程的特定程序,是在操作系统内核加载之前设备首先运行的一小段程序[2]。其主要工作包括设备硬件平台的初始化,内存地址空间映射的建立,以及从非易失存储器(Nand Flash或 Nor Flash,本文中设备采用的是Nand Flash)上或者网络上加载操作系统映像文件并引导运行等。

1.1 主流Bootloader简介

UBoot(universal Bootloader): 它 起 源 于 开 源 项 目PPCBoot,后来ARMBoot也合并进来,再加入其他一些Bootloader,于是 UBoot诞生了[3]。2002年12月17日UBoot 0.2.0发布,它是UBoot的第一个发布版本。从那以后,UBoot又陆续修改和更新了6次之多。从2008年8月后,UBoot采用日期作为版本号。截至目前为止,最新版本号为 UBoot-2011.06。UBoot的支持是不间断的。UBoot有引导启动(Bootloading)模式和下载运行(downloading)模式,并具有大型Bootloader所应该具备的所有功能。它是GPL(general public license)下资源代码最完整的一个通用Bootloader。UBoot支持的处理器架构包括PowerPC,ARM,MIPS和X86等。UBoot支持大量的外设驱动,支持多种不同的文件系统,还附带有脚本和调试等工具,专门针对Linux的支持做了优化,并特别为板级移植做了很多的支持。其主要特性为:以太网支持,IP/MAC预置功能,在线读写Flash,支持串口下载代码,识别二进制及其它格式的内核,监控命令集,支持看门狗(WatchDog)时钟,支持LCD显示Logo等。

Redboot:它是Redhat公司的一个开源项目,是伴随ECOS发布的一个独立运行在嵌入式系统上的Bootloader方案[4]。Redboot广泛支持各种处理器架构,诸如:Power-PC、MIPS、ARM和X86等,功能非常完善。Redboot采用了ECOS的硬件抽象层并以此为基础,继承了ECOS的简洁和稳定可靠的优点,同时又可以灵活的配置。它不仅支持Ymodem或者Xmodem协议通过串口下载映像,也支持以太网口使用TFTP的方式下载映像文件,常用于系统初始化、引导内核映像和调试支持。Redboot自启动后,会提供一个可交互的命令行,用来管理本地映像,映像下载和运行,Bootloader配置以及其它各种外部硬件设备等。Redboot的引导脚本文件保存在本地Flash上,主要用作从TFTP服务器端或本地Flash下载系统映像并将其加载运行。

Blob(boot loader object):它是由Jan-Derk Bakker and Erick Mouw发布的,是专门针对StrongARM构架下的LART(Linux advanced radio terminal)设计的一个 Bootloader[5]。Blob提供两种工作模式,在启动时处于引导加载模式,但是它有10s的等待时间,当用户按下任意键,则Blob立刻切换到下载运行模式。如果10s内没有按键响应,则Blob启动并加载储存在本地的Linux内核。Blob主要是通过串口跟主机通信,速度慢而且效率低下,同时其支持的CPU结构也很有限。Blob最新的版本是Blob 2.0.5。

VIVI:它是由韩国mizi公司开发设计的一个专门针对ARM 9嵌入式处理器的Bootloader。与其它的Bootloader相比VIVI具有容易理解,易于移植等优点[6]。VIVI也具有两种工作模式:引导启动模式和下载运行模式。引导启动模式是VIVI的默认工作模式,它可在一段用户自定义的时间流逝后自行引导和启动Linux内核。在非默认的下载运行模式下,VIVI会为用户提供一个电脑终端命令行接口,通过该接口可以利用主机的串口来使用VIVI提供的操作命令和VIVI进行通信。

1.2 WinCE 6.0Bootloader分析

一个典型的WinCE 6.0系统的启动流程如图1所示。

图1 WinCE 6.0系统启动流程

采用分级Bootloader(NBoot和EBoot)设计,可以方便代码维护和修改,并且将核心硬件和外围硬件初始化分开完成,提高了代码执行效率和复用率,同时使得代码便于移植[7]。所以本文中的第二代居民身份证阅读器就是采用 NBoot(Nand Flash Bootloader) 和 EBoot(Ethernet Bootloader)的两级Bootloader模式。

1.2.1 NBoot分析

NBoot位于 Nand Flash的block 0(每block大小为1MB)上,通过Platform Builder编译为block0.nb0映像文件[8]。该文件固定大小为72KB。系统上电时首先即自动加载 Nand Flash的block 0上的前4KB代码[9],它是 NBoot的汇编初始化代码。汇编代码完成最基本的硬件初始化之后,就跳转到C语言入口开始执行后续代码[10],后续代码所完成的主要工作就是将EBoot从Nand Flash的block 3上拷贝到RAM(内存)并加载运行。整个NBoot的主要执行流程如图2所示。

图2 NBoot执行流程

1.2.2 EBoot分析

EBoot位于 Nand Flash的block 3上。大小控制在512KB以内(本设备为391KB)。EBoot主要由Blcommon、OEM代码和网络驱动等组成[11]。它有两种工作模式:烧写模式完成将Bootloader自身和内核映像(NK.bin)固化到Nand Flash的指定block上;下载模式完成将内核映像从Nand Flash下载到RAM指定地址处加载运行。

本设计主要利用EBoot的main()函数中包含的BootloaderMain()函数实现。在BootloaderMain()中调用了OEMPlatformInit()函数来完成硬件平台的初始化过程,包括LCD的初始化。本文中实现开机Logo的功能即是在这两个函数中添加C语言代码实现的。首先通过EBoot的烧写模式将Logo下载到Nand Flash的指定block中,然后开机时再通过EBoot的下载模式将Logo从Nand Flash读到RAM中的LCD缓冲区显示。EBoot简化后的执行流程如图3所示。

图3 EBoot执行流程

2 LCD简介

由于Bootloader执行效率和硬件关联度高,并且开机Logo的显示相对于普通的视频输出从实现方式和显示内容并不完全一样[12]。所以在Bootloader中添加的实现开机Logo的代码要相对简单且执行效率高,同时必须和底层的硬件以及LCD密切相关。

本文中的设备上使用的LCD是信利(truly)半导体公司生产的型号为 TFT800480-30-E 4.8英寸 TFT LCD,分辨率为800×480,32位色彩显示[13]。硬件核心采用的是三星电子(samsung electronics)的 ARM11架构的S3C6410嵌入式处理器,主频为667MHz。S3C6410的显示控制器时序如图4所示[14]。

3 开机Logo的实现

图4 LCD RGB接口时序

在 WinCE 6.0自带的 Bootloader中并没有初始化S3C6410的LCD控制器的代码,LCD的初始化发生在内核的加载启动之后。所以在Bootloader运行的这段时间内,LCD上没有任何视频输出。因此为了产品的美观性和交互性,本设备在Bootloader中添加了实现开机Logo的代码,使得系统一启动就有视频图像输出并显示系统开机进度条,Logo包含有公司的信息和图标等。其中Logo是BMP(位图)格式的图片,分辨率为800×480,其颜色位值为24,大小固定为1152054字节。通过Bootloader烧写到Nand Flash的block 5和block 6上,并在系统启动后由Bootloader读取位图数据,然后将数据直接拷贝到RAM的LCD输出缓冲区中,LCD就会原样显示出Logo。Logo在Nand Flash上的存储位置如图5所示。

图5 Logo存储分布

实现开机显示Logo的具体过程如下:

(1)从SD卡中读取Logo数据到RAM:在Bootloader的烧写工作模式下,添加从SD卡读取Logo的C语言代码,在BootloaderMain()函数中添加如下函数:

LogoReadFromSD();从SD卡中读取Logo信息,包括Logo存放的起始地址和长度等。其主要代码如下:

这两段代码分别指明了Logo将要读取到RAM中的地址值和对Logo数据进行分析和处理,为读取SD卡中的Logo到RAM做准备。

DownloadImage(DWORD dwImageStart, DWORD dwImageLength,DWORD dwLaunchAddr);这3个入口参数分别是映像存储起始地址,映像长度和映像加载地址。主要功能是从SD卡下载Logo数据到RAM。它会调用它所 包 含 的 OEMReadData(DWORD dwData,PUCHAR pData)函数来完成具体的Logo数据下载工作,其中2个入口参数分别指:映像数据长度和映像存储缓冲区。

(2)将RAM中的Logo烧写到 Nand Flash:这是在Bootloader烧写工作模式下实现整个开机Logo设计与显示过程中最关键的一部分,主要由 WinCE 6.0自带的底层Flash访问函数完成。该函数具有便于移植,代码复用率高和执行效率高的优点,并且可以不加修改直接运用于其它基于 WinCE 6.0的嵌入式设备上。

OEMLaunch(DWORD dwImageStart,DWORD dwImage-Length,DWORD dwLaunchAddr,const ROMHDR *pRomHdr);这4个入口参数分别是映像存储起始地址,映像长度,映像加载地址和TOC分区标识符。主要功能是将下载到RAM中的Logo烧写到Nand Flash的指定block上。

OEMLaunch()调用 WriteRawImageToBootMedia

(DWORD dwImageStart,DWORD dwImageLength,DWORD dwLaunchAddr)函数完成具体烧写过程。其入口参数分别指:映像存储起始地址,映像长度和映像加载地址。其主要功能就是执行下面的底层Flash访问函数代码:

dwBlock=LOGO_BLOCK;指定了Logo将要烧写到的Nand Flash起始block数。

pLowFuncTbl=FIL_GetFuncTbl();直接访问底层Nand Flash的函数,可以直接对Nand Flash进行访问和修改等操作,其中最重要3个底层操作如下:

pLowFuncTbl-> Read(UINT32nBank, UINT32 nPpn, UINT32nSctBitmap, UINT32nPlaneBitmap,UINT8 *pDBuf,UINT8 *pSBuf,BOOL32bECCIn,BOOL32bCleanCheck);直接读Nand Flash数据。其参数分别指:block数,Nand Flash页数,扇区映射位,Nand Flash平面映射位,目标数据缓冲区,源数据缓冲区,ECC校验码标识位和Nand Flash数据清除标识位。

pLowFuncTbl->Write(UINT32nBank,UINT32nPpn,UINT32nSctBitmap,UINT32nPlaneBitmap,UINT8*pDBuf,UINT8*pSBuf);直接写Nand Flash数据。其参数分别指:block数,Nand Flash页数,扇区映射位,Nand Flash平面映射位,目标数据缓冲区和源数据缓冲区。

pLowFuncTbl-> Erase(UINT32nBank, UINT32 nPbn,UINT32nPlaneBitmap);直接擦除Nand Flash数据。其参数分别指:block数,Nand Flash页数和Nand Flash平面映射位。

(3)设置 LCD寄存器[15]:

设置LCD主要在Bootloader的下载模式中完成。首先在OEMPlatformInit()函数中调用LCD初始化函数InitializeDisplay()来设置CPU的控制LCD输出的GPIO口:

然后在InitializeDisplay()中实现重要函数:LDI_fill_output_device_information(void*pDevInfo);其参数指针指向一个系统定义的视频设备信息结构体。该函数功能为:初始化LCD设备基本信息,像素时钟采样频率33.33MHz,位数模式24BPP,输出图像格式8:8:8,像素点时钟下降沿采样,帧率为60,水平、垂直同步信号低电平有效。在该函数中还要设置如下重要参数:

以上代码分别指:帧后、帧前等待计数分别为31、1个行时钟,垂直脉冲宽度为2个行时钟,行后、行前等待计数分别为86、1个像素点时钟,水平同步时钟宽度为128个像素点时钟。

(4)将Logo数据拷贝到RAM的LCD输出缓冲区:

将Logo从Nand Flash拷贝到RAM中,主要是靠在下载模式下通过OEMPlatformInit()中添加的如下3个函数完成的:

ShadowLogo()函数主要将Logo数据从Nand Flash对应block读取到RAM指定地址中。其中包含如下重要代码:

pBuffer=(UINT8*)EBOOT_BINFS_BUFFER_UA_START;指向Logo在RAM中的储存起始地址,这是一个通过 MMU(Memory Management Unit)映射后的虚拟地址。

dwStartBlock=LOGO_START_BLOCK;指向Logo在Nand Flash存储的起始block。

dwNumBlock=LOGO_BLOCK_SIZE;指向Logo在Nand Flash上所占据的block数。

CopyLogoPicSeg(S32xPos,S32yPos,S32nWidth,S32nHight,PU08pBuf);其各个参数分别指:Logo在LCD屏幕上开始显示的横坐标和纵坐标,二维图像数组宽和高,以及Logo在RAM的起始地址值。其中包含如下重要参数设置:

U32*tmp=EBOOT_FRAMEBUFFER_UA_START;指向RAM中的LCD输出缓冲区,这也是一个经过MMU映射的虚拟地址,Logo数据信息将被拷贝至此地址处,然后在LCD上完整的显示出来。

显示内核加载进度的进度条也是显示Logo的一部分,该功能主要由函数progress_draw_v(int_top_left,int_top_right,int _width,int _heigth,int _color)完成,其入口参数分别指:进度条位于LCD的横坐标和纵坐标,LCD屏幕宽度和高度,以及进度条的颜色。

(5)显示示例Logo:

打开Platform Builder编译生成本项目下的BSP(board support package)包,会得到EBoot.bin和EBoot.nb0两个Bootloader映像文件。将EBoot.bin烧写到本设备的Nand Flash的block 3上,启动设备,即可看到如图6所示示例Logo及位于LCD下方的开机进度条。

图6 开机Logo

4 结束语

本文通过对WinCE 6.0的Bootloader启动流程进行分析,针对实际的硬件平台,完成了基于 WinCE 6.0系统和三星S3C6410硬件平台的开机Logo的设计与实现。对比其它类似设计与实现不能快速准确显示彩色图片,不易于移植以及不能随意且方便的更换Logo的局限性,本文中的设计与实现代码简洁高效,方便移植,Logo可以随意更换,而且代码可以不加修改而直接运用于其它基于 WinCE 6.0系统的嵌入式设备上。经过反复测试,该设计与实现可以准确快速的将Logo原样显示在LCD上。本文中的第二代居民身份证阅读器正是采用了上述设计实现了开机显示Logo的功能,该设备已进入量产和实际应用阶段。

[1]HE Zongjian.Windows CE embedded system [M].Beijing:Beihang University Press,2006:7-10(in Chinese).[何宗健.Windows CE嵌入式系统 [M].北京:北京航空航天大学出版社,2006:7-10.]

[2]ZHANG Dongquan,TAN Nanlin.Windows CE practical development technology [M].Beijing:Publishing House of Electronics Industry,2006(in Chinese).[张东泉,谭南林.Windows CE实用开发技术 [M].北京:电子工业出版社,2006.]

[3]YANG Fumin,WANG Pengyu,TU Gnag.Design and implementation of BSP in the embedded Linux [J].Computer Engineering and Science,2005(in Chinese). [阳富民,王朋羽,涂刚.嵌入式Linux系统BSP的设计与实现 [J].计算机工程与科学,2005,27(1):64-66.]

[4]ZHENG Kelong.Design and application of RedBoot based ARM-Linux embedded system [D].Xi'an:Xidian University Library,2009(in Chinese).[郑克龙.基于 ARM-Linux嵌入式系统RedBoot的设计与应用 [D].西安:西安电子科技大学图书馆,2009.]

[5]Startup code analyze of BLOB and research of Bootloader porting[D]. Wuhan: Wuhan University of Science and Technology Library,2010(in Chinese). [李 昂.基 于 S3C44BOX 的Bootloader-BLOB移植研究 [D].武汉:武汉科技大学图书馆,2010.]

[6]KU Shaoping,TIAN Yunfang.Analysis &improvement of VIVI BootLoader based on Nand Flash [J].Control and Automation Publication Group,2009,26(8):76-78(in Chinese).[库少平,田云芳.基于Nand Flash的VIVI装载器的分析于改进 [J].微计算机信息,2009,26(8):76-78.]

[7] WANG Yagang.Analysis and transplant of embedded Boot-Loader mechanism [J].Computer Engineering,2010,36(6):267-269(in Chinese). [王亚刚.嵌入式 Bootloader机制分析与移植 [J].计算机工程,2010,36(6):267-269.]

[8]Platform builder for microsoft Windows CE 6.0help [Z].Microsoft Corporation,2006.

[9]QI Yun,ZHANG Yongrui.Design and implementation of Boot-Loader based on PXA255processor in WinCE [J].Electronic Science and Technology,2005,(10):58-61(in Chinese).[齐云,张永瑞.PXA255处理器在 WinCE系统下的Boot-Loader设计与实现 [J].电子科技,2005,(10):58-61.]

[10]ZHANG Fei,BAI Ruilin,LU Lin.Design and implementation of WinCE 5.0Bootloader [J].Computer Engineering,2009(in Chinese).[张飞,白瑞林,陆林.WinCE 5.0Bootloader的设计与实现 [J].计算机工程,2009,35(7):232-234.]

[11]GONG Nan,CAO Ling,GAO Zhiying.Design and development of Windows CE 5.0Boot Loader based on Sansung S3C2440Aprocessor [J].Journal of Xi'an Institute of Posts and Telecommunications,2008,13(5):45-47(in Chinese).[弓楠,曹凌,高志英.基于Sansung S3C2440A处理器 Windows CE 5.0Boot Loader的设计与开发 [J].西安邮电学院学报,2008,13(5):45-47.]

[12]ZHANG Zhi,JIANG Zhilong.Implementation of Boot Logo in Bootloader based on Windows CE and S3C2410 [J].Electronic Measurement Technology,2010,33(2):87-90(in Chinese).[张智,江志农.基于S3C2410和Windows CE的Bootloader启动图片的实现 [J].电子测量技术,2010,33(2):87-90.]

[13]TFT800480-30-E Specification [Z]. Truly Semiconductors LTD,2009.

[14]S3C6410XUser's Manual [Z].Samsung Electronics,2009.

[15]ZHANG Genbao,YANG Feng,TIAN Ze,et al.Development of Eboot Based on Windows CE.NET [J].Measurement and Control Technology,2007,26(7):53-55(in Chinese).[张根宝,杨峰,田泽,等.Windows CE.NET系统下Eboot开发 [J].测控技术,2007,26(7):53-55.]

猜你喜欢

缓冲区代码嵌入式
创世代码
创世代码
创世代码
创世代码
搭建基于Qt的嵌入式开发平台
嫩江重要省界缓冲区水质单因子评价法研究
嵌入式软PLC在电镀生产流程控制系统中的应用
关键链技术缓冲区的确定方法研究
Altera加入嵌入式视觉联盟
倍福 CX8091嵌入式控制器