写了一个将VxWorks的shell打印输出到指定内存中的接口,可广泛用于CLI下的调试函数显示以及故障自动捕获等功能,稍作修改可以适合其它嵌入式OS

本代码在Tornado2.0的Simu下调试通过,原理上与CPU架构无关,应该都适用。
如果引用的话,请告诉我,或者评论一句[页面最下方],不要一声不吭


/* usrAppInit.c - stub application initialization routine */

/* Copyright 1984-1998 Wind River Systems, Inc. */

/*
modification history
--------------------
2004-9-29  ,Rex  deal with buffer alloc
2004-9-29  ,Rex  deal with task's err output
2004-9-25  ,Rex  shell_output_to_memory()
01a,02jun98,ms   written
*/

/*
DESCRIPTION
rex  shell_output_to_memory
*/

/*********************rex******************************/
/*libs*/
#include <taskLib.h>
#include <vxWorks.h>
#include <stdio.h>
#include <string.h>

#include "dosFsLib.h"
#include "ramDrv.h"
#include "usrLib.h"

/*Macros*/
#define DIAG_RAM_DISK_SIZE  (0x100000)  /* 1M */
#define DIAG_RAM_DISK_NAME  "/diag/"
#define DIAG_TEMP_PIPE_FILE DIAG_RAM_DISK_NAME"temp.pip"

/*struct&type*/
typedef struct Rex_taskSummary
{
    int tid;
}Rex_TASKSUMMARY;

/*Declarations*/
STATUS Diagnose_Init();
char* shell_output_to_memory(FUNCPTR , void* , char *, unsigned int );

char* cmd_exe_taskSummary(char *);
void Rex_taskSummary(Rex_TASKSUMMARY *);

/******************************************************************************
*
* usrAppInit - initialize the users application
*/

void usrAppInit (void)
    {
#ifdef USER_APPL_INIT
 USER_APPL_INIT;  /* for backwards compatibility */
#endif

    /* add application specific code here */
    Diagnose_Init();
    }
 

/* new implement employing shell_output_to_memory() routine */
void Rex_taskSummary(Rex_TASKSUMMARY *Rex_ts)
{
    i(Rex_ts->tid);
}

char* cmd_exe_taskSummary(char * taskNameString)
{
    Rex_TASKSUMMARY Rex_TS;
   
    if(NULL == taskNameString)
        Rex_TS.tid = 0;
    else
        Rex_TS.tid = (int)taskNameString;
   
    return shell_output_to_memory((FUNCPTR)Rex_taskSummary, &Rex_TS, NULL, 0);
}

char* cmd_exe_taskInfo(char * taskNameString)
{
    return NULL;
}


/*
 i | ti | tt | memShow | spyReport | etc.
*/
/*Exe Entry*/
void ExeRex(int cmdIndex, char* taskNameString)
{
    char* stString = NULL;
   
    switch(cmdIndex)
    {
        case 1: /* i */
            if((stString = cmd_exe_taskSummary(taskNameString)))
            {
                printf("%s", stString);
                free(stString);
            }
            else
            {
                printf("i Error\n");
            }
         break;
        case 2: /* ti */
            if((stString = cmd_exe_taskInfo(taskNameString)))
            {
                printf("%s", stString);
                free(stString);
            }
            else
            {
                printf("ti Error\n");
            }
         break;
        case 3: /* tt */
         break;        
        case 4: /* memShow */
         break;
        case 5: /* spyReport */
         break;
        case 0:
        default: 
            printf("help!\n");
         break;
    }
}

STATUS Diagnose_Init()
{
    BLK_DEV     *pBlkDev;
    char        *pDiagRamDiskBase = NULL;
   
    ramDrv();
    pDiagRamDiskBase = malloc(DIAG_RAM_DISK_SIZE);
    if(NULL == pDiagRamDiskBase)
        return ERROR;
    bzero(pDiagRamDiskBase,DIAG_RAM_DISK_SIZE);

    pBlkDev = ramDevCreate( pDiagRamDiskBase,              /* start address */
                            512,                                /* sector size */
                            64,                                 /* sectors per track */
                            (int)(DIAG_RAM_DISK_SIZE/512),       /* total sectors 64 MBytes */
                            0);                                 /* offset */
    if(NULL == pBlkDev)
    {
        free(pDiagRamDiskBase);
        return ERROR;
    }

    if(NULL == dosFsMkfs (DIAG_RAM_DISK_NAME, pBlkDev))
    {
        free(pDiagRamDiskBase);
        return ERROR;

    }

    return OK;
}
/*****************************************************************************
  函数名        : shell_output_to_memory
  功能描述      : 将VxWorks的shell打印输出到指定内存中,可用于CLI下的诊断命令显示以及故障自动捕获等功能
  调用函数列表  :   ioTaskStdGet()
                    ioTaskStdSet()
                    open()
                    close()
                    fopen()
                    fseek()
                    ftell()
                    fclose()
                    bzero()
                    remove()
  被函数调用    : CLI用户函数
  输入参数      : FUNCPTR shellRoutine,   在shell下打印输出的函数实体,它调用printf输出的内容将“打印”到指定内存里去
                  void* arg,              shellRoutine的参数,一般来说是一个结构指针,以包含更多信息,具体信息由shellRoutine解析
                  char *dest,             为NULL,则说明用户不知道输出的信息数据大小,需要本接口代为申请;不为NULL,即为指定地址
                  unsigned int destSize   当dest为NULL时无意义;当dest不为NULL时,为dest指向的内存的大小
  输出参数      : 无
  返回          : 指向具体输出信息的指针; NULL为失败
  特殊内存      : 需要事先创建RamDisk,参见Diagnose_Init()
  其他          :
==============================================================================
  修改记录:
  修改日期         版本         修改人      修改原因及内容
==============================================================================
  2004-9-25        1.0          REX            创建
******************************************************************************/
char* shell_output_to_memory(FUNCPTR shellRoutine, void* arg, char *dest, unsigned int destSize)
{
    int tempFileFd = ERROR;
    int OrigOutPutFd = ERROR;
    int OrigErrPutFd = ERROR; /*2004-9-29*/
    FILE *tempFile = NULL;
    long  fileSize = 0;
    char *contentBuf = NULL;

    /*1、参数检查*/
    if(NULL == shellRoutine)
    {
        return NULL;   
    }
    if(NULL == dest) /*用户未指定内存,则将destSize置为最大,以便之后统一取最小值*/
        destSize = ~0x0;
       
    /*2、重定向输出到临时文件*/
    OrigOutPutFd = ioTaskStdGet(0,1); /*保存原来的输出句柄*/
    OrigErrPutFd = ioTaskStdGet(0,2); /*保存原来的ERR句柄 2004-9-29*/

    if(ERROR == (tempFileFd = open(DIAG_TEMP_PIPE_FILE,O_CREAT | O_RDWR,0)))
    {
        printf("error open a temp file for diag\n");
        return NULL;
    }
    ioTaskStdSet(0,1,tempFileFd);
    ioTaskStdSet(0,2,tempFileFd); /*2004-9-29*/
    shellRoutine(arg); /*调用用户输出例程*/
    ioTaskStdSet(0,1,OrigOutPutFd);
    ioTaskStdSet(0,2,OrigErrPutFd); /*2004-9-29*/
    close(tempFileFd);
   
    /*3、打开临时文件,获取数据大小,并指定内存*/
    if(NULL == (tempFile = fopen(DIAG_TEMP_PIPE_FILE,"r")))
    {
        printf("error open the temp file for diag\n");
        remove(DIAG_TEMP_PIPE_FILE);
        return NULL;
    }
    fseek(tempFile, 0, SEEK_END);
    if(-1L == (fileSize = ftell(tempFile)))
    {
        printf("error pos the temp file for diag\n");
        fclose(tempFile);
        remove(DIAG_TEMP_PIPE_FILE);
        return NULL;
    }
    printf("fileSize1 = %ld\n",fileSize);
    fileSize = (fileSize >= destSize) ? destSize : fileSize; /*取两者的最小值,避免越界*/
    printf("fileSize2 = %ld\n",fileSize);
   
    if(NULL == dest) /*用户未指定内存,我们为之申请*/
    {    /*fileSize为零不处理,直接返回 2004-9-29*/
        if((0 == fileSize) || (NULL == (contentBuf = malloc(fileSize + 1))))
        {/*多申请一个字节作为字符串的结束符位置 2004-9-29*/
            printf("error alloc mem for diag\n");
            fclose(tempFile);
            remove(DIAG_TEMP_PIPE_FILE);
            return NULL;
        }
    }
    else /*使用用户指定的内存存放*/
    {
        contentBuf = dest;
    }/*内存的释放由用户完成*/
   
    /*4、读取文件内容到内存*/
    bzero(contentBuf, fileSize + 1); /*多清零一个字节作为字符串的结束符位置 2004-9-29*/
    fseek(tempFile, 0, SEEK_SET);
    fread(contentBuf, fileSize, 1, tempFile);
    /*printf("%s\n",contentBuf);*/
   
    /*5、清理*/
    fclose(tempFile);
    remove(DIAG_TEMP_PIPE_FILE);   
   
    return contentBuf;
}



你可能感兴趣的:(shell)