//从str中获取函数名,id,及参数信息 //*str:字符串指针. //返回值:0,识别成功;其他,错误代码. u8 usmart_cmd_rec(u8*str) { u8 sta,i,rval;//状态 u8 rpnum,spnum; u8 rfname[MAX_FNAME_LEN];//暂存空间,用于存放接收到的函数名 u8 sfname[MAX_FNAME_LEN];//存放本地函数名 sta=usmart_get_fname(str,rfname,&rpnum,&rval);//得到接收到的数据的函数名及参数个数 if(sta)return sta;//错误 for(i=0;i<usmart_dev.fnum;i++) { sta=usmart_get_fname((u8*)usmart_dev.funs[i].name,sfname,&spnum,&rval);//得到本地函数名及参数个数 if(sta)return sta;//本地解析有误 if(usmart_strcmp(sfname,rfname)==0)//相等 { if(spnum>rpnum)return USMART_PARMERR;//参数错误(输入参数比源函数参数少) usmart_dev.id=i;//记录函数ID. break;//跳出. } } if(i==usmart_dev.fnum)return USMART_NOFUNCFIND; //未找到匹配的函数 sta=usmart_get_fparam(str,&i); //得到函数参数个数 if(sta)return sta; //返回错误 usmart_dev.pnum=i; //参数个数记录 return USMART_OK; }
//处理系统指令 //0,成功处理;其他,错误代码; u8 usmart_sys_cmd_exe(u8 *str) { u8 i; u8 sfname[MAX_FNAME_LEN];//存放本地函数名 u8 pnum; u8 rval; u32 res; res=usmart_get_cmdname(str,sfname,&i,MAX_FNAME_LEN);//得到指令及指令长度 if(res)return USMART_FUNCERR;//错误的指令 str+=i; for(i=0;i<8;i++)//支持8个系统指令 { if(usmart_strcmp(sfname,sys_cmd_tab[i])==0)break; } switch(i) { case 0: case 1://帮助指令 printf("\r\n"); #if USMART_USE_HELP printf("------------------------USMART V2.8------------------------ \r\n"); printf(" USMART是由ALIENTEK开发的一个灵巧的串口调试互交组件,通过 \r\n"); printf("它,你可以通过串口助手调用程序里面的任何函数,并执行.因此,你可\r\n"); printf("以随意更改函数的输入参数(支持数字(10/16进制)、字符串、函数入\r\n"); printf("口地址等作为参数),单个函数最多支持10个输入参数,并支持函数返 \r\n"); printf("回值显示.新增参数显示进制设置功能,新增进制转换功能.\r\n"); printf("技术支持:www.openedv.com\r\n"); printf("USMART有6个系统命令:\r\n"); printf("?: 获取帮助信息\r\n"); printf("help: 获取帮助信息\r\n"); printf("list: 可用的函数列表\r\n\n"); printf("id: 可用函数的ID列表\r\n\n"); printf("hex: 参数16进制显示,后跟空格+数字即执行进制转换\r\n\n"); printf("dec: 参数10进制显示,后跟空格+数字即执行进制转换\r\n\n"); printf("请按照程序编写格式输入函数名及参数并以回车键结束.\r\n"); printf("--------------------------ALIENTEK------------------------- \r\n"); #else printf("指令失效\r\n"); #endif break; case 2://查询指令 printf("\r\n"); printf("-------------------------函数清单--------------------------- \r\n"); for(i=0;i<usmart_dev.fnum;i++)printf("%s\r\n",usmart_dev.funs[i].name); printf("\r\n"); break; case 3://查询ID printf("\r\n"); printf("-------------------------函数 ID --------------------------- \r\n"); for(i=0;i<usmart_dev.fnum;i++) { usmart_get_fname((u8*)usmart_dev.funs[i].name,sfname,&pnum,&rval);//得到本地函数名 printf("%s id is:\r\n0X%08X\r\n",sfname,usmart_dev.funs[i].func); //显示ID } printf("\r\n"); break; case 4://hex指令 printf("\r\n"); usmart_get_aparm(str,sfname,&i); if(i==0)//参数正常 { i=usmart_str2num(sfname,&res); //记录该参数 if(i==0) //进制转换功能 { printf("HEX:0X%X\r\n",res); //转为16进制 }else if(i!=4)return USMART_PARMERR;//参数错误. else //参数显示设定功能 { printf("16进制参数显示!\r\n"); usmart_dev.sptype=SP_TYPE_HEX; } }else return USMART_PARMERR; //参数错误. printf("\r\n"); break; case 5://dec指令 printf("\r\n"); usmart_get_aparm(str,sfname,&i); if(i==0)//参数正常 { i=usmart_str2num(sfname,&res); //记录该参数 if(i==0) //进制转换功能 { printf("DEC:%lu\r\n",res); //转为10进制 }else if(i!=4)return USMART_PARMERR;//参数错误. else //参数显示设定功能 { printf("10进制参数显示!\r\n"); usmart_dev.sptype=SP_TYPE_DEC; } }else return USMART_PARMERR; //参数错误. printf("\r\n"); break; case 6://read指令 printf("\r\n"); usmart_get_aparm(str,sfname,&i); if(i==0)//参数正常 { i=usmart_str2num(sfname,&res); //记录该参数 if(i==0) //读取指定地址数据功能 { if(usmart_dev.sptype==SP_TYPE_HEX)printf("*(0X%X)=0X%X\r\n",res,*(u32*)res); //读取指定地址的值 else printf("*(%d)=%d\r\n",res,*(u32*)res); //读取指定地址的值 }else return USMART_PARMERR; //未带参数,或者参数错误 }else return USMART_PARMERR; //参数错误. printf("\r\n"); break; default://非法指令 return USMART_FUNCERR; } return 0; }
//处理系统指令 //0,成功处理;其他,错误代码; u8 usmart_sys_cmd_exe(u8 *str) { u8 i; u8 sfname[MAX_FNAME_LEN];//存放本地函数名 u8 pnum; u8 rval; u32 res; res=usmart_get_cmdname(str,sfname,&i,MAX_FNAME_LEN);//得到指令及指令长度 if(res)return USMART_FUNCERR;//错误的指令 str+=i; for(i=0;i<sizeof(sys_cmd_tab)/4;i++)//支持的系统指令 { if(usmart_strcmp(sfname,sys_cmd_tab[i])==0)break; } switch(i) { case 0: case 1://帮助指令 printf("\r\n"); #if USMART_USE_HELP printf("------------------------USMART V3.2------------------------ \r\n"); printf(" USMART是由ALIENTEK开发的一个灵巧的串口调试互交组件,通过 \r\n"); printf("它,你可以通过串口助手调用程序里面的任何函数,并执行.因此,你可\r\n"); printf("以随意更改函数的输入参数(支持数字(10/16进制,支持负数)、字符串\r\n"), printf("、函数入口地址等作为参数),单个函数最多支持10个输入参数,并支持\r\n"), printf("函数返回值显示.支持参数显示进制设置功能,支持进制转换功能.\r\n"); printf("技术支持:www.openedv.com\r\n"); printf("USMART有7个系统命令(必须小写):\r\n"); printf("?: 获取帮助信息\r\n"); printf("help: 获取帮助信息\r\n"); printf("list: 可用的函数列表\r\n\n"); printf("id: 可用函数的ID列表\r\n\n"); printf("hex: 参数16进制显示,后跟空格+数字即执行进制转换\r\n\n"); printf("dec: 参数10进制显示,后跟空格+数字即执行进制转换\r\n\n"); printf("runtime:1,开启函数运行计时;0,关闭函数运行计时;\r\n\n"); printf("请按照程序编写格式输入函数名及参数并以回车键结束.\r\n"); printf("--------------------------ALIENTEK------------------------- \r\n"); #else printf("指令失效\r\n"); #endif break; case 2://查询指令 printf("\r\n"); printf("-------------------------函数清单--------------------------- \r\n"); for(i=0;i<usmart_dev.fnum;i++)printf("%s\r\n",usmart_dev.funs[i].name); printf("\r\n"); break; case 3://查询ID printf("\r\n"); printf("-------------------------函数 ID --------------------------- \r\n"); for(i=0;i<usmart_dev.fnum;i++) { usmart_get_fname((u8*)usmart_dev.funs[i].name,sfname,&pnum,&rval);//得到本地函数名 printf("%s id is:\r\n0X%08X\r\n",sfname,usmart_dev.funs[i].func); //显示ID } printf("\r\n"); break; case 4://hex指令 printf("\r\n"); usmart_get_aparm(str,sfname,&i); if(i==0)//参数正常 { i=usmart_str2num(sfname,&res); //记录该参数 if(i==0) //进制转换功能 { printf("HEX:0X%X\r\n",res); //转为16进制 }else if(i!=4)return USMART_PARMERR;//参数错误. else //参数显示设定功能 { printf("16进制参数显示!\r\n"); usmart_dev.sptype=SP_TYPE_HEX; } }else return USMART_PARMERR; //参数错误. printf("\r\n"); break; case 5://dec指令 printf("\r\n"); usmart_get_aparm(str,sfname,&i); if(i==0)//参数正常 { i=usmart_str2num(sfname,&res); //记录该参数 if(i==0) //进制转换功能 { printf("DEC:%lu\r\n",res); //转为10进制 }else if(i!=4)return USMART_PARMERR;//参数错误. else //参数显示设定功能 { printf("10进制参数显示!\r\n"); usmart_dev.sptype=SP_TYPE_DEC; } }else return USMART_PARMERR; //参数错误. printf("\r\n"); break; case 6://runtime指令,设置是否显示函数执行时间 printf("\r\n"); usmart_get_aparm(str,sfname,&i); if(i==0)//参数正常 { i=usmart_str2num(sfname,&res); //记录该参数 if(i==0) //读取指定地址数据功能 { if(USMART_ENTIMX_SCAN==0)printf("\r\nError! \r\nTo EN RunTime function,Please set USMART_ENTIMX_SCAN = 1 first!\r\n");//报错 else { usmart_dev.runtimeflag=res; if(usmart_dev.runtimeflag)printf("Run Time Calculation ON\r\n"); else printf("Run Time Calculation OFF\r\n"); } }else return USMART_PARMERR; //未带参数,或者参数错误 }else return USMART_PARMERR; //参数错误. printf("\r\n"); break; default://非法指令 return USMART_FUNCERR; } return 0; }
//从str中得到函数名 //*str:源字符串指针 //*fname:获取到的函数名字指针 //*pnum:函数的参数个数 //*rval:是否需要显示返回值(0,不需要;1,需要) //返回值:0,成功;其他,错误代码. u8 usmart_get_fname(u8*str,u8*fname,u8 *pnum,u8 *rval) { u8 res; u8 fover=0; //括号深度 u8 *strtemp; u8 offset=0; u8 parmnum=0; u8 temp=1; u8 fpname[6];//void+X+'/0' u8 fplcnt=0; //第一个参数的长度计数器 u8 pcnt=0; //参数计数器 u8 nchar; //判断函数是否有返回值 strtemp=str; while(*strtemp!='\0')//没有结束 { if(*strtemp!=' '&&(pcnt&0X7F)<5)//最多记录5个字符 { if(pcnt==0)pcnt|=0X80;//置位最高位,标记开始接收返回值类型 if(((pcnt&0x7f)==4)&&(*strtemp!='*'))break;//最后一个字符,必须是* fpname[pcnt&0x7f]=*strtemp;//记录函数的返回值类型 pcnt++; }else if(pcnt==0X85)break; strtemp++; } if(pcnt)//接收完了 { fpname[pcnt&0x7f]='\0';//加入结束符 if(usmart_strcmp(fpname,"void")==0)*rval=0;//不需要返回值 else *rval=1; //需要返回值 pcnt=0; } res=0; strtemp=str; while(*strtemp!='('&&*strtemp!='\0') //此代码找到函数名的真正起始位置 { strtemp++; res++; if(*strtemp==' '||*strtemp=='*') { nchar=usmart_search_nextc(strtemp); //获取下一个字符 if(nchar!='('&&nchar!='*')offset=res; //跳过空格和*号 } } strtemp=str; if(offset)strtemp+=offset+1;//跳到函数名开始的地方 res=0; nchar=0;//是否正在字符串里面的标志,0,不在字符串;1,在字符串; while(1) { if(*strtemp==0) { res=USMART_FUNCERR;//函数错误 break; }else if(*strtemp=='('&&nchar==0)fover++;//括号深度增加一级 else if(*strtemp==')'&&nchar==0) { if(fover)fover--; else res=USMART_FUNCERR;//错误结束,没收到'(' if(fover==0)break;//到末尾了,退出 }else if(*strtemp=='"')nchar=!nchar; if(fover==0)//函数名还没接收完 { if(*strtemp!=' ')//空格不属于函数名 { *fname=*strtemp;//得到函数名 fname++; } }else //已经接受完了函数名了. { if(*strtemp==',') { temp=1; //使能增加一个参数 pcnt++; }else if(*strtemp!=' '&&*strtemp!='(') { if(pcnt==0&&fplcnt<5) //当第一个参数来时,为了避免统计void类型的参数,必须做判断. { fpname[fplcnt]=*strtemp;//记录参数特征. fplcnt++; } temp++; //得到有效参数(非空格) } if(fover==1&&temp==2) { temp++; //防止重复增加 parmnum++; //参数增加一个 } } strtemp++; } if(parmnum==1)//只有1个参数. { fpname[fplcnt]='\0';//加入结束符 if(usmart_strcmp(fpname,"void")==0)parmnum=0;//参数为void,表示没有参数. } *pnum=parmnum; //记录参数个数 *fname='\0'; //加入结束符 return res; //返回执行结果 }