一直以来都是使用串口进行调试,非常方便,最近将命令工具进行了重新,将支持的命令与通信接口,处理等进行了分离,可移植性更强,并且不依赖通信接口,可以使用串口,网口,433等等通信接口,只需要实现一个printf类似的函数即可,因为串口是字符流,不像其它通信接口,一次传输一个块,因此在使用非串口的时候,建议发送的时候将数据用sprntf缓存到一个buff中,一次传输。
//sys_cmd.c
/************************************************************************************************************* * 文件名: sys_cmd.c * 功能: 自定义的系统命令接口 * 作者: [email protected] * 创建时间: 2014-06-07 * 最后修改时间: 2018-01-14 * 详细: 分离底层,将命令缓冲区与接口句柄进行分离,并且命令可以自行控制添加,增加命令是否显示状态 *************************************************************************************************************/ #include "SYSTEM.H" #include "sys_cmd.h" #include "string.h" //命令缓冲区是否初始化ID #define SYS_CMD_BUFF_INIT_ID 0x86877F9D //管理密码状态 #define PASSWORD_STR "123456" static u32 sg_PASSWORD_HASH=0; u32 BKDRHash(const char *str); //BKDR 哈希算法 void SYS_CMD_Help(SYS_CMD_HANDLE *pHandle, char *pStr); //帮助命令 void SYS_CMD_Exit(SYS_CMD_HANDLE *pHandle, char *pStr); //退出命令 //支持的命令定义 const SYS_CMD_TYPE CMD_GET_HELP = {"?", SYS_CMD_Help, "\t\t帮助", TRUE}; //帮助 const SYS_CMD_TYPE CMD_EXIT = {"EXIT", SYS_CMD_Exit, "\t\t退出,再次输入需要密码", TRUE}; //退出登录 /************************************************************************************************************************* *函数 : void SYS_CMD_Init(SYS_CMD_BUFF_TYPE *pCmdBuff) *功能 : 初始化系统命令(会初始化系统命令缓冲区,并添加帮助命令) *参数 : pCmdBuff:系统命令缓冲区 *返回 : 无 *依赖 : 无 *作者 : [email protected] *时间 : 2018-01-14 *最后修改时间 : 2018-01-14 *说明 : *************************************************************************************************************************/ void SYS_CMD_Init(SYS_CMD_BUFF_TYPE *pCmdBuff) { if(sg_PASSWORD_HASH == 0) sg_PASSWORD_HASH = BKDRHash(PASSWORD_STR); //初始化密码的哈希值 pCmdBuff->CmdCount = 0; //清空命令 pCmdBuff->InitId = 0; //初始化为无效状态 SYS_CMD_Add(pCmdBuff, &CMD_GET_HELP); //添加帮助命令 SYS_CMD_Add(pCmdBuff, &CMD_EXIT); //添加退出命令 } /************************************************************************************************************************* *函数 : bool SYS_CMD_Add(SYS_CMD_BUFF_TYPE *pCmdBuff, const SYS_CMD_TYPE *pCmd) *功能 : 添加一个命令到命令缓冲区中 *参数 : pCmdBuff:当前使用的命令缓冲区指针;pCmd:当前要添加的命令 *返回 : TRUE:添加成功;FALSE:添加失败 *依赖 : 无 *作者 : [email protected] *时间 : 2018-01-14 *最后修改时间 : 2018-01-14 *说明 : 用于添加并初始化命令缓冲区 *************************************************************************************************************************/ bool SYS_CMD_Add(SYS_CMD_BUFF_TYPE *pCmdBuff, const SYS_CMD_TYPE *pCmd) { if(pCmdBuff->InitId != SYS_CMD_BUFF_INIT_ID) //没有被初始化过 { pCmdBuff->CmdCount = 0; //命令数量清零 pCmdBuff->InitId = SYS_CMD_BUFF_INIT_ID; //初始化ID有效 } if(pCmdBuff->CmdCount >= SYS_MAX_CMD_COUNT) return FALSE; //命令已经满了,无法添加了 pCmdBuff->CmdPointerBuff[pCmdBuff->CmdCount] = pCmd; //添加命令到命令缓冲区中 pCmdBuff->CmdBKDHashBuff[pCmdBuff->CmdCount] = BKDRHash(pCmd->pCmdStr); //计算当前命令的哈希值 pCmdBuff->CmdCount ++; //命令数量增加 return TRUE; } /************************************************************************************************************************* *函数 : void SYS_CMD_InterfaceInit(SYS_CMD_HANDLE *pHandle, int (*DataPrintf)(const char * format, ...)) *功能 : 初始化通讯句柄 *参数 : pHandle:句柄;DataPrintf:字符串打印接口 *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 2018-01-14 *最后修改时间 : 2018-01-14 *说明 : 用于初始化底层通讯接口 *************************************************************************************************************************/ void SYS_CMD_InterfaceInit(SYS_CMD_HANDLE *pHandle, int (*DataPrintf)(const char * format, ...)) { pHandle->pCmdBuff = NULL; //初始化命令缓冲区为无效状态 pHandle->DataPrintf = DataPrintf; //初始化通讯接口 pHandle->isInputPassword = FALSE; //密码输入状态无效 } /************************************************************************************************************************* *函数 : void SYS_CMD_Help(SYS_CMD_HANDLE *pHandle,char *pStr) *功能 : 帮助命令 *参数 : pHandle:句柄;pStr:当前输入的命令字符串 *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 2018-01-14 *最后修改时间 : 2018-01-14 *说明 : 用于初始化底层通讯接口 *************************************************************************************************************************/ void SYS_CMD_Help(SYS_CMD_HANDLE *pHandle,char *pStr) { u16 i; u16 cnt = 0; if(pHandle->pCmdBuff == NULL) return; pHandle->DataPrintf("\r\n\r\n=============================命令列表=============================\r\n"); pHandle->DataPrintf("[编号]\t[命令]\t\t\t[功能]\r\n\r\n"); for(i = 0;i < ((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdCount;i ++) { if(((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdPointerBuff[i]->isShow == TRUE) //需要显示才进行打印 { cnt ++; pHandle->DataPrintf(" %02d\t%s\t%s\r\n",cnt,((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdPointerBuff[i]->pCmdStr,((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdPointerBuff[i]->pFunExp); } } pHandle->DataPrintf("===================================================================\r\n"); pHandle->DataPrintf("\r\n"); } /************************************************************************************************************************* *函数 : void SYS_CMD_Exit(SYS_CMD_HANDLE *pHandle,char *pStr) *功能 : 退出命令 *参数 : pHandle:句柄;pStr:当前输入的命令字符串 *返回 : 无 *依赖 : 底层 *作者 : [email protected] *时间 : 2018-01-14 *最后修改时间 : 2018-01-14 *说明 : 用于退出命令,退出后下次必须输入密码才能使用 *************************************************************************************************************************/ void SYS_CMD_Exit(SYS_CMD_HANDLE *pHandle,char *pStr) { pHandle->isInputPassword = FALSE; //输入密码无效 pHandle->DataPrintf("[退出登录成功]:下次需要输入密码才能操作!\r\n"); } /************************************************************************************************************************* *函数 : bool SYS_CMD_Handle(SYS_CMD_HANDLE *pHandle, SYS_CMD_BUFF_TYPE *pCmdBuff, char *pStr) *功能 : 系统命令处理 *参数 : pHandle:句柄;pCmdBuff:当前所使用的命令缓冲区;pStr:当前输入的命令字符串 *返回 : TRUE:命令有效;FALSE:无效的命令 *依赖 : 底层 *作者 : [email protected] *时间 : 2018-01-14 *最后修改时间 : 2018-01-14 *说明 : 用于核心的命令处理函数 *************************************************************************************************************************/ bool SYS_CMD_Handle(SYS_CMD_HANDLE *pHandle, SYS_CMD_BUFF_TYPE *pCmdBuff, char *pStr) { u8 len; u8 i; u32 CmdHash; char *p; if(pHandle == NULL || pCmdBuff == NULL || pStr == NULL) return FALSE; pHandle->pCmdBuff = pCmdBuff; //记录当前的命令缓冲区指针 len = strlen(pStr); //检测是否输入过密码 if(pHandle->isInputPassword==FALSE) //没有输入过密码 { for(i = 0;i < len;i ++) { if((pStr[i]>='a') && (pStr[i]<='z')) //小写转换为大写 { pStr[i] -= 32; //变为大写字母 } if((pStr[i] == '\r')||(pStr[i] == '\n')) { pStr[i] = 0; break; } } CmdHash = BKDRHash(pStr); //计算命令的哈希值 if(CmdHash == sg_PASSWORD_HASH) { pHandle->isInputPassword = TRUE; //密码输入成功 pHandle->DataPrintf("[密码正确]:可以继续操作!\r\n>"); return TRUE; } pHandle->DataPrintf("[密码错误]:请输入管理密码!\r\n>"); return FALSE; } pHandle->DataPrintf("%s\r\n", pStr); if(len > 200) //检测参数的长度 { pHandle->DataPrintf("[错误]:命令超出长度(>(%d))!\r\n>",200); return FALSE; } //检查命令的结束符-\r\n for(i = 0;i < len;i ++) { if((pStr[i] == '\r')||((pStr[i] == '\n'))) { pStr[i] = 0; len = i; if(len == 0) { pHandle->DataPrintf("\r\n>"); return FALSE; } break; } } //检测是否含有非法字符 for(i = 0;i < len;i ++) { if((pStr[i] < 32) || (pStr[i] > 126)) { pHandle->DataPrintf("[错误]:含有非法字符!\r\n>"); return FALSE; } if((pStr[i]>='a') && (pStr[i]<='z')) //小写转换为大写 { pStr[i] -= 32; //变为大写字母 } } p = strstr(pStr,"="); //搜索等于 if(p!=NULL) { p ++; //跳过== len = strlen(p); //获取命令的参数长度 if(len > CMD_PARAMETER_STR_LEN) //检测参数的长度 { pHandle->DataPrintf("[错误]:命令参数超出长度(>(%d))!\r\n>",CMD_PARAMETER_STR_LEN); return FALSE; } strcpy(pHandle->CmdPara,p); //复制参数 p[0] = '\0'; //截断命令 } else { pHandle->CmdPara[0] = 0; //命令没有参数 } CmdHash = BKDRHash(pStr); //计算命令的哈希值 //uart_printf("[调试]:%s(0x%X)\r\n",pStr, CmdHash); //循环查找命令 for(i = 0;i < ((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdCount;i ++) { if(CmdHash == ((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdBKDHashBuff[i]) //判断哈希值是否一样 { //cmd_printf("[解析成功]:!\r\n>"); ((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdPointerBuff[i]->CmdExe(pHandle, pHandle->CmdPara); //执行命令 break; } } if(i == ((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdCount) { pHandle->DataPrintf("[错误]:不支持的命令!\r\n>"); return FALSE; } pHandle->DataPrintf(">"); return TRUE; } /************************************************************************************************************************* *函数 : u32 SYS_CMD_StringToDec(char *pStr, u8 NumDigits) *功能 : 将10进制样式字符串转换为整型数(必须保证完全为数字字符) *参数 : pStr:字符串起始指针 * NumDigits:数字位数,10进制数字位数 *返回 : 转换后的数字 *依赖 : 无 *作者 : [email protected] *时间 : 2013-04-30 *最后修改时间 : 2018-01-14 *说明 : 比如字符串"1865"转换后为1865,位数为4位 必须保证完全为数字字符 *************************************************************************************************************************/ u32 SYS_CMD_StringToDec(char *pStr, u8 NumDigits) { u32 temp; u32 DEC = 0; u8 i; u8 j; NumDigits = (NumDigits > 10) ? 10 : NumDigits; //最大支持10位10进制数 for(i = 0;i < NumDigits;i ++) { temp = pStr[i] - '0'; if(temp > 9) //只能是数字范围 return 0; for(j = 1;j < (NumDigits - i);j ++) { temp *= 10; } DEC += temp; } return DEC; } // BKDR Hash Function //BKDR 哈希算法 u32 BKDRHash(const char *str) { u32 seed = 131; // 31 131 1313 13131 131313 etc.. u32 hash = 0; while (*str) { hash = hash * seed + (*str++); } //return (hash & 0x7FFFFFFF); return hash; } //测试数据是否全部为数字以及空格 bool isStrNumAndSpc(char *pStr, u8 len,u8 SpcNum) { u8 i; u8 n = 0; for(i = 0;i < len;i ++) { if((pStr[i] < '0')||(pStr[i] > '9')) { if(pStr[i] == ' ') { n ++; if(n > SpcNum) return FALSE; //空格过多 } else return FALSE; } } return TRUE; } //测试数据是否全部为数字 bool isStrNum(char *pStr, u8 len) { u8 i; for(i = 0;i < len;i ++) { if((pStr[i] < '0')||(pStr[i] > '9')) { return FALSE; } } return TRUE; } //测试数据是否全部为字母,数字,'.' bool isStrAndNum(char *pStr, u8 len) { u8 i; for(i = 0;i < len;i ++) { if(((pStr[i] >= '0')&&(pStr[i] <= '9'))||((pStr[i] >= 'A')&&(pStr[i] <= 'Z'))||((pStr[i] >= 'a')&&(pStr[i] <= 'z'))||(pStr[i] == '.')) { } else { return FALSE; } } return TRUE; }
/************************************************************************************************************* * 文件名: sys_cmd.h * 功能: 自定义的系统命令接口 * 作者: [email protected] * 创建时间: 2014-06-07 * 最后修改时间: 2018-01-14 * 详细: 分离底层,将命令缓冲区与接口句柄进行分离,并且命令可以自行控制添加,增加命令是否显示状态 *************************************************************************************************************/ #ifndef __SYS_CMD_H_ #define __SYS_CMD_H_ #include "system.h" #define CMD_PARAMETER_STR_LEN 24 //限制命令的参数长度,过长会占用过多的内存,请按照实际设置 #define CMD_DEFAULT_COUNT 10 //默认的支持的命令数量,实际数量由SYS_CMD_COUNT决定 #ifndef SYS_CMD_COUNT //系统文件中定义了数量 #define SYS_MAX_CMD_COUNT SYS_CMD_COUNT //最大支持的命令数量 #else #define SYS_MAX_CMD_COUNT CMD_DEFAULT_COUNT //最大支持的命令数量 #endif //SYS_CMD_COUNT //通信句柄 typedef struct { int (*DataPrintf)(const char * format, ...); //数据打印接口-尽可能将数据集中到一起进行打印输出 void *pCmdBuff; //当前使用的命令缓冲区指针-由于互相包含,因此这个地方将指针声明为空指针 char CmdPara[CMD_PARAMETER_STR_LEN+4]; //命令参数缓冲区 bool isInputPassword; //用于指示是否输入密码 }SYS_CMD_HANDLE; //系统命令结构 typedef struct { const char *pCmdStr; //命令字符串 void(*CmdExe)(SYS_CMD_HANDLE *pHandle, char *); //命令执行函数 const char *pFunExp; //功能说明 bool isShow; //是否显示(可以影藏一些特殊命令) }SYS_CMD_TYPE; //系统命令集合定义 typedef struct { u32 InitId; //用于指示是否进行了初始化 const SYS_CMD_TYPE *CmdPointerBuff[SYS_MAX_CMD_COUNT]; //系统命令指针集合 u32 CmdBKDHashBuff[SYS_MAX_CMD_COUNT]; //系统命令的哈希值 u8 CmdCount; //当前支持的系统命令数量 }SYS_CMD_BUFF_TYPE; //相关命令接口 void SYS_CMD_Init(SYS_CMD_BUFF_TYPE *pCmdBuff); //初始化系统命令(会初始化系统命令缓冲区,并添加帮助命令) bool SYS_CMD_Add(SYS_CMD_BUFF_TYPE *pCmdBuff, const SYS_CMD_TYPE *pCmd);//添加一个命令到命令缓冲区中 void SYS_CMD_InterfaceInit(SYS_CMD_HANDLE *pHandle, int (*DataPrintf)(const char * format, ...)); //初始化通讯句柄 bool SYS_CMD_Handle(SYS_CMD_HANDLE *pHandle, SYS_CMD_BUFF_TYPE *pCmdBuff, char *pStr); //系统命令处理 //工具命令接口 u32 SYS_CMD_StringToDec(char *pStr, u8 NumDigits); //字符串转换为整形数 bool isStrNumAndSpc(char *pStr, u8 len,u8 SpcNum); //测试数据是否全部为数字以及空格 bool isStrAndNum(char *pStr, u8 len); //测试数据是否全部为字母,数字,'.' bool isStrNum(char *pStr, u8 len); //测试数据是否全部为数字 #endif //__SYS_CMD_H_
//命令的实现,以RTC为例
//使能系统命令行 #if SYS_CMD_EN_ #include "sys_cmd.h" #include "string.h" const SYS_CMD_TYPE CMD_GET_TIME = {"TIME?", CMD_GetTime, "\t\t获取系统时间", TRUE}; const SYS_CMD_TYPE CMD_GET_DATE = {"DATE?", CMD_GetDate, "\t\t获取系统日期", TRUE}; const SYS_CMD_TYPE CMD_SET_TIME = {"TIME=", CMD_SetTime, "\t\t设置系统时间 如(12:32:54):TIME=12 32 54", TRUE}; const SYS_CMD_TYPE CMD_SET_DATE = {"DATE=", CMD_SetDate, "\t\t设置系统日期 如(2014 6 8):TIME=2014 6 8", TRUE}; //获取时间 void CMD_GetTime(SYS_CMD_HANDLE *pHandle,char *pStr) { RTC_Get(); //更新时间 pHandle->DataPrintf("[获取时间成功]:%02d:%02d:%02d\r\n",g_timer.hour, g_timer.min, g_timer.sec); } //获取日期 void CMD_GetDate(SYS_CMD_HANDLE *pHandle,char *pStr) { RTC_Get(); //更新时间 pHandle->DataPrintf("[获取日期成功]:%04d-%02d-%02d\r\n",g_timer.year, g_timer.month, g_timer.date); } //设置时间 void CMD_SetTime(SYS_CMD_HANDLE *pHandle,char *pStr) { u8 hour,min,sec; u8 len; char *p; u8 num; len = strlen(pStr); //获取长度 if(isStrNumAndSpc(pStr, len, 2) == FALSE) { pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!\r\n"); return; } //小时 p = strstr(pStr," "); //搜索空格 if(p == NULL) { pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!\r\n"); return; } num = p - pStr; if((num > 2) || (num == 0)) { pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!\r\n"); return; } hour = SYS_CMD_StringToDec(pStr, num); if(hour>23) { pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!\r\n"); return; } //分钟 pStr = p+1; p = strstr(pStr," "); //搜索空格 if(p == NULL) { pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!\r\n"); return; } num = p - pStr; if((num > 2) || (num == 0)) { pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!\r\n"); return; } min = SYS_CMD_StringToDec(pStr, num); if(min>59) { pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!\r\n"); return; } //秒钟 pStr = p+1; num = strlen(pStr); if((num > 2) || (num == 0)) { pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!\r\n"); return; } sec = SYS_CMD_StringToDec(pStr, num); if(sec>59) { pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!\r\n"); return; } if(RTC_SetTime(hour, min, sec) == FALSE) { RTC_Get(); //更新时间 pHandle->DataPrintf("[时间设置失败]:%02d:%02d:%02d\r\n",g_timer.hour, g_timer.min, g_timer.sec); } else { RTC_Get(); //更新时间 pHandle->DataPrintf("[时间设置成功]:%02d:%02d:%02d\r\n",g_timer.hour, g_timer.min, g_timer.sec); } } //设置日期 void CMD_SetDate(SYS_CMD_HANDLE *pHandle,char *pStr) { u16 year; u8 month, date; u8 len; char *p; u8 num; len = strlen(pStr); //获取长度 if(isStrNumAndSpc(pStr, len, 2) == FALSE) { pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!\r\n"); return; } //年 p = strstr(pStr," "); //搜索空格 if(p == NULL) { pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!\r\n"); return; } num = p - pStr; if((num > 4) || (num == 0)) { pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!\r\n"); return; } year = SYS_CMD_StringToDec(pStr, num); if(year>9999) { pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!\r\n"); return; } //月 pStr = p+1; p = strstr(pStr," "); //搜索空格 if(p == NULL) { pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!\r\n"); return; } num = p - pStr; if((num > 2) || (num == 0)) { pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!\r\n"); return; } month = SYS_CMD_StringToDec(pStr, num); if(month>12) { pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!\r\n"); return; } //日 pStr = p+1; num = strlen(pStr); if((num > 2) || (num == 0)) { pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!\r\n"); return; } date = SYS_CMD_StringToDec(pStr, num); if(date>31) { pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!\r\n"); return; } if(RTC_SetDate(year, month, date) == FALSE) { RTC_Get(); //更新时间 pHandle->DataPrintf("[日期设置失败]:%04d-%02d-%02d\r\n",g_timer.year, g_timer.month, g_timer.date); } else { RTC_Get(); //更新时间 pHandle->DataPrintf("[日期设置成功]:%04d-%02d-%02d\r\n",g_timer.year, g_timer.month, g_timer.date); } } #endif //SYS_CMD_EN_//命令的声明
//使能系统命令行 #if SYS_CMD_EN_ #include "sys_cmd.h" #include "string.h" extern const SYS_CMD_TYPE CMD_GET_TIME; extern const SYS_CMD_TYPE CMD_GET_DATE; extern const SYS_CMD_TYPE CMD_SET_TIME; extern const SYS_CMD_TYPE CMD_SET_DATE; //获取时间 void CMD_GetTime(SYS_CMD_HANDLE *pHandle,char *pStr); //获取日期 void CMD_GetDate(SYS_CMD_HANDLE *pHandle,char *pStr); //设置时间 void CMD_SetTime(SYS_CMD_HANDLE *pHandle,char *pStr); //设置日期 void CMD_SetDate(SYS_CMD_HANDLE *pHandle,char *pStr); #endif //SYS_CMD_EN_
//需要实现的一个通信接口,我直接使用了printf,如果需要使用其它接口,需要自己实现一个 int DataPrintf(const char * format, ...) 函数,结构与printf一样,可以网上找找-下面是一个例子
//调试信息输出-注意单次长度不要超过5K int Printf(const char * format, ...) { DWORD len; va_list ap; va_start(ap, format); len = vsnprintf(buff, format, ap); va_end(ap); SendData((BYTE *)buff, len); return len; }//命令的初始化与添加命令
//初始化系统命令
SYS_CMD_HANDLE g_SysCmdHandle; //系统命令句柄 SYS_CMD_BUFF_TYPE g_SysCmdBuff; //系统命令缓冲区
SYS_CMD_Init(&g_SysCmdBuff);//初始化系统命令(会初始化系统命令缓冲区,并添加帮助命令) SYS_CMD_InterfaceInit(&g_SysCmdHandle, printf);//初始化通讯句柄 //添加RTC相关的命令支持 SYS_CMD_Add(&g_SysCmdBuff, &CMD_GET_TIME); SYS_CMD_Add(&g_SysCmdBuff, &CMD_GET_DATE); SYS_CMD_Add(&g_SysCmdBuff, &CMD_SET_TIME); SYS_CMD_Add(&g_SysCmdBuff, &CMD_SET_DATE);
//命令的处理,收到数据后调用SYS_CMD_Handle
cnt1 = UARTx_GetRxCnt(UART_PRINTF_CH); OSTimeDlyHMSM(0,0,0,20); cnt2 = UARTx_GetRxCnt(UART_PRINTF_CH); if((cnt1 > 0) && (cnt1 == cnt2)) { buff[cnt1] = 0; SYS_CMD_Handle(&g_SysCmdHandle, &g_SysCmdBuff, (char *)buff); //命令处理 UARTx_ClearRxCnt(UART_PRINTF_CH); } else { OSTimeDlyHMSM(0,0,0,100);; }