王宏文,李晓燕,黄金兰
(河北工业大学 控制科学与工程学院,天津 300130)
喷码机平台WinCE5.0系统的BSP开发
王宏文,李晓燕,黄金兰
(河北工业大学 控制科学与工程学院,天津 300130)
基于以S3C2440A处理器为核心的喷码机硬件开发平台,研究了嵌入式WinCE5.0操作系统板级支持包BSP的开发。分析了喷码机平台的硬件组成和BSP的框架结构,利用源代码重用的思想,完成了Bootloader、OAL、驱动程序、配置文件的开发工作并在BINFS文件系统的基础上实现Multi-bin成功将内核分块。实践表明该BSP在喷码机台上运行稳定,可靠性高,能有效提升系统的开机速度,并使平台拥有了运行大型喷印软件的能力。
喷码机;WinCE5.0;Multi-bin;BSP
本文在实现喷码机板载系统一体化的目标下,研究了喷码机软件系统开发的操作系统板级支持包(Board Support Package,BSP)[1]。
板级支持包BSP是介于硬件和操作系统之间的一层软件系统,其作用就是抽象操作系统和主板硬件之间的交互接口。基于具体开发板开发BSP,必须对它的结构有一定的了解。一般情况下,WinCE5.0的BSP包含引导程序(BootLoader)、OEM适配层(OEM Adaptation Layer,OAL)、驱动程序、配置文件四部分。
BSP不仅与特定的操作系统有关,而且与不同的开发平台也是一一对应的。喷码机系统的硬件平台主要由图1所示的几大部分组成。
图1 开发板硬件组成
以喷码机控制系统的CPU为核心,外围设备主要包括两片HY57V561620F(L)T(P)芯片、一片K9F2G08U0A和EN29LV160AB芯片,使开发板拥有了64 MB的SDRAM、256 MB的NAND FLASH以及2 MB的 NOR FLASH。网卡采用DM9000,提供互联网连接等功能,同时包含4.3寸的触摸屏、XJ128喷头以及丰富的接口资源。
从零开始研发BSP成本较高、耗时长,所以现实中最常采用的方法是根据需要对现有的相近BSP源码进行移植。本文就是以相近开发板的BSP为基础,根据喷码机硬件平台的外围配置,对BSP的源码做出对应的修改,使之能够有效支持硬件系统。主要工作介绍如下。
3.1 BootLoader的实现
BootLoader是嵌入式软件系统最底层的一组代码,是依赖硬件存在的。微软公司提供了一套WinCE系统BootLoader的基本框架,由Blcommon库、Eboot库、OEM代码、EDBG驱动以及存储管理组成[1]。移植时前二者无需改动,后面三部分则需要根据开发板的实际配置进行修改。在实现过程中应尽量使用微软提供的支持库,这样在保证了规范性、高效性的同时还节省了实现时间。
BootLoader需要实现的代码主要分为两部分:由汇编语言编写的启动代码以及由C语言编写的主代码。汇编代码startup.s是BootLoader的入口函数,CPU启动后将立即运行,完成对CPU的初始化、地址映射、及BootLoader代码的搬运[2]。以下是平台的部分代码实现:
ResetHandler
movr0, #0
mcrp15, 0, r0, c8, c7, 0 ; flush both TLB
mcrp15, 0, r0, c7, c5, 0 ; invalidate instruction cache
mcrp15, 0, r0, c7, c6, 0 ; invalidate data cache
ldr r0, = WTCON ; disable watch dog
ldr r1, = 0x0
str r1, [r0]
; set INTMSK, INTSUBMSK, disable all interrupts
ldr r0, = INTMSK
ldr r1, = 0xffffffff ; disable all interrupts
str r1, [r0]
ldr r0, = INTSUBMSK
ldr r1, = 0x7fff;disable all sub interrupt
str r1, [r0]
……
;set INTMOD, Configure MPLL, UPLL
……
;Copy boot loader to memory
……
汇编程序执行完以后,就会跳转到主程序main函数中,调用BLCOMMON库blcommon.c中定义的BootLoaderMain函数。由它控制着接下来的整个代码执行流程,是引导加载程序的主控函数。
① 调用KerneRrelocate()函数(blcommon.c中实现):将BootLoader中的全局变量重新定位到RAM中。
② 调用OEMDebugInit()函数(main.c中实现):初始化调试端口,一般情况下就是异步串行通信口UART,调用OEMInitDebugSerial()函数实现。在喷码机平台中选择串口UART0作为调试端口,查看处理器的芯片手册,要把通用I/O口的GPH2和GPH3用作功能复用口,设置它们为UART0的发送数据引脚TXD与接收数据引脚RXD,代码如下:
pIOPortReg->GPHCON &= ~((3 << 4) | (3 << 6));
pIOPortReg->GPHCON |= ((2 << 4) | (2 << 6));
同时,初始化它的传输速率、每帧传输数据位数、有无奇偶校验和停止位等,主要是对UART0的各控制寄存器进行设置,如下:
UFCON0 = 0x0; //设置串口FIFO控制寄存器,禁用FIFO
UMCON0 = 0x0; //禁用
ULCON0 = 0x3; //选择每帧数据位数为8,停止位数为1,无 //奇偶校验
UCON0 = 0x245;//选择串口波特率时钟,发送模式,接收 //模式
UBRDIV0=( (int)(PCLK/(16*115200) -1 );
//设置串口波特率
③ 调用OEMPlatformInit()函数(main.c中实现):调用InitDisplay(),InitUSB(),Isr_Init()等函数完成平台初始化工作。
④ 调用OEMPreDownload()函数(main.c中实现):当平台的USB下载不可用时,调用此函数完成以太网下载前其他的一些准备工作。获得IP地址,初始化TFTP传输协议。
⑤ 调用DownloadImage()函数(在blcommon.c中实现):下载操作系统映像到SDRAM中,完成后进行TOC签名的检查。
⑥ 调用OEMLaunch()函数(在main.c中实现):启动操作系统映像。
3.2 OAL移植
OAL(OEM Adaptation Layer)从WinCE5.0以后,引入了OAL的新概念:产品质量级OAL,即PQOAL。它使OAL的目录结构标准化、代码分布模块化,降低了移植的难度[3]。WinCE5.0中OAL的代码主要分成4部分:板级代码、SoC芯片级代码、体系结构级代码和硬件无关级代码。
喷码机平台相较于学习板主要是在外围设备方面做了变动,因此这里完成OAL移植的主要工作就是修改板级OAL代码,位于WINCE500PLATFORM HARDWAER PLATFORM NAMESRC KERNELOAL。在最后的编译过程中,OAL是被编译进操作系统内核的,因此OAL的启动流程实际也就是操作系统内核的启动流程。图2是操作系统的初始化启动流程。
图2 WinCE5.0内核启动顺序
其中的绝大部分函数由微软提供,并不需要修改,只有部分涉及到具体硬件的地方需要实现。
① startup函数。这是系统启动时调用的第一个函数,主要完成CPU和硬件的初始化等工作。本系统的OAL由BootLoader引导,很多硬件设备已经在那里完成初始化,所以此处startup的主要工作就是完成其余部分初始化然后跳转到OAL的主控函数KernelStart()处开始执行。部分代码如下:
LEAF_ENTRY StartUp
addr0, pc, #g_oalAddressTable- (.+ 8)
bl KernelStart
ENTRY_END
② 串口调试函数OEMInitDebugSerial()。其由ARMInit()函数调用,主要完成初始化串口的工作,与BootLoader分享相同的代码。
③ OEMInit()函数。OEMInit()函数也是由ARMInit()调用,主要完成硬件平台的初始化,包括cache globals、中断、系统时钟、KITL等,几乎完成了所有的硬件初始化工作[4]。如初始化I/O函数ConfigureGPIO()的部分代码如下:
s2440IOP->GPBDAT=0x60;
s2440IOP->GPBUP=0x7FF;
s2440IOP->GPBCON=0x2A96A8;
……
s2440IOP->GPGCON=0x16A4F3B4;
s2440IOP->GPGUP=0x9BDC;
……
具体操作就是根据喷码机平台对端口的要求,查S3C2440A芯片手册的I/O部分,根据规则设置相关寄存器来初始化它们的实际功用。这些所有的初始化工作都在WINCE500 PLATFORMHARDWAER PLATFORM NAMESRC KERNELOAL init.c中实现。
④ 中断初始化函数OALIntrInit()。由OEMInit()函数调用,负责初始化外围硬件的中断控制器。首先调用OALIntrMapInit()初始化物理中断Irq和逻辑中断SysIntr的映射表,然后清除外部中断和内部中断,调用BSPIntrInit()对BSP中的GPIO中断进行初始化工作,这里移植时不作修改。
⑤ 中断处理函数OEMInterruptHandler()。OAL中对中断的处理主要是实现ISR部分。当发生硬件中断时,该函数就会被调用完成ISR部分的中断处理:读取系统的中断标记位、确定中断源、屏蔽中断并返回相应的系统中断号。然后触发相应的事件,由具体驱动程序的IST完成真正的中断处理。代码存放路径为WINCE500PLATFORM HARDWAER PLATFORM NAMESRC COMMONINTRintr.c,针对开发板实际设置的中断修改此代码。同时涉及到中断处理的函数OALIntrRequestIrqs()、OALIntrEnableIrqs()、OALIntrDisableIrqs() 和OALIntrDoneIrqs()都在intr.c中实现,它们相应地会调用BSPIntrRequestIrqs()、BSPIntrEnableIrq()、BSPIntrDisableIrq()、BSPIntrDoneIrq()来实现同一CPU的不同开发板对中断所做的一些修改。
⑥ 内核初始化函数KernelInit()。完成初始化系统API函数调用表、系统堆、内存池、内核进程和进程调度等工作,由微软提供。
⑦ FirstSchedule()。这实际上不是一个函数,而是armtrap.s文件中的一个标签,使第一个处于就绪态的线程执行[4]。
OAL作为内核与目标硬件之间的接口,主要对硬件的4种部分加以抽象:RTC、Timers、Caches和调试端口,针对实际情况改变了哪里的硬件就修改对应的代码。具体到喷码机硬件开发板,移植的重点是硬件初始化部分和中断处理部分。
3.3 驱动程序的实现
如果增加或删改了目标板的硬件设备,那么移植BSP时,就必须修改设备驱动程序。WinCE开发平台提供了多种类型的设备驱动程序,它们的源代码由两部分组成:与硬件平台无关的部分位于WINCE500PUBLICCOMMONOAKDRIVERS目录下,与硬件平台有关的部分位于WINCE500PLATFORM下相应BSP目录的DRIVERS[5]。
我们不需要修改与硬件平台无关的公共部分,只需要修改与硬件密切相关的源代码。具体到喷码机平台,主要就是XJ128喷头底层驱动的PMJ_Init(初始化设备)、PMJ_Deinit(卸载设备)、PMJ_Open(打开设备)、PMJ_Close(关闭设备)、PMJ_Write(写数据到设备)、PMJ_IOControl(设备的I/O控制)等12个流接口驱动函数。
3.4 移植配置文件
PB5使用两种配置文件来生成操作系统运行时的镜像,一种是源代码配置文件,另一种是映像配置文件[6]。配置文件的移植主要集中在Dirs、source、BIB以及REG文件。
根据实验结果,导入移植好的BSP编译出的系统镜像内存太大,烧入喷码机平台以后系统开机十分缓慢。因此需要在BINFS基础上实现Multi-bin技术来将内核分块,解决开机缓慢的问题。其具体实现主要在配置文件部分:修改config.bib的MEMORY部分如表1所列。
表1 config.bib文件MEMORY部分配置
将内核分为XIPKERNEL和NK两块,开机必备的内容存放在XIPKERNEL中,其他部分存放在NK中按需调用。经过实践,XIPKERNEL应包含如下的几个模块(添加在MODULES段):
MODULES
nk.exe $(_FLATRELEASEDIR)kern.exe XIPKERNEL SH coredll.dll $(_FLATRELEASEDIR)coredll.dll XIPKERNEL SH
filesys.exe $(_FLATRELEASEDIR)filesys.exe XIPKERNEL SH
fsdmgr.dll $(_FLATRELEASEDIR)fsdmgr.dll XIPKERNEL SH
mspart.dll $(_FLATRELEASEDIR)mspart.dll XIPKERNEL SH
binfs.dll $(_FLATRELEASEDIR)infs.dll XIPKERNEL SH
ceddk.dll $(_FLATRELEASEDIR)ceddk.dll XIPKERNEL SH regenum.dll $(_FLATRELEASEDIR) egenum.dll XIPKERNEL SHbusenum.dll $(_FLATRELEASEDIR)usenum.dll XIPKERNEL SH
pm.dll $(_FLATRELEASEDIR)pm.dll XIPKERNEL SH smflash.dll $(_FLATRELEASEDIR)smflash.dll XIPKERNEL SHfatfsd.dll $(_FLATRELEASEDIR)fatfsd.dll XIPKERNEL SH
diskcache.dll $(_FLATRELEASEDIR)diskcache.dll XIPKERNEL SH
fatutil.dll $(_FLATRELEASEDIR)fatutil.dll XIPKERNEL SH
除此之外还要在FILES段添加下面两个模块:
FILESboot.hv $(_FLATRELEASEDIR)oot.hv XIPKERNEL SH
wince.nls $(_FLATRELEASEDIR)wince.nls XIPKERNEL SH
配合修改platform.bib、common.bin文件完善系统各功能模块的镜像归属问题,同时在platform.reg中添加BINFS文件的支持。所有工作完成后,导入新的BSP,成功编译出的系统镜像如图3所示。
图3 编译生成的系统镜像
最终将XIP.BIN烧写到喷码机平台,系统启动时只需将2 MB的XIPKERNEL复制到RAM中,而不是原来将近30 MB的NK。
这样不仅将开机时间降低至10 s以内,同时增加了29 MB的可用RAM,使系统拥有了运行大型应用软件的能力。
喷码机产品的应用领域越来越广,针对不同的需要设计开发板,在定制系统时就必须有配套的BSP。移植在满足应用要求的同时可以大大节省开发时间,减少产品的研发成本。
[1] 何剑锋,李祥,何月顺.基于XScale PXA270处理器平台WindowsCE5.0系统的BSP二次开发[J].化工自动化及仪表,2009,36(4):72-75.
[2] 张飞,白瑞林,陆林.WinCE5.0 Bootloader的设计与实现[J].计算机工程,2009,35(7):232-234.
[3] 赵永志.WinCE5_0在嵌入式平台ARK1200上的移植与应用[D].哈尔滨:哈尔滨工业大学,2009.
[4] 夏军,胡景春.基于ARM的Windows CE移植及应用开发[J].计算机技术与发展,2011,21(4):129-132.
[5] 李尚柏,钟瑞.基于ARM的嵌入式Windows CE系统高级开发技术[M].北京:清华大学出版社,2011:192-198.
[6] 张德华.基于AT91SAM9261平台的Windows CE的移植[J].工业控制计算机,2009,22(4):62-65.
王宏文(教授),研究领域为现代传动控制系统与智能化工程设备;李晓燕、黄金兰(硕士研究生),研究领域为智能化工程装备、嵌入式技术。
Development of BSP Based on WinCE 5.0 and Inkjet Printer Platform
Wang Hongwen,Li Xiaoyan,Huang Jinlan
(School of Control Science and Engineering, Hebei University of Technology, Tianjin 300130, China)
Based on the inkjet printer hardware platform with its core of S3C2440A CPU, the development of BSP based on Windows CE5.0 is introduced. Compositions of inkjet printer platform and the frame construction of BSP are analyzed, and then transplantations of Bootloader, OAL, device driver,configuration files and the implementation approach that divides the kernel into a few pieces on the basis of BINFS and Multi-bin are stated in detail by using the comcept of code reuse. Practices show that the BSP in the inkjet printer platform is stable with high-reliability, and can effectively improve system boot speed. Meanwhile it also has the opportunity to run large-scale printing software.
inkjet printer;WinCE5.0;Multi-bin;BSP
TP316
A
迪娜
2013-12-07)