当前位置:首页 > 芯闻号 > 充电吧
[导读]一直以来都是使用串口进行调试,非常方便,最近将命令工具进行了重新,将支持的命令与通信接口,处理等进行了分离,可移植性更强,并且不依赖通信接口,可以使用串口,网口,433等等通信接口,只需要实现一个pr

一直以来都是使用串口进行调试,非常方便,最近将命令工具进行了重新,将支持的命令与通信接口,处理等进行了分离,可移植性更强,并且不依赖通信接口,可以使用串口,网口,433等等通信接口,只需要实现一个printf类似的函数即可,因为串口是字符流,不像其它通信接口,一次传输一个块,因此在使用非串口的时候,建议发送的时候将数据用sprntf缓存到一个buff中,一次传输。


//sys_cmd.c


/*************************************************************************************************************
 * 文件名:			sys_cmd.c
 * 功能:			自定义的系统命令接口
 * 作者:			cp1300@139.com
 * 创建时间:		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, "tt帮助", TRUE};						//帮助
const SYS_CMD_TYPE  CMD_EXIT			=	{"EXIT", SYS_CMD_Exit, "tt退出,再次输入需要密码", TRUE};	//退出登录
		

/*************************************************************************************************************************
*函数        	:	void SYS_CMD_Init(SYS_CMD_BUFF_TYPE *pCmdBuff)
*功能        	:	初始化系统命令(会初始化系统命令缓冲区,并添加帮助命令)
*参数        	:	pCmdBuff:系统命令缓冲区
*返回        	:	无
*依赖        	:	无
*作者        	:	cp1300@139.com
*时间        	:	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:添加失败
*依赖        	:	无
*作者        	:	cp1300@139.com
*时间        	:	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:字符串打印接口
*返回        	:	无
*依赖        	:	底层
*作者        	:	cp1300@139.com
*时间        	:	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:当前输入的命令字符串
*返回        	:	无
*依赖        	:	底层
*作者        	:	cp1300@139.com
*时间        	:	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("rnrn=============================命令列表=============================rn");
	pHandle->DataPrintf("[编号]t[命令]ttt[功能]rnrn");
	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("  %02dt%st%srn",cnt,((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdPointerBuff[i]->pCmdStr,((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdPointerBuff[i]->pFunExp);
		}
		
	}
	pHandle->DataPrintf("===================================================================rn");
	pHandle->DataPrintf("rn");
}

/*************************************************************************************************************************
*函数        	:	void SYS_CMD_Exit(SYS_CMD_HANDLE *pHandle,char *pStr)
*功能        	:	退出命令
*参数        	:	pHandle:句柄;pStr:当前输入的命令字符串
*返回        	:	无
*依赖        	:	底层
*作者        	:	cp1300@139.com
*时间        	:	2018-01-14
*最后修改时间	:	2018-01-14
*说明        	:	用于退出命令,退出后下次必须输入密码才能使用
*************************************************************************************************************************/
void SYS_CMD_Exit(SYS_CMD_HANDLE *pHandle,char *pStr)
{
	pHandle->isInputPassword = FALSE;	//输入密码无效
	pHandle->DataPrintf("[退出登录成功]:下次需要输入密码才能操作!rn");
}


/*************************************************************************************************************************
*函数        	:	bool SYS_CMD_Handle(SYS_CMD_HANDLE *pHandle, SYS_CMD_BUFF_TYPE *pCmdBuff, char *pStr)
*功能        	:	系统命令处理
*参数        	:	pHandle:句柄;pCmdBuff:当前所使用的命令缓冲区;pStr:当前输入的命令字符串
*返回        	:	TRUE:命令有效;FALSE:无效的命令
*依赖        	:	底层
*作者        	:	cp1300@139.com
*时间        	:	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]isInputPassword = TRUE;		//密码输入成功
			pHandle->DataPrintf("[密码正确]:可以继续操作!rn>");
			return TRUE;
		}
		pHandle->DataPrintf("[密码错误]:请输入管理密码!rn>");
		return FALSE;
	}
	
	pHandle->DataPrintf("%srn", pStr);
	if(len > 200)									//检测参数的长度
	{
		pHandle->DataPrintf("[错误]:命令超出长度(>(%d))!rn>",200);
		return FALSE;
	}
	//检查命令的结束符-rn
	for(i = 0;i < len;i ++)
	{
		if((pStr[i] == 'r')||((pStr[i] == 'n')))
		{
			pStr[i] = 0;
			len = i;
			if(len == 0)
			{
				pHandle->DataPrintf("rn>");
				return FALSE;
			}
			break;
		}
	}
	
	//检测是否含有非法字符
	for(i = 0;i < len;i ++)	
	{
		if((pStr[i] < 32) || (pStr[i] > 126))
		{
			pHandle->DataPrintf("[错误]:含有非法字符!rn>");
			return FALSE;
		}
		if((pStr[i]>='a') && (pStr[i] CMD_PARAMETER_STR_LEN)			//检测参数的长度
		{
			pHandle->DataPrintf("[错误]:命令参数超出长度(>(%d))!rn>",CMD_PARAMETER_STR_LEN);
			return FALSE;
		}
		strcpy(pHandle->CmdPara,p);				//复制参数
		p[0] = '';							//截断命令
	}
	else
	{
		pHandle->CmdPara[0] = 0;				//命令没有参数
	}
	
	CmdHash = BKDRHash(pStr);					//计算命令的哈希值
	//uart_printf("[调试]:%s(0x%X)rn",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("[解析成功]:!rn>");
			((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdPointerBuff[i]->CmdExe(pHandle, pHandle->CmdPara); //执行命令
			break;
		}
	}
	if(i == ((SYS_CMD_BUFF_TYPE *)pHandle->pCmdBuff)->CmdCount)
	{
		pHandle->DataPrintf("[错误]:不支持的命令!rn>");
		return FALSE;
	}		
	
	pHandle->DataPrintf(">");
	return TRUE;
}




/*************************************************************************************************************************
*函数        	:	u32 SYS_CMD_StringToDec(char *pStr, u8 NumDigits)
*功能        	:	将10进制样式字符串转换为整型数(必须保证完全为数字字符)
*参数        	:	pStr:字符串起始指针
* 					NumDigits:数字位数,10进制数字位数
*返回        	:	转换后的数字
*依赖        	:	无
*作者        	:	cp1300@139.com
*时间        	:	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] = 'A')&&(pStr[i] = 'a')&&(pStr[i] <= 'z'))||(pStr[i] == '.'))
		{
		
		}
		else
		{
			return FALSE;
		}
	}
	
	return TRUE;
}


/*************************************************************************************************************
 * 文件名:			sys_cmd.h
 * 功能:			自定义的系统命令接口
 * 作者:			cp1300@139.com
 * 创建时间:		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, "tt获取系统时间", TRUE};
const SYS_CMD_TYPE  CMD_GET_DATE		=	{"DATE?", CMD_GetDate, "tt获取系统日期", TRUE};
const SYS_CMD_TYPE  CMD_SET_TIME		=	{"TIME=", CMD_SetTime, "tt设置系统时间 如(12:32:54):TIME=12 32 54", TRUE};
const SYS_CMD_TYPE  CMD_SET_DATE		=	{"DATE=", CMD_SetDate, "tt设置系统日期 如(2014 6 8):TIME=2014 6 8", TRUE};

//获取时间
void CMD_GetTime(SYS_CMD_HANDLE *pHandle,char *pStr)
{
	RTC_Get();		//更新时间
	pHandle->DataPrintf("[获取时间成功]:%02d:%02d:%02drn",g_timer.hour, g_timer.min, g_timer.sec);
}

//获取日期
void CMD_GetDate(SYS_CMD_HANDLE *pHandle,char *pStr)
{
	RTC_Get();		//更新时间
	pHandle->DataPrintf("[获取日期成功]:%04d-%02d-%02drn",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("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	//小时
	p = strstr(pStr," ");	//搜索空格
	if(p == NULL)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	num = p - pStr;
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	hour = SYS_CMD_StringToDec(pStr, num);
	if(hour>23)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	
	//分钟
	pStr = p+1;
	p = strstr(pStr," ");	//搜索空格
	if(p == NULL)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	num = p - pStr;
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	min = SYS_CMD_StringToDec(pStr, num);
	if(min>59)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	//秒钟
	pStr = p+1;
	num = strlen(pStr);
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	sec = SYS_CMD_StringToDec(pStr, num);
	if(sec>59)
	{
		pHandle->DataPrintf("[时间设置错误]:格式不对或非法参数!rn");
		return;
	}
	
	if(RTC_SetTime(hour, min, sec) == FALSE)
	{
		RTC_Get();		//更新时间
		pHandle->DataPrintf("[时间设置失败]:%02d:%02d:%02drn",g_timer.hour, g_timer.min, g_timer.sec);
	}
	else
	{
		RTC_Get();		//更新时间
		pHandle->DataPrintf("[时间设置成功]:%02d:%02d:%02drn",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("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	//年
	p = strstr(pStr," ");	//搜索空格
	if(p == NULL)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	num = p - pStr;
	if((num > 4) || (num == 0))
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	year = SYS_CMD_StringToDec(pStr, num);
	if(year>9999)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	
	//月
	pStr = p+1;
	p = strstr(pStr," ");	//搜索空格
	if(p == NULL)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	num = p - pStr;
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	month = SYS_CMD_StringToDec(pStr, num);
	if(month>12)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	//日
	pStr = p+1;
	num = strlen(pStr);
	if((num > 2) || (num == 0))
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	date = SYS_CMD_StringToDec(pStr, num);
	if(date>31)
	{
		pHandle->DataPrintf("[日期设置错误]:格式不对或非法参数!rn");
		return;
	}
	

	if(RTC_SetDate(year, month, date) == FALSE)
	{
		RTC_Get();		//更新时间
		pHandle->DataPrintf("[日期设置失败]:%04d-%02d-%02drn",g_timer.year, g_timer.month, g_timer.date);
	}
	else
	{
		RTC_Get();		//更新时间
		pHandle->DataPrintf("[日期设置成功]:%04d-%02d-%02drn",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);;
		}


在测试时使用起来会非常方便,无需上位机支持,比如设置一些参数,调用xmodem下载升级等操作会非常方便,如下图所示












本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭