/******************************************************************************
版权所有：	
文件名称：	rt_console.c
文件版本：	01.01
创建作者：	sunxi
创建日期：	2020-01-18
功能说明：	实时FIFO，采用免锁算法，只支持单进单出。
其它说明：
修改记录：
*/
/*------------------------------- 头文件 --------------------------------------
*/
#include "rt.h"
#include "my_rtc.h"
#include <pthread.h>
#include <sys/prctl.h>


/*------------------------------- 宏定义 --------------------------------------
*/
#define CONSOLE_BUF_SIZE		16384

/*------------------------------ 类型结构 -------------------------------------
*/


/*------------------------------ 全局变量 -------------------------------------
*/
static unsigned char 	g_console_buf_tx[CONSOLE_BUF_SIZE];
static unsigned char 	g_console_buf_rx[CONSOLE_BUF_SIZE];
struct rt_fifo	g_console_fifo_tx;
struct rt_fifo	g_console_fifo_rx;
//static int 	g_uart_imr = 0;

static char str_hint[] = "DTU_SHELL:\\>";

int g_console_dev_write = 0;

// SOE信号发生器控制全局变量
int g_soe_gen_state;	// 状态，0停止，1初始化，2运行
int g_soe_gen_on_us;    // 导通时间
int g_soe_gen_off_us;	// 断开时间
int g_soe_gen_seq_us;   // 通道序列间隔时间

static pthread_t g_tidp = 0;
int g_thread_exit_flag = 1;
int g_thread_created_flag = 0;

/*------------------------------ 函数声明 -------------------------------------
*/
static void rt_console_thread(void *arg);

/*------------------------------ 外部函数 -------------------------------------
外部函数供其它实体文件引用，必须仔细检查传入参数的合法性.
*/
/******************************************************************************
函数名称：	rt_fifo_init
函数版本：	01.01
创建作者：	sunxi
创建日期：	2020-06-18
函数说明：	rt_fifo初始化
参数说明：
	fifo:	要初始化的rt_fifo结构的指针
	buffer	需要和fifo相连接的buffer
	size	buffer的大小，必须是2的n次方
返回值：	
	0：		成功
	其它：	失败
修改记录：	
*/
int rt_console_init(void)
{
	int ret;
	// 初始化FIFO
	rt_fifo_init(&g_console_fifo_tx,g_console_buf_tx,CONSOLE_BUF_SIZE);
	rt_fifo_init(&g_console_fifo_rx,g_console_buf_rx,CONSOLE_BUF_SIZE);

	ret = pthread_create(&g_tidp, NULL, (void *)rt_console_thread, NULL);
	if(ret)
	{
		rt_printf("thread create error!\n");
		g_tidp = 0;
		return ret;
	}
	g_thread_created_flag = 1;

	return 0;
}

int rt_console_exit(void)
{
	int try_cnt = 0;
	if(!g_thread_created_flag)
		return 0;

	g_thread_exit_flag = 1;
	g_tidp = 0;
	while(g_thread_exit_flag && (try_cnt < 10))
	{
		try_cnt ++;
		usleep(50000);
	}

	return 0;
}

int rt_console_read(unsigned char *buffer, unsigned int len)
{
	if(buffer == NULL)
	{
		return -1;
	}
	
	return (int)rt_fifo_get(&g_console_fifo_rx,buffer,len);
}


int rt_console_write(int is_net,unsigned char *buffer, unsigned int len)
{
	if(buffer == NULL)
	{
		return -1;
	}

{
#if 1

	if(g_console_dev_write)
	{
		rt_fifo_put(&g_console_fifo_tx,buffer,len);
	}
	//else if(g_print_to_net)
	//{
	//	net_debug_send(buffer,len);
//		return 0;
	//}

	else
	{
		unsigned int i;
		unsigned char *buf = buffer;
		for(i=0;i<len;i++)
		{
			rt_printf("%c",*buf++);
		}
	}
#if 0
	if(is_net && pRunSet->bTT_LogPrintf)
	{
		// 如果末尾有回车换行，去掉，因为log_str_len函数会加上。
		if(len > 2)
		{
			if((buffer[len-2]==0x0D) && (buffer[len-1]==0x0A))
			{
				len -= 2;
			}
		}
		
		log_str_len(LOG_PRINTF,buffer,len);
	}
#endif

#else
	struct console *con;

	for (con = console_drivers; con; con = con->next) {
		if ((con->flags & CON_ENABLED) && con->write &&
				(cpu_online(smp_processor_id()) ||
				(con->flags & CON_ANYTIME)))
			con->write(con, buffer, len);
	}
#endif
}

	return 0;
}

unsigned int rt_console_write_len(void)
{
	return g_console_fifo_tx.size - rt_fifo_len(&g_console_fifo_tx);
}

static inline void console_tx_chars(void)
{
    unsigned char c;

    if (rt_fifo_get(&g_console_fifo_tx, &c, 1))
    {
        /* Wait until space is available in the FIFO */
        // while (!(MCF_UART_USR(CFG_UART_RT_CONSOLE) & MCF_UART_USR_TXRDY)) ;

        // MCF_UART_UTB(CFG_UART_RT_CONSOLE) = c;
    }
    else
    {
        //	g_uart_imr &= ~(MCF_UART_UIMR_TXRDY);
        // MCF_UART_UIMR(CFG_UART_RT_CONSOLE) = (unsigned char)g_uart_imr;
    }
}

/*------------------------------ 内部函数 -------------------------------------
内部函数以下划线‘_’开头，不需要检查参数的合法性.
*/

/*------------------------------ 测试函数 -------------------------------------
一个实体文件必须带一个本模块的测试函数来进行单元测试，如果的确不方便在本模块中
进行单元测试，必须在此注明实际的测试位置（例如在哪个实体文件中使用哪个测试函数）.
*/

//-------------------------------------- 外部移植 -------------------------------------


//-------------------------------------- 函数声明 -------------------------------------

// sunxi 20200805 char dt_In(void);
// sunxi 20200805 int dt_OutOne(char c);
// sunxi 20200805 int dt_CmdLine(void);

int dt_CmdCls(void);
int dt_CmdHelp(void);
// sunxi 20200805 int dt_CmdArp(void);
// sunxi 20200805 int dt_CmdExit(void);
// sunxi 20200805 int dt_CmdNetStat(void);
// sunxi 20200805 int dt_CmdReg(void);
int dt_CmdMem(void);
int dt_cmd_rt(void);
int dt_cmd_rt_reset(void);
int dt_cmd_adc(void);
int dt_cmd_freq(void);
int dt_cmd_comm(void);
extern int can_stat(void);
#if 0
static int dt_soe_gen(void);
int printf_file101(void)
{
	return 0;
}

int can_stat_reset(void)
{
	return 0;
}
// sunxi 20200805 int atimer_stat(void);
// sunxi 20200805 int atimer_stat_reset(void);

int equ_info_printf(void)
{
	return 0;
}
int equ_info_printf_di(void)
{
	return 0;
}
int equ_info_printf_do(void)
{
	return 0;
}
int equ_info_printf_ac(void)
{
	return 0;
}
int dido_printf(void)
{
	return 0;
}
int dido_stat_reset(void)
{
	return 0;
}
int factor_printf(void)
{
	return 0;
}
int dcfactor_printf(void)
{
	return 0;
}
int tbl_printf_rsc(void)
{
	return 0;
}
int tbl_printf(void)
{
	return 0;
}
int sw_ui_temp(void)
{
	return 0;
}
int runstu_printf(void)
{
	return 0;
}
int s_stat_display(void)
{
	return 0;
}
int  x509_show_all(void)
{
	return 0;
}
int protect_printf_process(void)
{
	return 0;
}
int IEC101_Info_Printf(void)
{
	return 0;
}
int IEC104_Info_Printf(void)
{
	return 0;
}
int plc_info_printf(void)
{
	return 0;
}
int plc_lp_printf(void)
{
	return 0;
}
int soe_info_printf(void)
{
	return 0;
}
int soe_stat_reset(void)
{
	return 0;
}
// sunxi 20200805 int bat_create_csv(void);
int led_info_printf(void)
{
	return 0;
}
int auth_info_printf(void)
{
	return 0;
}
#endif
//-------------------------------------- 宏定义 -------------------------------------

#ifdef __WIN32__
#define DT_COM			"COM2"
#else
#define DT_COM			"COM1"
#endif
#define DT_COM_BAUD		57600
#define DT_CMDLINE_SIZE 256

typedef struct
{
	char *szCmd;
	int (*fnCmd)(void);
	char *szCmdHelp;
}TCmd;

//发送
static char str_esc[]      	 = { 0x1b, 0x5b, 0x0 } ; // ESC[
static char str_version[]	= "V01.01.01 2012/02/15";
static char str_cls[]      	 = "\x1b[2J" ;
static char str_clr[]		= "\x1b[K" ;
//static char str_save[]		= "\x1b[s" ;
//static char str_load[]		= "\x1b[u" ;
//static char str_moveto[]	= "\x1b[H" ;

//接收
static char str_up[]		= "\x1b[A" ;
static char str_down[]		= "\x1b[B" ;

//------------------------------------- 全局变量 ----------------------------------------
//static int	ghCom = -1;
//static int	gThreadId = -1;

//static char gOutLine[DT_CMDLINE_SIZE];
static char gCmdLine[DT_CMDLINE_SIZE];
static char gCmdLineBack[DT_CMDLINE_SIZE];
static int	gCmdLineCount;
char * gCmdArg[32];
int	gCmdArgCount;

TCmd gCmd[] = 
{
	{"help",dt_CmdHelp,"帮助,列出所有命令"},
	{"?",dt_CmdHelp,"帮助,列出所有命令"},
	{"cls",dt_CmdCls,"清屏"},
	{"mem",dt_CmdMem,"显示和修改存储器内容"},
	{"rt",dt_cmd_rt,"显示实时时间统计"},
	{"reset",dt_cmd_rt_reset,"实时统计数据复位"},
#if 0
	{"adc",dt_cmd_adc,"显示ADC抖动统计"},
	{"freq",dt_cmd_freq,"显示频率抖动统计"},
	{"f101",printf_file101,"101文件传输状态"},
	{"dido",dido_printf,"开入开出打印"},
//	{"at",atimer_stat,"可调定时器统计"},
	{"equ",equ_info_printf,"装置信息"},
	{"equdi",equ_info_printf_di,"装置开入信息"},
	{"equdo",equ_info_printf_do,"装置开出信息"},
	{"equac",equ_info_printf_ac,"装置模拟量信息"},
	{"led",led_info_printf,"LED灯信息"},
	//{"pub",sw_pub_printf,"开关公共信息打印"},
	//{"sw",sw_printf,"开关信息打印"},
	//{"pubv",sw_pub_printf_v,"开关公共值打印"},
	//{"swv",sw_printf_v,"开关值打印"},
	//{"ui",sw_ui_printf,"电压电流系数打印"},
	//{"uie",sw_ui_printf_e,"测量电压电流有效值打印"},
	//{"uip",sw_ui_printf_p,"测量电压电流角度值打印"},
	//{"uim",sw_ui_printf_m,"保护电压电流M2值打印"},
	{"factor",factor_printf,"校正系数"},
	{"dcfactor",dcfactor_printf,"直流校正系数"},
	{"rsc", tbl_printf_rsc, "资源表打印"},
	{"err",rt_err_printf, "系统错误信息"},
	{"uitemp",sw_ui_temp, "温度校正系数"},
	{"tbl",tbl_printf, "转发点表打印"},
	//{"vol_stu",vol_stu_printf, "上电合闸状态打印"},
	{"run_st",runstu_printf, "内部状态打印"},
	{"x509",x509_show_all, "查看证书内容"},
	{"protect", protect_printf_process, "保护整组处理过程"},
	{"sstat", s_stat_display, "通讯统计信息"},
	{"101", IEC101_Info_Printf, "101规约信息打印"},
	{"104", IEC104_Info_Printf, "104规约信息打印"},
	{"lp",plc_lp_printf,"逻辑点信息打印"},
	{"plc", plc_info_printf, "可编程逻辑信息打印"},
	{"soe", soe_info_printf, "SOE信息打印"},
	{"soegen", dt_soe_gen, "SOE信号发生器"},
	{"comm", dt_cmd_comm, "通讯报文监视"},
#endif
	#if 0
	{"bathh", bat_create_csv, "生成电池活化CSV文件"},
	{"extrema",extrema_create_csv,"极值文件生成"},
	{"energy", energy_create_csv, "电度文件生成"},
	{"mearcd", mearcd_create_csv, "定点遥测文件生成"},
	{"capmanage", capmanage_create_csv, "电容器管理文件生成"},
	{"udcrcd", udcrcd_create_csv, "电池电压文件生成"},
	#endif
	
//	{"auth", auth_info_printf, "装置授权信息打印"},
	//{"linktbl", tbl_link_printf, "级联点表打印"},
	//{"link", lnk_info_printf, "级联信息打印"},
	//{"xdl", xdl_info_printf, "小电流接地信息打印"},
	//{"fxdl", xdl_info_fromfile_printf, "录波文件小电流接地信息打印"},
	//{"esam", esam_info_printf, "加解密芯片信息打印"},
	//{"sec", sec_info_printf, "安全信息打印"},
	//{"ept", print_EquipParaTable, "装置参数打印"},
	
#ifdef BSP_CAN_ENABLE
	{"can",can_stat,"CAN总线统计"},
	{"sb",can_app_sb_monitor, "子板监视信息"},
	{"cantest",can_app_test_printf, "子板测试信息"},
#endif
};
  
#define CMD_NUM	((int)(sizeof(gCmd)/sizeof(TCmd)))

 
//------------------------------------- 外部函数 ----------------------------------------

static void rt_console_thread(void *arg)
{
	static char EscCmd[16];
	static int IsEsc=0;
	
	char c;
	char *p;
	int i;

	g_thread_exit_flag = 0;

	// 1.得到一行字符,每接收一个字符要回送.
	prctl(PR_SET_NAME, "rt_console_thread");
	while(rt_console_read((unsigned char *)&c, 1) == 1)
	{
		//ESC处理
		if(c == 0x1b)
		{
			IsEsc=0;
			EscCmd[IsEsc++] = c;
			continue;
		}
		else if(IsEsc)
		{
			EscCmd[IsEsc++] = c;
			if(IsEsc == 3)
			{
				IsEsc=0;
				if(memcmp(EscCmd,str_up,3) == 0 || memcmp(EscCmd,str_down,3) == 0)
				{
					rt_printf("%s%dD",str_esc,gCmdLineCount);
					rt_printf(str_clr);
					strcpy(gCmdLine,gCmdLineBack);
					gCmdLineCount = (int)strlen(gCmdLine);
					rt_printf(gCmdLine);
				}
			}
			continue;
		}

		if(c == '\b' && gCmdLineCount > 0)
		{
			gCmdLineCount--;
			rt_printf(str_clr);
			continue;
		}
		else if(c == '\n' || c == '\r')
		{
			gCmdLine[gCmdLineCount]  = 0;
			strcpy(gCmdLineBack,gCmdLine);
		//	gCmdLineBack[strlen(gCmdLineBack) - 1] = 0;//去掉最后的回车符
			gCmdLineCount++;
		//	break;
		}
		else if(gCmdLineCount < DT_CMDLINE_SIZE -1)
		{
			gCmdLine[gCmdLineCount] = c;
			gCmdLineCount++;
			continue;
		}

		//如果是空行,重新开始
		if(strlen(gCmdLine)<1)
		{
			gCmdLineCount = 0;
			rt_printf(str_hint);
			continue;
		}
		
		//将命令行转换成小写
#if 0 // 不允许将命令行转为小写，否则auth授权命令不正确
		for(i=0;i<strlen(gCmdLine);i++)
		{
			if(gCmdLine[i]>='A' && gCmdLine[i]<='Z')
				gCmdLine[i] += 'a' - 'A';
		}
#endif
		// 2.分解出所有的参数
		memset(gCmdArg,0,sizeof(gCmdArg));
		gCmdArgCount = 0;
		p = gCmdLine;
		while(*p)
		{
			//去掉前面的空格
			while(*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
				p++;
			if(*p == 0)
				break;

			//得到参数
			gCmdArg[gCmdArgCount++] = p;
			while(*p != 0 &&*p != ' ' && *p != '\t' && *p != '\r' && *p != '\n')
				p++;
			if(*p == 0)
				break;
			*p =0;

			if(gCmdArgCount >= 32)
				break;
			p++;
		}
		if(gCmdArgCount == 0)
		{
			gCmdLineCount = 0;
			continue;
		}

		// 3.寻找相应的命令,执行
		for(i=0;i<CMD_NUM;i++)
		{
			if(strcmp(gCmdArg[0],gCmd[i].szCmd) == 0)
			{
				gCmd[i].fnCmd();
				break;
			}
		}

		if(i == CMD_NUM)
			rt_printf("不能识别的命令: \"%s\"!\r\n",gCmdArg[0]);

		//命令提示符
		rt_printf(str_hint);

		gCmdLineCount = 0;
	}

	g_thread_created_flag = 0;

}


//------------------------------------- 内部函数 ----------------------------------------

int dt_CmdCls(void)
{
	rt_printf(str_cls);
	return 0;
}

static unsigned int str2int(char *str)
{
	unsigned int i,result;
	char n;
	
	if(!str)
		return 0;

	//处理10进制		
	if( !(strlen(str)>2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) )
	{
		return (unsigned int)atoi(str);
	}
		
	//处理16进制
	str += 2;
	result = 0;
	for(i=0;i<strlen(str);i++)
	{
		n = str[i];
		if(n>='0' && n<='9')
			n = n - '0';
		else if(n>='a' && n<='f')
			n = n - 'a' + 10;
		else if(n>='A' && n<='F')
			n = n - 'A' + 10;
		else
			break;
		
		result = result*16 + n;
	}
	
	return result;
}



//------------------------------------- 命令行函数 ----------------------------------------
//帮助
int dt_CmdHelp(void)
{
	int i;

	rt_printf("\r\n");
	rt_printf(str_version);
	rt_printf("\r\n\r\n");
	for(i=0;i<CMD_NUM;i++)
	{
		rt_printf("%s:	%s\r\n",gCmd[i].szCmd,gCmd[i].szCmdHelp);
	}
	rt_printf("\r\n");

	rt_printf("如果需要命令的详细帮助,请输入\"命令 -h\"\r\n");
	
	return 0;
}



int dt_CmdMem(void)
{
	unsigned int i,addr,value,length;
	unsigned short value1;
	unsigned char value2;
	
	if(gCmdArgCount == 1)
	{
			rt_printf("mem [-r addr |-w addr value] [-t4 number|-t2 number|-t1 number] -h\r\n");
			return 0;
	}

	if(strcmp(gCmdArg[1],"-h") == 0)
	{
			rt_printf("mem [-r addr |-w addr value] [-t4 number|-t2 number|-t1 number] -h\r\n");
			return 0;
	}
	else if(strcmp(gCmdArg[1],"-r") == 0 && gCmdArgCount >= 3)
	{
			addr = str2int(gCmdArg[2]);
			addr = addr&0xfffffffc;
			
			if((gCmdArgCount >=5) && ((strcmp(gCmdArg[3],"-t4") == 0) || (strcmp(gCmdArg[3],"-t2") == 0) || (strcmp(gCmdArg[3],"-t1") == 0)))
				length = str2int(gCmdArg[4]);
			else if(gCmdArgCount == 4 && ((strcmp(gCmdArg[3],"-t4") == 0) || (strcmp(gCmdArg[3],"-t2") == 0) || (strcmp(gCmdArg[3],"-t1") == 0)))
			{
				length = 1;			
			}
			else if(gCmdArgCount == 3)
			{
				length = 1;
				gCmdArg[3] = "-t4";	
			}
			else 
			{
				rt_printf("不能识别的参数:%s\r\n",gCmdArg[3]);
				return -1;
			}
			
			if(strcmp(gCmdArg[3],"-t4") == 0)
			{
				for(i=0;i<length;i++)
				{
					if(i%4 == 0)
					{
						rt_printf("0x%08x: ",(addr+i*4));
					}
					rt_printf("%08x ",*(unsigned int *)(addr+i*4));
					if(i%4 == 3)
					{
							rt_printf("\r\n");
					}
					//rt_printf("0x%08x: %08x\r\n",(addr+i*4),*(unsigned int *)(addr+i*4));
				}
				if((length-1)%4 != 3)
				{
					rt_printf("\r\n");
				}	
			}
			else if((strcmp(gCmdArg[3],"-t2") == 0))
			{
				for(i=0;i<length;i++)
				{
					if(i%8 == 0)
					{
						rt_printf("0x%08x: ",(addr+i*2));
					}
					rt_printf("%04x ",*(unsigned short *)(addr+i*2));
					if(i%8 == 7)
					{
							rt_printf("\r\n");
					}
					//rt_printf("0x%04x: %04x    ",(addr+i*2),*(unsigned short *)(addr+i*2));
				}
				if((length-1)%8 != 7)
				{
					rt_printf("\r\n");
				}	
			}
			else if((strcmp(gCmdArg[3],"-t1") == 0))
			{
				for(i=0;i<length;i++)
				{
					if(i%16 == 0)
					{
						rt_printf("0x%08x: ",(addr+i));
					}
					rt_printf("%02x ",*(unsigned char *)(addr+i));
					if(i%16 == 15)
					{
							rt_printf("\r\n");
					}
					//rt_printf("0x%02x: %02x    ",(addr+i),*(unsigned char *)(addr+i));
				}
				if((length-1)%16 != 15)
				{
					rt_printf("\r\n");
				}	
			}	

			return 0;
	}
	else if(strcmp(gCmdArg[1],"-w") == 0  && gCmdArgCount >= 4)
	{
			addr = str2int(gCmdArg[2]);
			addr = addr&0xfffffffc;
			
			value = str2int(gCmdArg[3]);
			
			if(gCmdArgCount >=6 && ((strcmp(gCmdArg[4],"-t4") == 0) || (strcmp(gCmdArg[4],"-t2") == 0) || (strcmp(gCmdArg[4],"-t1") == 0)))
				length = str2int(gCmdArg[5]);
			else if(gCmdArgCount == 5 && ((strcmp(gCmdArg[4],"-t4") == 0) || (strcmp(gCmdArg[4],"-t2") == 0) || (strcmp(gCmdArg[4],"-t1") == 0)))
			{
				length = 1;			
			}
			else if(gCmdArgCount == 4)
			{
				length = 1;
				gCmdArg[4] = "-t4";	
			}
			else if(gCmdArgCount == 3)
			{
				rt_printf("缺少参数\r\n");
				return -1;
			}
			else
			{
				rt_printf("不能识别的参数:%s\r\n",gCmdArg[4]);
				return -1;
			}
				
			if((strcmp(gCmdArg[4],"-t4") == 0))
			{
					for(i=0;i<length;i++)
					{
						*(unsigned int *)(addr+i*4) = value;
						
						if(i%4 == 0)
						{
							rt_printf("0x%08x: ",(addr+i*4));
						}
						rt_printf("%08x ",*(unsigned int *)(addr+i*4));
						if(i%4 == 3)
						{
								rt_printf("\r\n");
								
						}
						//rt_printf("0x%08x: %08x    \r\n",(addr+i*4),*(unsigned int *)(addr+i*4));
					}
					if((length-1)%4 != 3)
					{
						rt_printf("\r\n");
					}				
			}
			else if((strcmp(gCmdArg[4],"-t2") == 0))
			{
					value1 = (unsigned short)(value);
					for(i=0;i<length;i++)
					{
						*(unsigned short *)(addr+i*2) = value1;

						if(i%8 == 0)
						{
							rt_printf("0x%04x: ",(addr+i*2));
						}
						rt_printf("%04x ",*(unsigned short *)(addr+i*2));
						if(i%8 == 7)
						{
							rt_printf("\r\n");
						}
						//rt_printf("0x%04x: %04x    ",(addr+i*2),*(unsigned short *)(addr+i*2));
					}		
					if((length-1)%8 != 7)
					{
						rt_printf("\r\n");
					}			
			}
			else if((strcmp(gCmdArg[4],"-t1") == 0))
			{
					value2 = (unsigned char)(value);
					for(i=0;i<length;i++)
					{
						*(unsigned char *)(addr+i) = value2;
						
						if(i%16 == 0)
						{
							rt_printf("0x%02x: ",(addr+i));
						}
						rt_printf("%02x ",*(unsigned char *)(addr+i));
						if(i%16 == 15)
						{
								rt_printf("\r\n");
					  }
						//rt_printf("0x%02x: %02x    ",(addr+i),*(unsigned char *)(addr+i));
					}		
					if((length-1)%16 != 15)
					{
						rt_printf("\r\n");
					}			
			}
			
			
			return 0;	
	}
	else
	{
		rt_printf("不能识别的参数:%s\r\n",gCmdArg[1]);
	}
	
	return -1;
}


struct timespec g_ts_rt_reset;
static void dt_cmd_rt_printf_head(void)
{
	struct timespec ts;
	struct rtc_time_t tm;
  
	//rt_printf("%s!\r\n",RT_SYSTEM_INFO);
	
	timespec_to_rtc(g_ts_rt_reset,&tm,0);
	rt_printf("RESET  TIME: %04d-%02d-%02d %02d:%02d:%02d:%09d!\r\n",
			tm.year + 2000,
			tm.month,
			tm.day,
			tm.hour,
			tm.min,
			tm.ms/1000,
			g_ts_rt_reset.tv_nsec
			);

	clk_time_get(&ts);
	timespec_to_rtc(ts,&tm,0);
	rt_printf("UPDATE TIME: %04d-%02d-%02d %02d:%02d:%02d:%09d!\r\n",
			tm.year + 2000,
			tm.month,
			tm.day,
			tm.hour,
			tm.min,
			tm.ms/1000,
			ts.tv_nsec
			);
}


int dt_cmd_rt(void)
{
	dt_cmd_rt_printf_head();
	rt_printf("name\t\t\tmin\tmax\tavg\tsum\t\tcnt");
	
	pit_stat_printf();
	
	rt_stat_other_printf();

	return 0;
}

int dt_cmd_adc(void)
{
	dt_cmd_rt_printf_head();
	adc_stat_printf();

	return 0;
}


int dt_cmd_freq(void)
{
	dt_cmd_rt_printf_head();
	rt_printf("name\t\t\tmin\tmax\tavg\tsum\t\tcnt");
	// sunxi 20200805 freq_stat_printf();

	return 0;
}

extern SOCKET g_debug_client;
#define COMM_CHANNEL_NUM	10	// sunxi 20200814 这些命令的实现不应该放在rt这边的，特别是涉及到这些业务的代码。
int dt_cmd_comm(void)
{
	u32 port;
	if(gCmdArgCount == 2)
	{
		port = atoi(gCmdArg[1]);
		if(port < COMM_CHANNEL_NUM)
		{
			// sunxi 20200805 g_print_port = 1<<port;

			rt_printf("报文监视打开成功:port=%lu.\r\n",port);
		}
		else
		{
			rt_printf("报文监视打开失败:port=%lu.\r\n",port);
			return -1;
		}
	}
	else
	{
		// sunxi 20200805 g_print_port = -1;
		rt_printf("报文监视打开成功...\r\n");
	}

//	g_print_comm_raw = 1;
	// sunxi 20200805 g_print_sys = 1;
	// sunxi 20200805 g_print_104 = 1;
	// sunxi 20200805 g_print_101 = 1;
	// sunxi 20200805 g_print_lnk = 1;

	if(g_debug_client != RT_SOCKET_ERR)
	{
		// sunxi 20200805 g_print_to_net = 1;
	}

	
	return 0;
}

#if 0
static int dt_soe_gen(void)
{
	g_soe_gen_state = 0;
	
	if(gCmdArgCount != 2 && gCmdArgCount != 4)
	{
		rt_printf("soe发生器已关闭。\r\n");
		rt_printf("soe发生器用法:soegen soe_seq_ms soe_on_ms g_soe_off_ms\r\n");
		return 0;
	}
	
	if(gCmdArgCount == 2)
	{
		g_soe_gen_seq_us = atoi(gCmdArg[1]);
		g_soe_gen_on_us = 50;
		g_soe_gen_off_us = 50;
		
	}
	else if(gCmdArgCount == 4)
	{
		g_soe_gen_seq_us = atoi(gCmdArg[1]);
		g_soe_gen_on_us = atoi(gCmdArg[2]);
		g_soe_gen_off_us = atoi(gCmdArg[3]);
	}
	
	rt_printf("soe发生器开启:间隔时间=%dms,ON时间=%dms,OFF时间=%dms.\r\n",g_soe_gen_seq_us,g_soe_gen_on_us,g_soe_gen_off_us);

	g_soe_gen_seq_us *= 10;
	g_soe_gen_on_us  *= 10;
	g_soe_gen_off_us *= 10;
	g_soe_gen_state   = 1;

	return 0;
}
#endif

// sunxi 20200805 extern unsigned int g_iec101_recv_count;
void s_stat_reset1(int all)
{

}

extern int dido_stat_reset(void);
extern int s_stat_reset(int all);
extern int soe_stat_reset(void);
int dt_cmd_rt_reset(void)
{
	// sunxi 20200805 g_print_104 = 0;
	// sunxi 20200805 g_print_101 = 0;
	// sunxi 20200805 g_print_lnk = 0;
//	g_print_comm_raw = 0;
	// sunxi 20200805 g_print_port = -1;
	
	//clock_gettime(CLOCK_REALTIME, &g_ts_rt_reset);
	
	pit_stat_reset();
	
	rt_stat_other_reset();

	// sunxi 20200805 adc_stat_reset();

	// sunxi 20200805 freq_stat_reset();


//	atimer_stat_reset();

	// sunxi 20200805 sw_stat_reset();
	
	dido_stat_reset();

	// sunxi 20200805 protect_stat_reset();
	s_stat_reset(1);//串口统计信息复位

	soe_stat_reset();

#if defined(BSP_CAN_ENABLE)
	can_stat_reset();
#endif

	rt_printf("实时统计数据已复位!\r\n");

	return 0;
}



/*------------------------------ 文件结束 -------------------------------------
*/


