www.pudn.com > IEC104_codeamaterial.rar > cmddo.c, change:2011-02-19,size:11692b
/*------------------------------------------------------------------------ Module: cmddo.c Author: solar Project: pas300m Creation Date: 2005-9-29 Description: ------------------------------------------------------------------------*/ /*------------------------------------------------------------------------ $Log: $ ------------------------------------------------------------------------*/ #include "syscfg.h" #include <string.h> #include <stdarg.h> #include <stdio.h> #include "sys.h" #define SHELL_COMM_ID SHELL_ID #if ((TYPE_BACK&EXT_TYPE_DIO_MASK) == EXT_TYPE_DIO_DI) #define SHELL_NAME "DI>" #endif #if ((TYPE_BACK&EXT_TYPE_DIO_MASK) == EXT_TYPE_DIO_DO) #define SHELL_NAME "DO>" #endif #ifndef SHELL_NAME #define SHELL_NAME "IDA>" #endif enum { CMDLINESIZE = 48, ARGCNT = 8, PRINTF_BUF_LEN = 128 }; /*extern int gSerialInit;*/ /*用于判断串口初始化时候完成*/ /*------------------------------------------------------------------------ 变量定义 ------------------------------------------------------------------------*/ int g_DispNum = 0; static char uprint_buf[PRINTF_BUF_LEN]; /*static BYTE out_buf[PRINTF_BUF_LEN];*/ static int g_cur = 0; /*命令行当前指针*/ static char g_cmdline[CMDLINESIZE]; /*------------------------------------------------------------------------ 函数原型 ------------------------------------------------------------------------*/ /*静态函数*/ static void sendmacmsg(void); static int getline(char *buf,int max, int *cur); static int docommand(char *cmdline,int verbose); static int tokenize(char *,char **); static void getoptinit(void); static void execmd(void); /*------------------------------------------------------------------------ Procedure: ShellTask ID:1 Purpose: Shell任务 Input: Output: Errors: ------------------------------------------------------------------------*/ void shell(void) { DWORD events; evReceive(SHELL_ID, EV_RX_AVAIL | EV_TM1, &events); if (events&EV_RX_AVAIL) { if (g_DispNum > 0) { g_DispNum = 1; execmd(); } if (getline(g_cmdline,CMDLINESIZE,&g_cur) != 0) execmd(); } if (events&EV_TM1) { if (g_DispNum> 0) execmd(); /*if (TestRunFlag(RUNF_MAC_NOCFG)) sendmacmsg();*/ } } void ShellInit(void) { tmEvEvery(SHELL_ID, 50); tCreate(SHELL_ID, NULL, (ENTRYPTR)shell); } /*void sendmacmsg(void) { myputs("* NO Mac!\n"); faultLight_turn(); }*/ void execmd(void) { docommand(g_cmdline,0); if (g_DispNum == 0) { memset(g_cmdline,0,CMDLINESIZE); /*清命令行缓存*/ g_cur = 0; myprintf("%s",SHELL_NAME); } } /*------------------------------------------------------------------------ Procedure: myprintf ID:1 Purpose: Shell格式化输出 Input: Output: Errors: ------------------------------------------------------------------------*/ int myprintf( const char *fmt, ... ) { va_list varg; char *pbuf = uprint_buf; /*BYTE *pout = out_buf;*/ int i,retv; /*int add = 0;*/ va_start( varg, fmt ); retv = vsprintf(pbuf, fmt, varg); va_end( varg ); /*if( gSerialInit == 1){ for(i=0; i<retv; i++){ if(uprint_buf[i] == '\n'){ *pout = '\r'; pout++; add++; } *pout = uprint_buf[i]; pout++; if(uprint_buf[i] == '\0') break; } SerialWrite(SHELL_COMM_ID, out_buf, retv+add, 0); }else{*/ for(i=0; i<retv; i++) myputchar(*(char *)(uprint_buf+i)); /*}*/ return retv; } extern void uart_poll_out(int no, char outChar); /*------------------------------------------------------------------------ Procedure: myputchar ID:1 Purpose: 输出字符, '\n'前添加'\r' Input: Output: Errors: ------------------------------------------------------------------------*/ int myputchar(char c) { /*unsigned char buf[2];*/ /*if( gSerialInit == 1){ buf[0] = c; buf[1] = '\r'; if (c == '\n') { buf[0] = '\r'; buf[1] = c; SerialWrite(SHELL_COMM_ID, buf, 2, 0); }else{ buf[0] = c; SerialWrite(SHELL_COMM_ID, buf, 1, 0); } }else{*/ if (c == '\n') { uart_poll_out(SHELL_COMM_ID, '\r'); uart_poll_out(SHELL_COMM_ID, c); }else{ uart_poll_out(SHELL_COMM_ID, c); } /*}*/ return((int)c); } /*------------------------------------------------------------------------ Procedure: myputs ID:1 Purpose: 串输出 Input: Output: Errors: ------------------------------------------------------------------------*/ void myputs(char *str) { char *p = str; while (*p != '\0') { myputchar(*p); p++; } } /*------------------------------------------------------------------------ Procedure: gotoxy ID:1 Purpose: [VT100]调整shell光标位置 Input: Output: Errors: ------------------------------------------------------------------------*/ void gotoxy(unsigned char x, unsigned char y) { myputchar(0x1b); myputchar('['); myputchar((y%100)/10+0x30); myputchar((y%10)+0x30); myputchar(';'); myputchar((x%100)/10+0x30); myputchar((x%10)+0x30); myputchar('H'); } /*------------------------------------------------------------------------ Procedure: clrscr ID:1 Purpose: [VT100]shell清屏 Input: Output: Errors: ------------------------------------------------------------------------*/ void clrscr(void) { gotoxy(0,0); myputchar(0x1b); myputs("[J"); } /*------------------------------------------------------------------------ Procedure: vt100color ID:1 Purpose: [VT100]shell颜色控制 Input: Output: Errors: ------------------------------------------------------------------------*/ void vt100color(char *s) { myputchar(0x1b); myputchar('['); myputs(s); myputchar('m'); } /*------------------------------------------------------------------------ Procedure: mygetchar ID:1 Purpose: 从shell读取字符 Input: Output: Errors: ------------------------------------------------------------------------*/ int mygetchar(void) { int ret; BYTE ch; ret = commRead(SHELL_COMM_ID, &ch, 1, 0); if (ret != 1) return -1; return((int)ch); } /*------------------------------------------------------------------------ Procedure: getline ID:1 Purpose: 接收命令行 Input: Output: Errors: ------------------------------------------------------------------------*/ int getline(char *buf,int max, int *cur) { static unsigned char crlf; int tot, i; char *base; int ret; tot = 0; base = buf; buf = buf + (*cur); max -= 1; /* Make sure there is space for the null terminator. */ for(i=*cur;i<max;i++) { ret = mygetchar(); if(ret == -1) { /**cur = i;*/ return 0; } *buf = (char)ret; if (!*buf) { i--; continue; } { if ((*buf == '\r') || (*buf == '\n')) { if ((crlf) && (*buf != crlf)) { crlf = 0; continue; } myputs("\r\n"); crlf = *buf; *buf = 0; break; } if (*buf == '\b') { if (*cur) { i -= 2; buf--; *cur = *cur - 1; myputs("\b \b"); } /*if (tot) { i -= 2; buf--; tot--; myputs("\b \b"); }*/ } else { myputchar(*buf); tot++; *cur = *cur + 1; buf++; } crlf = 0; } } if (i == max) { myprintf("\007\n输入太长(超过%d字节).\n",max+1); *buf = 0; *cur = 0; return(0); } /*清空接收缓存*/ while( mygetchar() != -1 ); return 1; } /*------------------------------------------------------------------------ Procedure: docommand ID:1 Purpose: 命令执行. Input: Output: Errors: ------------------------------------------------------------------------*/ int docommand(char *cmdline,int verbose) { int ret, argc, i; struct monCommand *cmdptr; char *argv[ARGCNT], cmdcpy[CMDLINESIZE]; if (verbose == 2) /* print command line prior to processing */ myprintf("+ %s\n",cmdline); strcpy(cmdcpy,cmdline); /* Build argc/argv structure based on incoming command line. */ argc = tokenize(cmdcpy,argv); if (argc == 0) return 0; if (argc < 0) { myprintf("命令行错误\n"); return -1; } getoptinit(); cmdptr = (struct monCommand *)cmdlist; if (verbose) { /* print the tokenized command line. */ for(i=0;i<argc;i++) myprintf("%s ",argv[i]); myprintf("\n"); } while(cmdptr->name) { if (strcmp(argv[0],cmdptr->name) == 0) break; cmdptr++; } if (cmdptr->name) { ret = cmdptr->func(argc,argv); if (ret == -1) { myprintf("命令行错误...\n"); myprintf("用法: %s %s\n", cmdptr->name,cmdptr->helptxt[1]); } return ret; } myprintf("命令未发现: %s\n",argv[0]); return 0; } /*------------------------------------------------------------------------ Procedure: tokenize ID:1 Purpose: 命令行解析 Input: Output: Errors: ------------------------------------------------------------------------*/ int tokenize(char *string,char *argv[]) { int argc, done; /* Null out the incoming argv array. */ for(argc=0;argc<ARGCNT;argc++) argv[argc] = (char *)0; argc = 0; while(1) { while ((*string == ' ') || (*string == '\t')) string++; if (*string == 0) break; argv[argc] = string; while ((*string != ' ') && (*string != '\t')) { if ((*string == '\\') && (*(string+1) == '"')) { strcpy(string,string+1); } else if (*string == '"') { strcpy(string,string+1); while(*string != '"') { if ((*string == '\\') && (*(string+1) == '"')) strcpy(string,string+1); if (*string == 0) return(-1); string++; } strcpy(string,string+1); continue; } if (*string == 0) break; string++; } if (*string == 0) done = 1; else { done = 0; *string++ = 0; } argc++; if (done) break; if (argc >= ARGCNT) { argc = -1; break; } } return(argc); } /* Variables used by getopt: */ int optind; /* argv index to first cmd line arg that is not part of the option list */ char *optarg; /* pointer to argument associated with an option */ int sp; /*------------------------------------------------------------------------ Procedure: getoptinit ID:1 Purpose: 取得命令行选项初始化 Input: Output: Errors: ------------------------------------------------------------------------*/ void getoptinit(void) { sp = 1; optind = 1; } /*------------------------------------------------------------------------ Procedure: getopt ID:1 Purpose: 取得命令行选项 Input: Output: Errors: ------------------------------------------------------------------------*/ int getopt(int argc,char *argv[],char *opts) { register int c; register char *cp; if(sp == 1) { if (optind >= argc) return(-1); else if (argv[optind][0] != '-') return(-1); else if (argv[optind][1] == '\0') return(-1); else if(strcmp(argv[optind], "--") == 0) { optind++; return(-1); } } c = argv[optind][sp]; cp= strchr(opts, c); if(c == ':' || cp == 0) { myprintf("非法选项: %c\n",c); if(argv[optind][++sp] == '\0') { optind++; sp = 1; } return('?'); } if(*++cp == ':') { if(argv[optind][sp+1] != '\0') optarg = &argv[optind++][sp+1]; else if(++optind >= argc) { myprintf("选项需要参数: %c\n",c); sp = 1; return('?'); } else optarg = argv[optind++]; sp = 1; } else { if(argv[optind][++sp] == '\0') { sp = 1; optind++; } optarg = 0; } return(c); }