VxWorks的BSP开发

来源:互联网 发布:坏男孩软件 编辑:程序博客网 时间:2024/04/26 21:47

原文:http://hulianghui.com/blog/?p=19

VxWorks的BSP开发

文章主要是记录下些看到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中。

原创粉丝点击