vxWorks应用程序加载的另一种办法

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

但是这样有个问题,就是应用程序和BSP结合的太紧密了。BSP开发者得将BSP代码给应用程序开发者,或者应用程序开发者得将应用程序编译后的.a文件给BSP开发者,才能完成程序的升级!

那么下面的方法是我这两天弄出来的,可以将应用程序和BSP开发分离的一个办法。只要开始将接口约定好就可以了!还不是很成熟,我也还没有正式在项目中使用,但是我相信这是一个不错的选择!

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

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

  1. #include "loadLib.h"
  2. #include "stdio.h"
  3. #include "taskLib.h"
  4. #include "ioLib.h"
  5. extern SYMTAB_ID sysSymTbl;
  6. void usrAppInit (void)
  7. {
  8. #ifdef USER_APPL_INIT
  9. USER_APPL_INIT;  /* for backwards compatibility */
  10. #endif
  11. FUNCPTR taskEntry=NULL;
  12. SYM_TYPE *pType;
  13. intfd=open("/tffs0/appProj.out",O_RDONLY,0);
  14. if(fd==NULL)
  15. {
  16. printf("/nopen project fail../n");
  17. return;
  18. }
  19. if(loadModule(fd,LOAD_ALL_SYMBOLS)==ERROR)
  20. {
  21. printf("/nload module fail.../n");
  22. return;
  23. }
  24. if(symFindByName(sysSymTbl,"appEntry",(char* *)&taskEntry,pType)==ERROR)
  25. {
  26. printf("/nfind symbol fail.../n");
  27. return;
  28. }
  29. taskSpawn("entry",100,0,1024,taskEntry,0,0,0,0,0,0,0,0,0,0);
  30. /* add application specific code here */
  31. }
#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,这个由于不同的编译器而不同。解决这个问题,有两个办法:

(1).入口函数所在的文件,不要用cpp文件,全部改用c文件。

(2).cpp文件中的入口函数包含在external "C" {}中。

上一篇:深度学习(九) 深度学习最全优化方法总结比较(SGD,Momentum,Nesterov Momentum,Adagrad,Adadelta,RMSprop,Adam)


下一篇:前端javascript 实现到出excel 支持分页