文章主要是记录下些看到BSP包开发相关内容。
从BSP包完成功能来说。BSP流程分成两部分。首先是位于BootRom中的Boot代码,它的作用是实现配置硬件和启动VxWorks下载程序。接下来是下载后跳转到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入口。
它是运行的开始,实现这一部分是首先的。它实现判断启动类型、配置内核和非内核寄存器以及内存和外围设备的读写时序。因此可以在此处加入内存检测功能。在BSP中无法进行调试,只能通过闪灯实现云信正确与否的判断。闪灯功能函数也要在此加入。
判断启动类型和配置寄存器:这一部分不需要改动。
配置内存和外围设备读写时序:要进行改动。这一部分的SDRAM、ROM、FLASH、FPGA有相应的模板可以参考。它的实现是通过使用宏定义来实现的。但是要改动的话也不难,一般是改动空间大小的屏蔽位,读写位数,以及片选寄存器OR和BR。至于特殊外设的读写有待讨论。
内存检测在这里实现较复杂,它根据相应的内存检测算法实现。主要是对地址线和数据线的检测。通过写入数据再会读出数据来判断。使用”走步1″和”走步0″算法。这一部分较多的依赖硬件,可移植性较差,根据自己的单板改动。
闪灯在这一部分是强烈推荐的。因为闪灯才能定位程序的运行位置。闪灯函数可移植,一般要改动,因为灯可能接在不同的I/O口上。另外注意860SAR的PORT B是32位的。具体的端口见相应的CPU的I/O口的参数,配置相应的寄存器。
RomInit在函数结尾跳入RomStart。
bootInit.C : romStart()
它是系统运行的第一个C函数。这一部分是Wind River公司提供的标准程序,一般不需改动。该函数是C的入口函数,由汇编程序调用,主要完成清内存,将ROM中的程序拷贝到RAM,解压并跳至解压后的程序处运行,一般是sysInit()的入口地址。
拷贝的过程如下:
A、代码段不是驻留在ROM中,要拷贝代码段和数据段
B、如代码段是驻留在ROM中,则只拷贝数据段
C、未用的内存清零
D、需要时,要进行解压缩
UsrInit在BootConfig.c文件中。它主要是实现硬件的初始化。其中涉及到串口、网口的初始化、CONSOLE的配置等。其中串口和网口的配置是BSP的重要部分,但860CPU对串口和网口有很好的支持,只要做很小的改动即可。串口很简单,网口较复杂一些。
UsrRoot在BootConfig.c文件中。它主要是实现VxWorks文件的下载,并且跳转到VxWorks的入口地址。从而进入到操作系统中去。
—————————————-以上部分针对boot ROM—————————————-
sysALib.S : sysInit()
sysInit()是VxWorks映像的入口地址,起始地址由RAM_LOW_ADR定义。它首先关中断,使cache无效,初始化处理器的寄存器为缺省值,使tracing无效,清除中断寄存器,初始化usrInit()的堆栈并激活usrInit()。
它是vxworks的启动代码。它与RomInit的作用相同,对于这个文件我们一般不需要去改动它。
注意,在sysInit()中必须重新初始化在romInit()中所作的硬件初始化。
UsrInit在Usrconfig.c中。它的作用与Boot中的UsrInit的作用相同,他们都调用SysLib.c中的子函数,实现相同的硬件初始化功能。
UsrRoot在UsrConfig.c中。它的作用与Boot中的UsrRoot的作用类似。但是这里的UsrRoot是最终进入到应用程序中去。
————————————-以上部分针对VxWorks操作系统————————————
关于usrInit()和usrRoot()另外一种说明:
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中指定)
对于硬件初始化的顺序,大致可按下表中的形式进行:
1、sysInit() 所在的文件sysALib.s
(a)锁住中断
(b)禁用缓冲
(c)用缺省值初始化系统中断表(仅i960)
(d)用缺省值初始化系统错误表(仅i960)
(e)初始化处理器寄存器的一些缺省值
(f)使回溯无效
(g)清除所有悬置中断
(h)激活usrInit(),指明启动类型。
2、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
3、kernelInit()初始化并启动内核。所在文件kernelLib.c
(a)激活intLockLevelSet()
(b)从内存池顶部创建堆栈和TCB
(c)调用taskInit(),taskActivate(),用于usrRoot()
(d)调用usrRoot()
4、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() 所在文件romInit.s
(a)禁止中断
(b)保存启动类型
(c)硬件初始化
(d)调用romStart()
2、romStart() 所在文件bootInit.c
(a)将数据段从ROM拷贝到RAM,清内存
(b)将代码段从ROM拷贝到RAM,有必要的话解压缩
(c)调用usrInit()
3、usrInit() 所在文件usrConfig.c
初始化程序
4、usrKernelInit() 所在文件usrKernel.c
如果相应的配置文件被定义,对应函数被调用
5、kernelInit() 所在文件kernelLib.c
初始化并启动内核
6、usrRoot() 所在文件usrConfig.c
初始化I/O系统,驱动器,创建设备
7、Application routine 所在文件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中。