/****************************************************************************** 版权所有: 文件名称: rt_console.c 文件版本: 01.01 创建作者: sunxi 创建日期: 2020-01-18 功能说明: 实时FIFO,采用免锁算法,只支持单进单出。 其它说明: 修改记录: */ /*------------------------------- 头文件 -------------------------------------- */ #include "rt.h" #include "my_rtc.h" #include #include /*------------------------------- 宏定义 -------------------------------------- */ #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;ibTT_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); #if 0 static int dt_soe_gen(void); int printf_file101(void) { return 0; } int can_stat(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, "装置参数打印"}, #if defined(BSP_DTU3) || defined(BSP_DTU2) {"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='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;i2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) ) { return (unsigned int)atoi(str); } //处理16进制 str += 2; result = 0; for(i=0;i='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= 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= 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