要了解VxWorks BSP的制作,首先要对VxWorks的启动过程有个大体的了解。下面首先说说VxWorks的启动过程。一般来说,所有的处理器执行相同的逻辑步骤初始化和加载VxWorks,但是一些处理器可能会有一些特殊的步骤,而另外一些则可能跳过一些步骤。但它们都进行如下步骤,入:初始化处理器,并在存储器的特定位置提供一段代码(可能还有一些表)以供处理器上电或重启时运行。这段代码设置处理器的状态,初始化存储器和存储器地址,关中断把控制权交给启动代码(bootstrapping code)。
1、处理器首先跳到ROM的入口地址,设置状态字并创建一个哑堆栈(dummy stack)
2、跳到C程序的入口地址,根据哑堆栈中的参数决定是否清零内存RAM(若是泠启动cold start则清零),再把ROM段的剩余部分拷贝到RAM(如果ROM代码是压缩的,还要解压)。
3、处理器跳到RAM的入口地址(bootConfig.c),是cache无效,清零bss段,初始化中断向量表,进行板级初始化。
4、启动多任务内核
VxWorks的boot ROM本身就是一个独立的应用。开发者可用它通过网络来启动一个VxWorks映像并和应用代码连接。
VxWorks启动流程
romInit()------romStart()-------sysInit()---------initVectBaseSet()-------sysHwInit()--------usrKernelInit()-------kernelInit()-------usrRoot()
文件和程序说明:
romInit.S : romInit()
关中断,把启动类型(cold/warm)入栈,清零cache后跳到romStart入口。
bootInit.C : romStart()
把ROM代码和数据段拷贝并重定位到RAM,清零RAM的未用部分,需要的话要进行解压缩,然后跳到sysInit()的入口地址。
拷贝的过程如下:
A、代码段不是驻留在ROM中,要拷贝代码段和数据段
B、如代码段是驻留在ROM中,则只拷贝数据段
C、未用的内存清零
D、需要时,要进行解压缩
sysALib.S : sysInit()
sysInit()是VxWorks映像的入口地址,起始地址由RAM_LOW_ADR定义。它首先关中断,使cache无效,初始化处理器的寄存器为缺省值,使tracing无效,清除中断寄存器,初始化usrInit()的堆栈并激活usrInit()。
注意,在sysInit()中必须重新初始化在romInit()中所作的硬件初始化。
usrConfig.C and bootConfig.C : usrInit()
它是VxWorks运行的第一个C代码,在supervisor mode中激活。它关中断,存储有关启动类型(boot type)的信息,在VxWorks内核运行前进行必要的初始化。
A、初始化cache模式,设置为安全状态,在usrInit()结束时使cache有效。
B、清零系统bss段
C、初始化中断向量表,调用VectBaseSet(),exeVecInit();
D、初始化系统硬件,但使之无效Quiescent State,调用sysHwInit(),这是一个与硬件有关的过程,是我们要针对不同的目标板进行修改的重要部分,其中涉及到串口,网口的初始化,CONSOLE的配置等。
E、调用usrKernelInit(),并使能cache
F、调用kernelInit(),创建usrRoot()。
usrKernel.C : kernelInit()
初始化内核可选组建kernel facility
kernelLib.C : usrKernelInit()
初始化多任务环境。
调用intLockLevelSet(),使时间片(round-robin)方式无效,在内存的高端创建中断堆栈,ROOT堆栈和TCB,创建usrRoot(),中断usrInit()的运行,然后打开中断,注意要清除中断寄存器。
usrConfig.C and bootConfig.C :usrRoot()
初始化I/O系统,驱动器,设备(在configAll.h和config.h中指定)
程序列表
对于硬件初始化的顺序,大致可按下表中的形式进行:
函数
sysInit()
所在的文件sysALib.s
函数的功能
(a)锁住中断
(b)禁用缓冲
(c)用缺省值初始化系统中断表(仅i960)
(d)用缺省值初始化系统错误表(仅i960)
(e)初始化处理器寄存器的一些缺省值
(f)使回溯无效
(g)清除所有悬置中断
(h)激活usrInit(),指明启动类型。
函数
usrInit()
所在文件
usrConfig.c
函数功能
(a)对bss赋零
(b)保存bootType于sysStartType;
(c)调用excVecInit(),初始化所有系统和缺省中断向量
(d)依次调用sysHwInit(),usrKernelInit(),kernelInit()。
usrKernelInit()依次调用classLibInit(),taskLibInit(),taskHookInit(),semBLibInit(),semMLibInit(),
semCLibInit(),semOLibInit(),wbLibInit(),msgQLibInit(),qInit(),workQInit(),usrKernel.c
函数kernelInit()
kernelInit()初始化并启动内核。
所在文件
kernelLib.c
函数功能
(a)激活intLockLevelSet()
(b)从内存池顶部创建堆栈和TCB
(c)调用taskInit(),taskActivate(),用于usrRoot()
(d)调用usrRoot()
函数
usrRoot(),初始化I/O系统,驱动,设备(在configAll.h和config.h中指定)
所在文件
usrConfig.c
函数的功能
(a)调用sysClkConnect(),sysClkRateSet(),iosInit(),[ttyDrv()]
(b)初始化excInit(),logInit(),sigInit()
(c)初始化管道pipeDrv()
(d)stdioInit(),mathSoftInit()或mathHardInit()
(e)wdbConfig():配置并初始化目标代理机
在大多数目标板的板级支持包中,VxWorks的入口点由两个函数:romInit()和romStart()来完成,而非sysInit()。具体基于ROM的VxWorks的初始化过程如下表所示:
函数 函数功能 所在文件
1、romInit()
2、romStart()
3、usrInit()
4、usrKernelInit()
5、kernelInit()
6、usrRoot()
7、Application routine
(a)禁止中断
(b)保存启动类型
(c)硬件初始化
(d)调用romStart()
(a)将数据段从ROM拷贝到RAM,清内存
(b)将代码段从ROM拷贝到RAM,有必要的话解压缩
(c)调用usrInit()
初始化程序
如果相应的配置文件被定义,对应函数被调用
初始化并启动内核
初始化I/O系统,驱动器,创建设备
应用程序代码
romInit.s
bootInit.c
usrConfig.c
usrKernel.c
kernelLib.c
usrConfig.c
Application source file
BSP的文件构成如下:
1、硬件初始化文件:处理器初始化程序
2、操作系统初始化文件:各类头文件、驱动程序、操作系统内核初始化程序、创建多任务环境程序
3、工具文件:各类make文件,制作系统引导文件的工具
BSP的工作
1、单板硬件初始化,主要是CPU的初始化,为整个软件系统提供底层的硬件支持
2、为操作系统提供设备驱动程序和系统中断服务程序
3、定制操作系统的功能,为软件系统提供一个实时多任务的运行环境
4、初始化操作系统,为为操作系统正常运行做好准备
BSP的生成有赖于VxWorks提供的一些开发和调试工具
术语的意义:
CPU:目标板的CPU
TOOL:主机开发工具
ROM_TEXT_ADRS:启动ROM的16进制入口地址,多数目标板设置为ROM的起始地址
ROM_SIZE:ROM的16进制空间大小
ROM_LOW_ADRS:VxWorks装入的起始地址
ROM_HIGH_ADRS:boot ROM拷贝到RAM的起始地址
LOCAL_MEM_LOCAL_ADRS:目标板存储空间的起始地址
LOCAL_MEM_SIZE:固定(静态)存储器大小
USER_RESERVED_MEM:保留内存大小
RAM_HIGH_ADRS:拷贝boot ROM映像的目标地址
ROM_BASE_ADRS:ROM起始地址
ROM_TEXT_ADRS:boot ROM的入口地址,多数为ROM空间的起始地址
ROM_WARM_ADRS:热启动的入口地址
ROM_SIZE:ROM空间的大小
其中ROM_TEXT_ADRS和ROM_SIZE的定义必须和Makefile一致。
常见错误
A、LOCAL_MEM_LOCAL_ADS的重要性,大多数应用都设置为0
B、在romInit.S中做了太多的设备初始化,romInit.S只做基本的初始化,真正的设备初始化在sysHwInit()中完成。
C、在sysALib.S中做的太少,所有在romInit.S中所做的初始化都必须在sysALib.S中重新初始化
D、把修改过的驱动程序放在错误的目录,与BSP有关的驱动程序应该放在target/config/bspname中,而不是WRS的target/src/drv和target/h/drv中。
E、混淆配置选项,在文件config.h中必须是可选BSP的配置,不可选项应包含在bspname.h中。