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