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

简介: <p>现在我们的工作中,应用程序一般都是和BSP联编,然后将vxworks_rom.bin烧到班子里。在BSP启动后,调用应用程序的函数的。</p><p> </p><p>但是这样有个问题,就是应用程序和BSP结合的太紧密了。BSP开发者得将BSP代码给应用程序开发者,或者应用程序开发者得将应用程序编译后的.a文件给BSP开发者,才能完成程序的升级!</p><p> </p><p>那么下面

现在我们的工作中,应用程序一般都是和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.    
  6. extern SYMTAB_ID sysSymTbl;  
  7. void usrAppInit (void)  
  8.     {  
  9. #ifdef USER_APPL_INIT   
  10.  USER_APPL_INIT;  /* for backwards compatibility */  
  11. #endif   
  12.  FUNCPTR taskEntry=NULL;  
  13.  SYM_TYPE *pType;  
  14.  intfd=open("/tffs0/appProj.out",O_RDONLY,0);  
  15.  if(fd==NULL)  
  16.  {  
  17.  printf("/nopen project fail../n");  
  18.  return;  
  19.  }  
  20.  if(loadModule(fd,LOAD_ALL_SYMBOLS)==ERROR)  
  21.  {  
  22.  printf("/nload module fail.../n");  
  23.  return;  
  24.  }  
  25.  if(symFindByName(sysSymTbl,"appEntry",(char* *)&taskEntry,pType)==ERROR)  
  26.  {  
  27.  printf("/nfind symbol fail.../n");  
  28.  return;  
  29.  }  
  30.       taskSpawn("entry",100,0,1024,taskEntry,0,0,0,0,0,0,0,0,0,0);  
  31.    
  32.    /* add application specific code here */  
  33.  }  
  34.    
#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" {}中。

相关文章
关于 qml程序在目标机上开发时运行出现不断闪屏现象的 解决方法
关于 qml程序在目标机上开发时运行出现不断闪屏现象的 解决方法
关于 qml程序在目标机上开发时运行出现不断闪屏现象的 解决方法
|
1月前
|
监控 安全 API
7.3 Windows驱动开发:内核监视LoadImage映像回调
在笔者上一篇文章`《内核注册并监控对象回调》`介绍了如何运用`ObRegisterCallbacks`注册`进程与线程`回调,并通过该回调实现了`拦截`指定进行运行的效果,本章`LyShark`将带大家继续探索一个新的回调注册函数,`PsSetLoadImageNotifyRoutine`常用于注册`LoadImage`映像监视,当有模块被系统加载时则可以第一时间获取到加载模块信息,需要注意的是该回调函数内无法进行拦截,如需要拦截则需写入返回指令这部分内容将在下一章进行讲解,本章将主要实现对模块的监视功能。
39 0
7.3 Windows驱动开发:内核监视LoadImage映像回调
|
5月前
|
网络协议 安全 API
9.9 Windows驱动开发:内核远程线程实现DLL注入
在笔者上一篇文章`《内核RIP劫持实现DLL注入》`介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过`NtCreateThreadEx`这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,`NtCreateThreadEx`函数最终会调用`ZwCreateThread`,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。
81 0
9.9 Windows驱动开发:内核远程线程实现DLL注入
|
6月前
|
存储 安全 调度
4.2 Windows驱动开发:内核中进程线程与模块
内核进程线程和模块是操作系统内核中非常重要的概念。它们是操作系统的核心部分,用于管理系统资源和处理系统请求。在驱动安全开发中,理解内核进程线程和模块的概念对于编写安全的内核驱动程序至关重要。内核进程是在操作系统内核中运行的程序。每个进程都有一个唯一的进程标识符(PID),它用于在系统中唯一地标识该进程。在内核中,进程被表示为一个进程控制块(PCB),它包含有关进程的信息,如进程状态、优先级、内存使用情况等。枚举进程可以让我们获取当前系统中所有正在运行的进程的PID和其他有用的信息,以便我们可以监视和管理系统中的进程。
74 0
4.2 Windows驱动开发:内核中进程线程与模块
|
10月前
|
Linux
编译进内核的驱动是如何工作的
编译进内核的驱动是如何工作的
72 0
编译进内核的驱动是如何工作的
|
11月前
|
网络协议 安全 API
驱动开发:内核远程线程实现DLL注入
在笔者上一篇文章`《内核RIP劫持实现DLL注入》`介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过`NtCreateThreadEx`这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,`NtCreateThreadEx`函数最终会调用`ZwCreateThread`,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。
4900 0
|
11月前
|
API 索引 Windows
【滴水逆向P77】加载进程(PE查看器)应用程序源码解析(下)
【滴水逆向P77】加载进程(PE查看器)应用程序源码解析
|
11月前
|
存储 数据可视化 BI
【滴水逆向P77】加载进程(PE查看器)应用程序源码解析(上)
【滴水逆向P77】加载进程(PE查看器)应用程序源码解析
WinCE系统启动时自动运行应用程序之二
Windows CE 4.2平台下创建工程SMDK2440(目录为C:/WINCE420/PUBLIC/SMDK2440)且Build(或者Rebuild)成功;假定需要自动运行的的应用程序为CEDEMO.exe
|
监控
驱动开发:内核监视LoadImage映像回调
在笔者上一篇文章`《驱动开发:内核注册并监控对象回调》`介绍了如何运用`ObRegisterCallbacks`注册`进程与线程`回调,并通过该回调实现了`拦截`指定进行运行的效果,本章`LyShark`将带大家继续探索一个新的回调注册函数,`PsSetLoadImageNotifyRoutine`常用于注册`LoadImage`映像监视,当有模块被系统加载时则可以第一时间获取到加载模块信息,需要注意的是该回调函数内无法进行拦截,如需要拦截则需写入返回指令这部分内容将在下一章进行讲解,本章将主要实现对模块的监视功能。
312 0
驱动开发:内核监视LoadImage映像回调