当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]基于VxWorks的bootrom代码改进

摘要:在Wind River公司开发的VxWorks嵌入式操作系统平台上,改进交换机产品bootrom软件的实现方式;给出实现方法和改进目的,为BSP开发人员提供一套全新的bootrom实现方案。

    关键词:VxWorks bootrom BSP makefile

1 问题的提出

VxWorks是Wind River公司开发的一种嵌入式操作系统,具有强大的功能和友好的用户界面。VxWorks软件应用非常广泛,不仅应用在网络设备、家用电器当中,而且还应用在航天、导弹等高端领域。在网络设备应用领域中,通常利用VxWorks来开发bootrom代码、BSP(Boadr Support Packet)代码以及上层的网络协议代码。

通常,Bootrom软件有以下功能:①通过串口下载操作系统映像;②通过串口升级自身映像;③通过串口下载系统配置文件、系统信息文件;④加载操作系统映像,使其正常启动;⑤其它的辅助功能,如地址内容查看功能、址内容修改功能和bootrom菜单显示信息控制的功能等。对于通常的bootrom代码编译,大多数用户选择使用GNU make的DOS命令来进行。因为如果bootrom不提供网口功能的话,单纯的CPU驱动部分代码量是不大的;但如果提供网口功能的话,代码量相对较大,文件之间的内在关系比较复杂,因此,系统使用GNU make的DOS命令来编译生成bootrom就显得有点麻烦。Makefile文件主要是由“目标”(target)、“依赖性”(dependencies)和“动作”组成的一系列规则,而VxWorks提供的GNU make工具就是根据Makefile指定的规则来编译和链接程序的。Makefile基本结构虽然简单,但正确、灵活地运用这些规则并不是那么轻松的事情。即使根据GNU Makefile规则书写出适当的Makefile文件,但随着代码的改变,Makefile还需要经常修改,这就增加了BSP开发人员的负担。而且,对于交换产品而言,其成本控制是非常严格的。对于存放bootrom软件的Flash来说,通常要求大小为512KB,这样就需要考虑到容量的限制。

因此,必须使用新的方法来简化bootrom代码编译,而且要在保证提供网口功能的情况下,系统提供的bootrom软件小于512KB。

2 实现方法

2.1 通过建立工程生成bootrom映像

采用建立工程的方式可以有效地解决这个问题。首先依据bootrom中的BSP代码来新建一个工程,然后将网中驱动代码加入到建好的工程中。这样就可以通过编译工程实现带有网口下载功能的bootrom软件。但对于VxWorks嵌入式系统而言,它有自己一套规范,求bootrom软件在加电后必须从romInit()函数开始运行,而建立工程所得的入口函数为sysInit()。因此需要增加一个系统壳代码,这个壳代码所要完成的任务就是加载bootrom工程的映像,并从romInit()开始执行bootrom代码。通过建立工程来调试bootrom代码有以下优点。

(1)责任分明

开发产品是一个复杂的工程,需要多人合作完成。对于CPU子系统和网口驱动系统这两块内容来说,更需要责任明确。通过建立工程来调试代码,可以准确地定位错误文件和函数的位置。是BSP代码出现问题,还是网口驱动代码出现问题,可以一目了然,做到责任明确。

(2)提高效率

通过建立工程可以节省书写Makefile文件时间,并可以让VxWorks软件的友好图形界面这优点得到更好的体现。另外,建立工程也可以减少文件编译排错的难度,方便工程文件的调试以及功能的验证,从而大大提高工作效率,加快工作进度。

2.2 编写壳代码并实现加载

建立工程生成映像文件的入口函数为sysInit(),而VxWorks规范中要求系统加电后要从romInit()函数开始运行。因此,需要设计一个方案来加载编译工程得到的映像,而且要具备初始化CPU和SDRAM存储空间的功能。

首先,系统从romInit()函数中开始运行,完成CPU和SDRAM初始化,跳转到函数romStart()运行。然后,加载第二份bootrom代码到系统的低地址处,运行壳代码中的sysInit()函数,并调用自己构造的解压函数usrInit(),将压缩后的工程映像文件解压缩到系统高地址处,之后系统继续运行解压后的bootrom代码。此时,系统开始运行sysInit()函数,调用VxWorks系统中的usrInit()函数,开始初始化系统硬件、内核以及其它外围设备。

壳函数usrInit()代码如下:

void usrInit(void){

volatile FUNCPTR absEntry;

if(inflate((UCHAR*)ROM_OFFSET(_binArrayStart),

(UCHAR *)(RAM_LOW_ADRS),&_binArrayEndbinArrayStart)!=OK)

return;

absEntry=(FUNCPTR)(RAM_LOW_ADRS);

(absEntry)();

}

其中RAM_LOW_ADRS为系统低地址,是操作系统运行的起始地址,但bootrom可以利用低地址来实现在系统高地址的运行。宏ROM_OFFSET用于准确定位函数地址,因为bootrom中运行的代码要求以相对地址方式来寻址,而不能以绝对地址方式寻址。_binArrayStart为压缩后二进制代码的开始符,_binArrayEnd为压缩后二进制代码的结束符。Inflate()是VxWorks软件的解压缩函数,用于解压缩由deflate()压缩函数压缩的二进制文件映像。同时,需要将下述代码添加到编译规则文件rules.vxWorks中的相应部分:

$(CC)-c $(CFLAGS)$(BSP_DIR)/unzip.c-o$(BSP_DIR)/unzip.o

$(LD)$(LDFLAGS)-e sysInit -Ttext $(RAM_LOW_ADRS)o

unzip_obj.o sysALib.o $(BSP_DIR)/unzip.o $(LIBS)flex.z.o

其中,unzip.c中包含构造的壳函数usrInit()。SysInit()为解压软件入口函数。上述语句的功能:第一行完成壳文件的编译,第二、三行完成壳目标代码与第二份bootrom代码的链接。这样,一个具有解压功能的壳函数就被链接到第二份bootrom映像中了。

    图1、图2是修改前的系统运行方式与修改后系统运行方式比较。

通过这两种方式的比较可以看出,修改前系统运行式与修改后的运行方式有下面两点差异;①第一份bootrom启动后,前者存在解压缩自射映像的操作,而后者没有;②对于第二份bootrom,前者没有壳代码,而后者有。

2.3 缩减文件长度

通常第一份bootrom代码只有两个文件,一个是包含CPU和SDRAM初始化文件romInit.s,另外就是包含romStart()函数的bootInit.c文件。另外,根据需要还可以添加提供串口轮询显示功能的文件。对于第一份bootrom代码,通常只有10KB左右(这是针对系统修改后的方式),而对于包含壳函数代码的,通过建立工程并编译而生成的第二份bootrom比较大,通常为570KB左右。(注意:这几个数值是通过特定的产品来得出的结论,并不应用于所有产品,但遇到类似的情况可以借鉴处理。)而其后面的一部分完全是0,可以考虑去掉这些0,但不能影响软件的功能。经过测试得出结论:去掉后面的0对系统功能和性能没有任何影响。

通过文件的操作来实现两份bootrom合并,合并后的大小要求小于或等于512KB。如果不采用任何措施,直接将两个文件合并起来要在580KB左右,大于512KB,这是很多系统不能满足的。第二份bootrom映像的后面部分的内容类似表1所列的信息。

表1 bootrom映像部分二进制内容

000 210h EB E2 BD 95 BD 15 87 AE 3C 74 FD 5C 5F 6A FD 8B
000 220h D6 BD 3A EB FF 6F CF 2A D2 69 95 E9 34 AE E7 EF
000 230h 86 94 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000 240h 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
000 250h 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

从表1可以看出,在地址0x00078233处就是0值了。这样可以通过对文件内容的操作将0x00078240后面的内容全部剔除,从而可将合并后的bootrom代码控制在512KB以内。当然,我们通常会选择一个整数值进行操作,即将0x0007824后的所有值去掉即可。

这样处理,可以减少维护和开发的工作量。如果按照以往的做法,bootrom软件对外将有第一份和第二份的区别,无论是生产、上层软件调试还是开发,都需要分别对待,这样维护量和开发量将会加大。而经过修改后,可把区别只控制在开发阶段,在线升级时,可以按照一个软件来通过串口或网口来进行升级。通过对bootrom最后生成文件大小的控制,可以简化生产流程,加快生产进度。

3 小结

在嵌入式操作系统中进行程序开发,需要经常开辟新的思路,以一些简单的实现方式代替复杂易错的方式。在本次产品开发过程中,将bootrom映像生成方式由惯用的GNU make命令行实现,修改为按照新建工程的方式来实现,是一个相对好的方法,对整个产品的后续批量生产、用户维护和后续开发都奠定了一个良好的基础。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭