文献标识码:A
文章编号: 0258-7998(2015)02-0031-04
0 引言
当今嵌入式系统的功能日趋多元化,系统间通过总线、背板以及网络通信的互联日趋复杂,这导致嵌入式系统的调试、集成和测试变得相对困难。嵌入式软件开发者经常因为缺乏硬件开发板等物理设备,导致开发效率低下。譬如在获取硬件开发板实物之前,系统开发者很难提前开发基于硬件开发板的软件程序;当硬件开发板数量有限时,并不能保证每个系统开发者都能拿到硬件开发板进行相关软件的设计与开发。
Simics作为一款快速的、功能精确的全系统仿真环境[1],较好地解决了上述问题。Simics为多种任务提供了一个共用框架来实现处理器设计、存储器分级体系设计、元器件开发和测试、软件质量的自动化测试、SOC虚拟原型、软硬件协同仿真,以及固件、驱动程序和操作系统的开发等功能。首先,Simics提供了一个功能强大的虚拟平台,可以模拟处理器、存储器、板级硬件和复杂网络系统等任意规模的硬件目标设备,解决了软件开发者因缺乏硬件设备引起的问题。Simics允许开发者在硬件开发板实物到位之前,就开始进行相应的软件开发、系统集成以及系统测试,从而缩短产品的上市时间。针对于目标设备的板级支持包(Board Support Package,BSP)、固件、实时操作系统、中间件和应用程序等目标软件不需要进行任何更改,即可运行在Simics模拟的硬件平台上[2]。其次,Simics提供了故障注入、虚拟系统时间的控制和硬件寄存器管理等功能,并且支持整个系统精确地、并可恒现地正向和回溯执行以及创建系统检查点快照。嵌入式软件开发者可以借助Simics特有的开发及调试方式,降低调试难度,提高开发效率。譬如,同时启动或暂停操作系统与处理器的时钟,检查所有系统部件的状态。
美国风河系统公司推出的VxWorks嵌入式操作系统具备实时性好、可靠性高、可定制性强等特点。VxWorks嵌入式操作系统在实时嵌入式系统领域一直占据一席之地,尤其是在国防、航空、工业控制等领域具有统治地位。
本文以VxWorks 6.9嵌入式操作系统为例,论述了在风河Simics全系统仿真环境下进行嵌入式操作系统的bootrom开发、操作系统的定制、设备驱动和应用程序的开发方法,探究出了利用Simics全系统仿真环境协助开发者进行嵌入式操作系统底层软件、中间层软件和上层应用软件开发的新方法。
1 Simics全系统仿真环境架构
借助于Simics全系统仿真环境,开发者不仅可以进行硬件建模,还可以模拟真实硬件环境中运行的所有软件。Simics全系统仿真环境架构图如图1所示。Simics主要由虚拟硬件和目标软件栈两部分组成。虚拟硬件与真实的硬件设备相对应,开发者可以使用模型库,利用C/C++、SystemC、Python或DML等语言进行处理器、内存、存储设备等虚拟设备模型的开发和配置。目标软件栈自底向上分为Hypervisor层、驱动层、BSP层、固件层和实时操作系统(Real Time Operating System,RTOS)层、应用软件和中间件层。其中Hypervisor、驱动、BSP、固件和RTOS作为中间层负责上层软件与虚拟硬件的交互。此外,Eclipse、风河Workbench、Tornado等常用的开发调试工具均可配合Simics进行协同开发[3]。Simics支持运行各种目标软件,只要是能在实际硬件设备上运行的目标软件,均可在相应的Simics全系统仿真环境下运行且无丝毫差异[4]。
与VMware、VirtualBox等常用的虚拟机相比,Simics能够支持包括Power PC、Intel x86、MIPS、ARM、M68K、SPARC在内的更多类型的处理器架构[5]。与EDA仿真工具相比,Simics能够更加高效准确地运行目标软件,并提供强大的调试功能。虽然EDA仿真工具能够非常准确地仿真硬件设备,但速度往往不够快,或者不能完整地运行的整个目标软件。Simics能够较好地克服EDA仿真工具的上述缺陷。
2 开发VxWorks操作系统的bootrom
Simics可以运行风河公司官方提供的硬件目标设备模型以及开发者自定义的硬件目标设备模型。本文选用了风河官方提供的Model Library Intel Core i7 with X58 and ICH10 4.6(下文简称x86-X58-ICH10)硬件目标设备模型。该硬件目标设备模型可以仿真一个具有Intel Core i7处理器、X58北桥高速芯片组以及ICH10南桥的硬件系统。
在Simics x86-X58-ICH10硬件模型上启动VxWorks下载型映像,需要开发相应的VxWorks启动引导程序bootrom。首先,使用风河Workbench 3.3集成开发环境创建VxWorks Boot Loader Project类型的工程。输入工程名字,指定工程保存的位置,设置工程基于的BSP为Intel Nehalem BSP,设置工具链为gnu,设置bootrom格式为二进制bin格式,设置映像压缩类型为压缩型。然后,配置源代码索引,完成工程的创建。
如需修改VxWorks映像启动时的默认IP地址,则需修改Intel Nehalem BSP目录下的config.h头文件。将VxWorks映像启动时的IP地址设置为“172.21.28.64”的相应代码如下所示:
#if !defined (CDF_OVERRIDE) && !defined (PRJ_BUILD)
#define DEFAULT_BOOT_LINE \
"gei(0,0)host:vxWorks h=172.21.28.110 e=172.21.28.64 u=
target"
#endif
修改完毕后,编译该工程即可生成bootrom.bin映像。
3 定制VxWorks嵌入式操作系统
首先,创建VxWorks Image Project类型的工程。输入工程名字,指定VIP工程保存的位置。由于所定制的VxWorks镜像将要运行在Intel Core i7处理器上,因此设置工程所基于的BSP为Intel Nehalem BSP,设置工具链为gnu。然后,配置SMP、IPv6、Debug和编译器优化选项等。最后,配置源代码索引,完成VIP工程的创建。
完成创建VIP工程后,可在工程资源管理器选项卡中查看该工程的文件列表信息。其中Kernel Configuration是内核配置工具,帮助开发者快速添加或移除内核组件。vxWorks.bin、vxWorks.hex和vxWorks均是工程经过编译后生成的映像。
上述步骤只是定制了具有基本功能的VxWorks映像。由于VxWorks具有很好的可裁剪性,开发者可以根据需求添加相应的组件。以添加系统符号表组件INCLUDE_SYM_TBL_INIT及其依赖组件为例进行说明。首先选中Kernel Configuration,点击右键,单击Edit Kernel Configuration,或者直接双击Kernel Configuration打开组件配置列表。然后,按下Ctrl+F,打开内核组件查看器,输入INCLUDE_SYM_TBL_INIT。在组件树下会显示找到的组件,点击“Find”按钮,组件配置列表自动定位到找到的组件。最后,选中该组件,点击右键,选择“Include”即可将该组件添加到内核中。其他组件的添加方式与上述步骤类似。组件添加完毕后,重新编译映像。
4 开发VxBus架构的驱动程序
自VxWorks 6.2引入了VxBus设备驱动架构,该驱动架构提供了针对操作系统和硬件设备的标准接口。VxBus架构的最核心功能是VxBus驱动程序能够在风河Workbench开发环境中以组件的形式进行配置。开发者可以根据需求添加或删除驱动组件,重新编译VxWorks内核映像即可完成驱动的配置。在引入VxBus驱动架构之前,开发者若要添加或者删除VxWorks驱动,则需要修改繁琐的底层文件和代码。譬如,配置VxWorks5.5驱动程序时,开发者需要修改BSP中的sysLib.c等文件。此外,非VxBus架构的驱动程序的可移植性差,更换BSP时需要重新移植驱动程序。
开发基于VxBus的驱动,并将其集成到风河Workbench开发环境中,一般至少需要如下6个文件。其中组件描述文件、driverName.dc和driverName.dr被称为驱动配置文件。
(1)驱动源文件:实现驱动的逻辑;
(2)组件描述文件:将驱动集成至Workbench开发环境中;
(3)driverName.dc:提供了驱动注册程序的原型;
(4)driverName.dr:提供了一段调用驱动注册程序的代码;
(5)README:自述文件;
(6)Makefile:编译信息。
驱动源文件负责实现驱动的逻辑功能,从而实现对硬件设备的控制与操作。一个驱动可以包含一个或者多个驱动源文件以及可选的头文件。
组件描述文件提供了将驱动以组件的形式集成到风河Workbench开发环境中所需要的信息。VxWorks配置工具通过组件描述文件能够将基于VxBus的驱动识别成独立的组件,并集成到开发环境中。开发第三方驱动时,需要将组件描述文件拷贝到installDir\vxworks-6.x\target\config\comps\vxWorks路径下,以便VxWorks配置工具能够读取该文件。
driverName.dc文件声明了驱动注册程序的原型,其文件名要和驱动源文件保持一致。driverName.dr文件描述了调用驱动注册程序的方法。若新增驱动至VxWorks源码树,则需在installDir\vxworks-6.x\target\config\comps\src\
hwif路径下执行如下指令,将新增驱动的配置文件合并到vxbUsrCmdLine.c文件中:
makevxbUsrCmdLine.c
README文件包含驱动的版本列表、文件列表以及所支持的设备等信息。在撰写README文件时,可以参考风河官方提供的驱动的README文件。
Makefile文件定义了编译驱动的源文件的规则,并通过OBJ_COMMON宏指定了编译出的目标文件列表。
5 Simics上启动VxWorks操作系统
在x86-X58-ICH10硬件模型上启动VxWorks操作系统,首先要编写Session脚本文件。Simics在加载bootrom之前需要BIOS的引导。BIOS执行完毕后,跳转到bootrom继续执行。具体的实现方法是:将bootrom加载到RAM中,然后将BIOS的INT 19控制句柄切换到bootrom所在的RAM处。代码如下:
#itl_nehalem架构的bootrom入口点
$ram_boot_entry = 0x8000
#bootrom.bin文件的完整路径
$bootrombin="d:/bootrom.bin"
#VxWorks内核的完整路径
$kernel="d:/vxWorks"
#创建具有磁盘和串口控制台的x86-X58-ICH10虚拟机
#设置磁盘大小为512 KiB,涵盖了引导扇区(Boot Sector)
$disk_size = 0x80000
#启用串口控制台
$uart0_text_console = TRUE
#初始化x86-X58-ICH10硬件配置
run-command-file"%simics%/targets/x86-x58-ich10/x86-x58-ich10-system.include"
#初始化组件
instantiate-components
#设置系统信息,设置VxWorks可使用的CPU数目
$system->system_info = "Viper - vxWorks 6.9 SMP"
$system.mb.cpu0.core[0][0]->cpuid_logical_processor_count=0x1
cpu-switch-time 0.0001
#为BIOS设置一个假想的启动磁盘
#MBR直接跳转到bootrom入口处
$disk.hd_image.set 0x0 0xea 1
$disk.hd_image.set 0x1 ($ram_boot_entry& 0xFF ) 1
$disk.hd_image.set 0x2 (($ram_boot_entry& 0xFF00)>>8) 1
$disk.hd_image.set 0x3 (($ram_boot_entry& 0xFF0000)>>16) 1
$disk.hd_image.set 0x4 (($ram_boot_entry& 0xFF000000)>>24) 1
#引导扇区(Boot Sector)设置为0x55AA,分区结束标志
$disk.hd_image.set 0x1fe 0x55 1
$disk.hd_image.set 0x1ff 0xaa 1
#开始启动VxWorks映像
script-branch{
local $bpID = (break $ram_boot_entry)
local $con = $system.serconsole.con
#等待BIOS跳转至bootrom入口处
wait-for-breakpoint $bpID
delete $bpID
#加载bootrom
load-file $bootrombin $ram_boot_entry
$con.wait-then-write "auto-boot..." "*"
$entry = ( load-binary $kernel )
$con.wait-then-write -s "Boot]:"("g"+(hex $entry)+"\n")
}
上述代码在x86-x58-ich10-system.include文件中初始化了x86-X58-ICH10的硬件配置。首先,设置了硬盘大小为20 GB,设置时钟时间为当前本地时间。其次,设置CPU执行一条指令所需的平均时钟周期数为1,CPU类型为core-i7,CPU内核数目为1,主频为2 GHz。再次,设置主机名为viper,指定BIOS文件为seabios-simics-x58-ich10-1.6.3-20121004.bin,指定串口0作为文本控制台,设置MAC地址为00:19:A0:E1:1C:9F。最后,使用create-chassis-x58-ich10命令创建X58-ICH10主板,并配置南桥和北桥。
Session脚本编写完毕后,即可启动Simics。点击“New Session from Script”按钮,选中并载入编写好的Session脚本。此时,Simics控制板上显示将要启动的操作系统的名字以及硬件模型的相关信息。VxWorks在x86-X58-ICH10硬件模型上启动成功,如图2所示。
在VxWorks的启动过程中,开发者可以在任意时刻暂停启动过程,查看启动输出信息和相关的寄存器状态。开发者还可以使用Simics特有的检查点功能,将当前目标硬件平台以及所有软件的运行状态完整地保存在检查点文件中。该类型的文件可以在任意安装了相关Simics硬件安装包的环境下完全恢复现场。检查点调试主要有两大优势。第一,Simics可以通过重载检查点文件,恢复检查点位置的软硬件状态,迅速并精确地回到用户想要的位置;第二,检查点文件可以在用户之间进行共享,可以在世界任何地方重新载入,增强了开发团队协作能力,大大提高了调试效率。上述调试方法在传统的开发过程中是极难实现的。
譬如,在遇到某个故障错误时,用户可以暂停Simics并在命令行窗口中执行write-configuration “my-configuration”命令,创建一个名字为my-configuration的检查点,保存故障现场。检查点文件主要由info、config和镜像文件等三类文件组成。info文件提供了开发主机名、主机上安装的Simics产品列表等信息。config文件提供了硬件模型的配置信息。镜像文件保存了当前软硬件的运行状态。检查点创建完成后,用户可以将my-configuration检查点文件共享给其他用户。其他用户在Simics命令行窗口上执行read-configuration "my-configuration"命令即可重载检查点,恢复软硬件状态,然后分析故障并进行调试。
6 开发具有图形界面的VxWorks应用程序
开发具有图形界面的VxWorks应用程序需要用到风河媒体库。风河媒体库以源代码的方式提供了基本的图形、音频和视频开发技术以及开发框架。开发者需要自行编译风河媒体库文件,调用相应的API库函数进行多媒体应用程序的开发。
风河媒体库主要由软件开发工具包(Software Development Kit,SDK)和驱动开发工具包(Driver Development Kit,DDK)组成。SDK提供了丰富的API集,涵盖图形、输入处理、多媒体、字体、内存管理和设备管理等操作。开发者可以使用SDK开发独立于硬件设备之外的、具有较高可移植性的应用程序。DDK提供了完整的驱动程序参考集,这些参考集包括常用的硬件配置和API集,能够帮助开发者快速开发驱动程序。
本文开发了具有图形界面的VxWorks启动型内核模式应用程序。VxWorks启动型内核模式应用程序代码是VxWorks映像文件的一部分,VxWorks系统启动后不需要单独下载。当映像编译和链接风河媒体库时,应用程序代码也会自动链接到风河媒体库。由于只有内核和应用程序所需要的风河媒体库才会被链接到内核中,VxWorks内核的尺寸较小。该类型的应用程序优点是VxWorks映像所需内存空间较小和映像尺寸较小,应用程序在VxWorks启动后可以自动执行。
所开发的图形应用程序能够绘制不同颜色和不同粗细的实线和虚线、多边形、圆形和扇形等基本图形,如图3所示。在调试图形应用程序时,可以使用Simics强大的正向和回溯执行功能,逐步显示图形的绘制过程。
7 总结
本文论述了在风河Simics全系统仿真环境下进行VxWorks 6.9嵌入式操作系统的bootrom开发、VxWorks操作系统的定制、设备驱动和应用程序的开发方法,探究出了利用Simics全系统仿真环境协助开发者进行嵌入式操作系统底层软件、中间层软件和上层应用软件开发的新方法。
参考文献
[1] Wind River.Wind River Simics getting started 4.4[Z].2012.
[2] Wind River.WindPO_Simics_0411_cn[Z].2011.
[3] Wind River.Wind River Simics Eclipse user′s guide[Z].2014:5-13.
[4] Wind River.Wind River推出功能更强大的全系统仿真工具Simics 4.6[Z].2011.
[5] Wind River. Wind River Simics[Z].2012.