现在我们的工作中,应用程序一般都是和BSP联编,然后将vxworks_rom.bin烧到班子里。在BSP启动后,调用应用程序的函数的。

但是这样有个问题,就是应用程序和BSP结合的太紧密了。BSP开发者得将BSP代码给应用程序开发者,或者应用程序开发者得将应用程序编译后的.a文件给BSP开发者,才能完成程序的升级!那么下面的方法是我这两天弄出来的,可以将应用程序和BSP开发分离的一个办法。只要开始将接口约定好就可以了!还不是很成熟,我也还没有正式在项目中使用,但是我相信这是一个不错的选择!

首先,要建立一个文件系统,TFFS的文件系统就可以。磁盘大小只要可以放的下应用程序编译后的文件就好了。这步就不赘述了。

然后,在BSP工程的usrApp中添加下载应用程序模块和启动接口程序的代码。下面主要说明这步,代码如下:

 
 
#include "loadLib.h" 
#include "stdio.h" 
#include "taskLib.h" 
#include "ioLib.h" 
extern SYMTAB_ID sysSymTbl; 
void usrAppInit (void) 
{ 
#ifdef USER_APPL_INIT 
USER_APPL_INIT; /* for backwards compatibility */ 
#endif 
FUNCPTR taskEntry=NULL; 
SYM_TYPE *pType; 
intfd=open("/tffs0/appProj.out",O_RDONLY,0); 
if(fd==NULL) 
{ 
printf("/nopen project fail../n"); 
return; 
} 
if(loadModule(fd,LOAD_ALL_SYMBOLS)==ERROR) 
{ 
printf("/nload module fail.../n"); 
return; 
} 
if(symFindByName(sysSymTbl,"appEntry",(char* *)&taskEntry,pType)==ERROR) 
{ 
printf("/nfind symbol fail.../n"); 
return; 
} 
taskSpawn("entry",100,0,1024,taskEntry,0,0,0,0,0,0,0,0,0,0); 
/* add application specific code here */ 
} 
 

主要代码。只要应用程序将升级后的工程编译成.out文件,上传到磁盘/tffs0中,就可以了!当然,应用程序的入口函数appEntry不能变。

最后,这段代码如果之间运行,可能会遇到一些问题:

1. loadMoudle失败,报错Relocation value doesnot fit in 24 bits。这是因为函数在内存中的位置超出了跳转的最大距离(一般跳转指令是24bit,32M).为了解决这个问题,按如下步骤: 在应用程序的工程中选择"Builds"->"default"->"c/c++complier",在后边加入-mlongcall(GUN)或者-Xcode-absolute-far(diab),点击OK.把这个编译出来的.out文件上传到文件系统。

2. symFindByName失败。这个原因可能是因为应用程序的工程是cpp文件,也就是c++文件。c++编译出来的文件,符号表的入口和C 不同,所以找不到。如,同样的entry(void,int)函数,C编译出来就是entry,而C++可能是entry_Fvi,这个由于不同的编译器而不同。解决这个问题,有两个办法:

  • 入口函数所在的文件,不要用cpp文件,全部改用c文件。
  • cpp文件中的入口函数包含在external "C" {}中。
摘 要:介绍了一种新的基于Matlab/ RTW(Real2Time Workshop) 和VxWorks 实时操作系统的仿真方法,构建了基于Simulink 的某型无人机飞控系统仿真模型,可自动生成优化的嵌入式实时仿真代码、在线调整模型参数并监视仿真数据。

与传统的手工编写和修改仿真模型代码的方法相比,加速了半物理仿真平台的研制。通过使用该平台对某型无人机飞控系统进行了大量的实时半物理仿真,优化了控制律。

一般的飞控系统仿真总是分为2 个阶段:纯数字仿真阶段和半物理仿真阶段。飞控系统半物理仿真平台的研制除了设计和构建半物理仿真的硬件平台之外,一个工作量很大的内容就是开发半物理仿真软件。而传统的半物理仿真软件开发都是由开发人员手工编写仿真代码,工作量大且容易出错。

对于一般的开发过程虽然能在纯数字仿真阶段使用Matlab 等仿真软件开发仿真模型,但是到了半物理仿真阶段还需要人工把在纯数字仿真阶段使用的仿真模型翻译成可以被实时仿真机执行的代码而不能直接利用数字模型。怎样才能利用已经开发好的仿真模型,直接把这些模型放到仿真机中运行呢?Matlab RTW(Real2TimeWorkshop 实时工作空间)能够实现这一功能。使用基于Matlab/ RTW的实时仿真方法将大大减少仿真软件的开发量、避免各种手工编写代码出现的错误、缩短半物理仿真平台的开发周期。

1  基于Matlab/ RTW 和VxWorks 操作系统的实时仿真方法

RTW 是MATLAB图形建模仿真环境Simul2ink 的一个重要补充功能模块,简而言之,它是一个基于Simulink 的代码自动生成环境。它能直接从Simulink 模型中产生优化、可移植的嵌入式实时代码[2 ] ,并且能够根据目标机配置自动生成适合该目标机软硬件环境的可执行程序,既支持x86 、DSP、PowerPC 等目标机硬件也支持Dos、VxWorks、xPC等操作系统。RTW 除了可以将Simulink 模型自动转换成代码在目标机上运行外,还支持基于模型的在线调试(即在半物理仿真进行过程中在线修改仿真机中模型参数、监视仿真数据) 。

因此使用RTW进行实时系统的设计、仿真、测试可以缩短系统开发周期并降低成本。VxWorks 操作系统[3 ] 是美国WindRiver 公司于1983 年设计开发的一种嵌入式实时操作系统(RTOS) 。该操作系统以良好的可靠性、卓越的实时性、高性能的内核以及友好的用户开发环境,在嵌入式实时操作系统领域处于世界领先地位,被广泛地应用在通信、军事、航空、航天等高精尖技术领域及实时性要求极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。

在美国的F216 、FA218战斗机、B22 隐形轰炸机和爱国者导弹上,甚至连1997 年4 月在火星表面登陆的火星探测器上也使用了VxWorks 操作系统。所谓基于Matlab/ RTW 和VxWorks 的实时仿真方法就是应用Matlab/ Simulink 模块框图建立起仿真系统模型,以图形化方式对算法进行概念化,在搭建起半物理仿真硬件平台后使用RTW 自动代码生成功能,生成可以在VxWorks 实时操作系统上运行的仿真模型的实时C 代码;使用在线调参功能修改仿真模型参数,直至整个半物理实时仿真平台完全调通。基于Matlab/ RTW 的实时仿真方法实现了一种新的快速从纯数字仿真到半物理仿真的一体化过程。其仿真流程图如图1 所示。

在嵌入式系统中,我们通常会要求VxWorks文件尽量小,比如通过串口、软盘或tffs加载VxWorks的时候,如果文件太大,可能无法存储,或加载失败。下面介绍一种利用Tornado和VxWorks自带的deflate和inflate,对VxWorks文件进行压缩和解压缩的技术。

1 使用Tornado创建bootable的project,包括应用程序。对VxWorks进行适当的裁减和配置。

2 如果准备将VxWorks存储于硬盘,软盘或tffs上,应该在usrAppInit中使用usrNetEndDevStart 和 usrNetIfConfig启动网络接口。如果存储于tffs上,还要修改usrNetBoot.c中:

if ( (strncmp (sysBootParams.bootDev, "scsi", 4) == 0) 
 || (strncmp (sysBootParams.bootDev, "ide", 3) == 0) 
 || (strncmp (sysBootParams.bootDev, "ata", 3) == 0) 
 || (strncmp (sysBootParams.bootDev, "fd", 2) == 0)) 

改为

if ( (strncmp (sysBootParams.bootDev, "scsi", 4) == 0) 
 || (strncmp (sysBootParams.bootDev, "ide", 3) == 0) 
 || (strncmp (sysBootParams.bootDev, "ata", 3) == 0) 
 || (strncmp (sysBootParams.bootDev, "tffs", 4) == 0) 
 || (strncmp (sysBootParams.bootDev, "fd", 2) == 0)) 

3 在dos下运行 tornado/host/x86-win32/bin/torvars.bat

4 进入VxWorks所在的目录,运行: deflate VxWorks.z。这里我们默认.z文件是压缩文件。

5 如果准备将VxWorks.z存储于硬盘,软盘或tffs上,需要首先创建相应的设备,并用dosFS初始化。如 果是通过串口或网络加载VxWorks.z,则需要初始化相应的接口。

6 修改bootConfig.c文件:

a. 在LOCAL STATUS netLoad 函数的 tftpXfer和 ftpXfer这一部分代码结束的地方添加:

来源于网络,谢绝商业用途

一、WINDRIVER.TORNADO.V2.2.FOR.COLDFIRE

CD1= Tornado 2.2/VxWorks 5.5 for ColdFire (DISK_ID: TDK-14627-ZC-01)

CD2= BSPs/Drivers for VxWorks 5.5: ColdFire (DISK_ID: TDK-14637-ZC-01)

软件大小:347M

安装方法:

  1. 首先安装虚拟光驱软件DAEMON3.2
  2. 分别MOUNT 文件夹CD1和CD2下后缀名为BIN的文件
  3. 自动安装后,输入如下序列号
  4. 拷贝CRACK目录下的license.dat 到c:\flexlm 目录。如果没有这个目录,自己建一个。设置如下环境变量: LM_LICENSE_FILE = c:\flexlm\license.dat

安装序列号如下:

CD1: A7K8B-MbE7p-9rKfE-Gz9aP-bE59C

CD2: A7K9e-Rb9Cp-FNB79-gzbdd-F999C

二、WINDRIVER.TORNADO.V2.2.FOR.SUPERH

CD1= Tornado 2.2/VxWorks 5.5 for SuperH (DISK_ID: TDK-14625-ZC-01)

CD2= BSPs/Drivers for VxWorks 5.5: SuperH (DISK_ID: TDK-14635-ZC-01)

软件大小:512M

安装序列号如下:

CD1: dI&hi-qM6Ip-9rBb3-GzhsN-bE59g

CD2: BGphe-MbE7p-8rKf3-gzDPB-F999C

Wind内核中有二进制信号量、计数信号量和互斥信号量三种类型,为了是运用程序具有可移植性,还提供了POSIX(可移植操作系统接口)信号量 。在VxWorks中,信号量是实现任务同步的主要手段,也是解决任务同步的最佳选择。

关于互斥的实现:

使用二进制信号量可以很方便的实现互斥,互斥是指多任务在访问临界资源时具有排他性。为了使多个任务互斥访问临界资源,只需要为该资源设置一个信号量,相当于一个令牌,那个任务拿到令牌即有权使用该资源。把信号量设置为可用,然后把需要的资源 的任务的临界代码 置于semTake()和semGive()之间即可。

注明:

1、互斥中的信号量与任务优先级的关系:任务的调度还是按照任务优先级进行,但是在使用临界资源的时候只有一个任务获得信号量,也就是说还是按照任务优先级获得信号量从而访问资源。只是当前使用资源的任务释放信号量semGive(),其它任务按照优先级获得信号量。

2、信号量属性中的参数为:SEM_Q_PRIORITY。而且在创建信号量的时候必须把信号量置为满SEM_FULL。即信号量可用。

基本实现互斥模型:

 
 
SEM_ID semMutex; 
semMutex = semBCreate(SEM_Q_PRIORITY, SEM_FULL); 
 
task(void) 
{ 
        semTake(semMutex, WAIT_FOREVER);//得到信号量,即相当于得到使用资源的令牌 
        //临界区,某一个时刻只能由一个任务 访问 
        semGive(semMutex); 
} 
 

关于任务同步的实现