console.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. #include "macro_common.h"
  2. #include "uart.h"
  3. #include "trace.h"
  4. #include "console.h"
  5. /*TRACE模式使用的输出函数,cli模块借用trace模块的输出函数进行输出,cli初始化时根据
  6. 指定uart端口指定输出函数*/
  7. extern trace_msg_send g_msg_msg_send;
  8. /*console口的命令信息*/
  9. console_cmd_info g_cmd_info;
  10. /*记录上一个输入的命令,用于上箭头时重复执行,目前只支持一条历史命令*/
  11. char g_cmd_last_cmd[CMD_LINE_LEN_MAX];
  12. /*存储console使用的串口ID*/
  13. u8 Console_UID;
  14. /*用于保存用户注册的所有命令的数据结构*/
  15. S_CLI_CMD_LIST g_cli_cmd_list;
  16. /*功能*/
  17. const u32 escape_sequences[] =
  18. {
  19. 0x001B4F50, /* PF1 */
  20. 0x001B4F51, /* PF2 */
  21. 0x001B4F52, /* PF3 */
  22. 0x001B4F53, /* PF4 */
  23. 0x001B5B41, /* UP */
  24. 0x001B5B42, /* DOWN */
  25. 0x001B5B43, /* RIGHT */
  26. 0x001B5B44, /* LEFT */
  27. 0
  28. };
  29. /**************************************************************************************************
  30. *cmd_cmdline_parse --命令行解析函数
  31. *Input:
  32. * pcmd --需要解析的命令字符串;
  33. * cmdlen --需要解析的字符串的长度;
  34. *Output:
  35. * argv --解析出的参数变量
  36. * argc --解析出的参数数目
  37. *Return:
  38. * 0 --正确解析
  39. * -1 --命令字符串有错误
  40. */
  41. static int cmd_cmdline_parse(char *pcmd, u8 cmdlen, char **argv, u8 *argc)
  42. {
  43. char *ptemp = NULL;
  44. u8 argnum = 0;
  45. if(pcmd == NULL || cmdlen == 0)
  46. {
  47. return -1;
  48. }
  49. ptemp = pcmd;
  50. while((*ptemp == ' ')&&(ptemp))
  51. {
  52. ptemp++;
  53. }
  54. argv[argnum++] = ptemp;
  55. ptemp = strstr(pcmd, " ");
  56. while(ptemp != NULL)
  57. {
  58. ptemp++;
  59. *(ptemp-1) = '\0';
  60. /*lint -save -e779*/
  61. while(( " " ==ptemp)&&(ptemp))
  62. {
  63. ptemp++;
  64. }
  65. /*lint -restore*/
  66. argv[argnum++] = ptemp;
  67. ptemp = strstr(ptemp, " ");
  68. }
  69. *argc = argnum;
  70. return 0;
  71. }
  72. #define CMD_CHECK_0 0 /*正确的命令*/
  73. #define INCOMPLET_CMD 1 /*不完整的命令*/
  74. #define UNKOWN_CMD 2 /*未知命令*/
  75. #define UNCONFIRM_CMD 3 /*不确定命令*/
  76. /**************************************************************************************************
  77. *cmd_cmdstr_check --命令行参数检查
  78. *Input:
  79. * argv --解析出来的参数变量
  80. * argc --解析出来的参数数量
  81. *Output:
  82. * pcmdelement --如果参数检查正确,输出对应的命令数据结构的指针
  83. *Return:
  84. * CMD_CHECK_0
  85. * INCOMPLET_CMD
  86. * UNKOWN_CMD
  87. * UNCONFIRM_CMD
  88. */
  89. /*lint -save -e818*/
  90. static int cmd_cmdstr_check(char **argv, u8 argc, u32 *pcmdelement)
  91. {
  92. u8 i = 0, cmdnum = 0, samecmd = 0;
  93. char *arg[CMD_PARAM_NUM_MAX] = {NULL};
  94. PS_CLI_CMD pcmd = NULL;
  95. char buf[CMD_LINE_LEN_MAX];
  96. if(argc >= CMD_PARAM_NUM_MAX)
  97. {
  98. return UNKOWN_CMD;
  99. }
  100. memset(buf,0,sizeof(buf));
  101. for(i=0; i<CMD_MAX_NUM; i++)
  102. {
  103. if(g_cli_cmd_list.cmd[i]!=0)
  104. {
  105. pcmd = (PS_CLI_CMD)g_cli_cmd_list.cmd[i];
  106. if(strncmp(argv[0], pcmd->cmd, strlen(argv[0])) != 0)
  107. {
  108. continue;
  109. }
  110. *pcmdelement = g_cli_cmd_list.cmd[i];
  111. samecmd++;
  112. }
  113. }
  114. if(samecmd == 0)
  115. {
  116. return UNKOWN_CMD;
  117. }
  118. if(samecmd > 1)
  119. {
  120. return UNCONFIRM_CMD;
  121. }
  122. pcmd = (PS_CLI_CMD)(*pcmdelement);
  123. strncpy(buf, pcmd->cmd, strlen(pcmd->cmd));
  124. (void)cmd_cmdline_parse(buf, strlen(buf), arg, &cmdnum);
  125. if(argc < cmdnum)
  126. {
  127. return INCOMPLET_CMD;
  128. }
  129. /* if(argc > cmdnum)
  130. {
  131. return UNKOWN_CMD;
  132. }
  133. */
  134. return 0;
  135. }
  136. /*lint -restore*/
  137. /******************************************************************************
  138. *cmd_run --运行命令函数
  139. *Input:
  140. * None
  141. *Output:
  142. * None
  143. *Return:
  144. * None
  145. */
  146. static void cmd_run(void)
  147. {
  148. u8 argc = 0;
  149. char *arg[CMD_PARAM_NUM_MAX] = {NULL};
  150. PS_CLI_CMD pcmd = NULL;
  151. u32 cmdelement = 0;
  152. int ret = 0;
  153. (void)cmd_out(NEWLINE);
  154. if( 0 == g_cmd_info.cmdLineLen)
  155. {
  156. (void)cmd_out("%s", CMD_PROMPT);
  157. return;
  158. }
  159. memset(g_cmd_last_cmd, 0, sizeof(g_cmd_last_cmd));
  160. strncpy(g_cmd_last_cmd, g_cmd_info.cmdLine, g_cmd_info.cmdLineLen);
  161. if( 0 != cmd_cmdline_parse(g_cmd_info.cmdLine, g_cmd_info.cmdLineLen, arg, &argc) )
  162. {
  163. (void)cmd_out(NEWLINE);
  164. (void)cmd_out("%%\"%s\" unknown commond"NEWLINE, g_cmd_last_cmd);
  165. /*szb add*/
  166. (void)cmd_out("%s",CMD_PROMPT);
  167. return;
  168. }
  169. ret = cmd_cmdstr_check(arg, argc, &cmdelement);
  170. if(ret == CMD_CHECK_0)
  171. {
  172. pcmd = (PS_CLI_CMD)cmdelement;
  173. if(pcmd->func(argc,arg) != 0)
  174. {
  175. (void)cmd_out("%%\"%s\" unknown commond"NEWLINE, g_cmd_last_cmd);
  176. }
  177. }
  178. else
  179. {
  180. switch(ret)
  181. {
  182. case INCOMPLET_CMD:
  183. (void)cmd_out("%% \"%s\" incomplete command"NEWLINE,arg[0]);
  184. break;
  185. case UNKOWN_CMD:
  186. (void)cmd_out("%% \"%s\" unknown command"NEWLINE,arg[0]);
  187. break;
  188. case UNCONFIRM_CMD:
  189. (void)cmd_out("%% \"%s\" unconfirm command"NEWLINE,arg[0]);
  190. break;
  191. default:
  192. break;
  193. }
  194. }
  195. /*szb add*/
  196. (void)cmd_out("%s",CMD_PROMPT);
  197. }
  198. /*****************************************************************************
  199. *cmd_rcv --命令字符串接收函数
  200. *
  201. *Input:
  202. * prt --协议类型,固定为PRTTYPE_CONSOLE,校验用
  203. * pbuf --接收到的数据缓冲头指针
  204. * buflen --接收到的字符串的长度
  205. * version
  206. *Output:
  207. * None
  208. *Return:
  209. * 0 --正确执行
  210. * -1 --执行失败
  211. */
  212. /*lint -save -e818*/
  213. static int cmd_rcv(u8 uartid, void *arg, u8 *pbuf, u16 buflen,u8 version)
  214. {
  215. u32 i = 0, j = 0;
  216. u8 curpos = 0;
  217. static u32 key = 0;
  218. NO_USE(uartid);
  219. NO_USE(arg);
  220. NO_USE(version);
  221. curpos = g_cmd_info.curentpos;
  222. for(i=0; i<buflen; i++)
  223. {
  224. if(pbuf[i] == ESC_KEY)
  225. {
  226. continue;
  227. }
  228. else
  229. {
  230. key = pbuf[i];
  231. }
  232. switch(key)
  233. {/*根据需要增减case*/
  234. case ENTER_KEY:
  235. //if(uart_msg_send_disable(uartid)==FALSE)
  236. {
  237. cmd_run();
  238. }
  239. curpos = 0;
  240. memset(&g_cmd_info, 0, sizeof(g_cmd_info));
  241. break;
  242. case '\t':
  243. /*cmd_out("%c%c%c", 0x1b,0x5b,0x43);*/
  244. break;
  245. case BS_KEY:
  246. if((curpos > 0)&&(curpos == g_cmd_info.cmdLineLen))
  247. {
  248. curpos--;
  249. g_cmd_info.cmdLineLen--;
  250. g_cmd_info.cmdLine[curpos] = '\0';
  251. (void)cmd_out("%c %c", pbuf[i], pbuf[i]);
  252. }
  253. break;
  254. case ESC_KEY:
  255. break;
  256. case RIGHTARROW_KEY:
  257. break;
  258. case LEFTARROW_KEY:
  259. /* if(curpos >0)
  260. {
  261. curpos--;
  262. cmd_out("%c", BS_KEY);
  263. }*/
  264. break;
  265. case DOWNARROW_KEY:
  266. case UPARROW_KEY:
  267. for(j=0; j<g_cmd_info.cmdLineLen; j++)
  268. {
  269. (void)cmd_out("%c %c", BS_KEY, BS_KEY);
  270. }
  271. g_cmd_info.cmdLineLen = 0;
  272. memset(g_cmd_info.cmdLine, 0, sizeof(g_cmd_info.cmdLineLen));
  273. strncpy(g_cmd_info.cmdLine, g_cmd_last_cmd, strlen(g_cmd_last_cmd));
  274. g_cmd_info.cmdLineLen = strlen(g_cmd_last_cmd);
  275. g_cmd_info.curentpos = strlen(g_cmd_last_cmd);
  276. curpos = g_cmd_info.curentpos;
  277. (void)cmd_out("%s", g_cmd_info.cmdLine);
  278. break;
  279. case DEL_KEY:
  280. default:
  281. (void)cmd_out("%c", pbuf[i]);
  282. if(curpos<(CMD_LINE_LEN_MAX-1))
  283. {
  284. g_cmd_info.cmdLine[curpos++] = (char)pbuf[i];
  285. g_cmd_info.cmdLineLen++;
  286. }
  287. break;
  288. }
  289. }
  290. g_cmd_info.curentpos = curpos;
  291. return 0;
  292. }
  293. /*lint -restore*/
  294. /************************************************************
  295. *cmd_install --命令行安装命令函数
  296. *
  297. *Input:
  298. * 待安装的命令行结构
  299. *Output:
  300. * Noen
  301. *Return:
  302. * 0 --安装成功
  303. * -1 --安装失败
  304. */
  305. int cmd_install(CPS_CLI_CMD pcmdelement)
  306. {
  307. if(pcmdelement == NULL)
  308. {
  309. return -1;
  310. }
  311. if(g_cli_cmd_list.num >= CMD_MAX_NUM)
  312. {/*位置不够了*/
  313. return -1;
  314. }
  315. if(strlen(pcmdelement->cmd) > CMD_LINE_LEN_MAX)
  316. {/*命令字符串太长了,不能解析*/
  317. return -1;
  318. }
  319. g_cli_cmd_list.cmd[g_cli_cmd_list.num] = (u32)pcmdelement;
  320. g_cli_cmd_list.num++;
  321. return 0;
  322. }
  323. u8 uart_redirect_cfg[UART_MAX];
  324. DEFCLICMD(uart_redirect_cmd, uart_redirect_struct,
  325. "redirect uart SRC_ID to uart DST_ID","redirect")
  326. {
  327. u8 src_id = 0, dst_id = 0;
  328. NO_USE(argc);
  329. NO_USE(argv);
  330. src_id = atoi(argv[2]);
  331. dst_id = atoi(argv[5]);
  332. if(src_id&&(src_id <= UART_MAX)&&(dst_id <= UART_MAX)) {
  333. (void)cmd_out(NEWLINE"redirect uart src %d to uart %d ", src_id, dst_id);
  334. uart_redirect_cfg[src_id - 1] = dst_id;
  335. (void)cmd_out(NEWLINE);
  336. }
  337. return 0;
  338. }
  339. DEFCLICMD(uart_redirect_show, uart_redirect_show_struct,
  340. "uart redirect show","show redirect")
  341. {
  342. u8 id;
  343. NO_USE(argc);
  344. NO_USE(argv);
  345. cmd_out("%8s %8s"NEWLINE, "SrcUart", "DstUart");
  346. for(id = 0;id < UART_MAX;id++) {
  347. cmd_out("%7s%d %7s%d"NEWLINE, "Uart", id+1, "Uart", uart_redirect_cfg[id]);
  348. }
  349. return 0;
  350. }
  351. extern void cmd_test_install(void);
  352. extern int uart_msg_send(u8 uartid, const char *buf, u32 buflen);
  353. int cmd_init(u8 uartid)
  354. {
  355. Console_UID=uartid;
  356. g_msg_msg_send = uart_msg_send;
  357. //ESC_check_delay_htmr=0;
  358. memset(&g_cli_cmd_list,0,sizeof(g_cli_cmd_list));
  359. memset(&g_cmd_info, 0, sizeof(g_cmd_info));
  360. cmd_test_install();
  361. cmd_install(&uart_redirect_struct);
  362. cmd_install(&uart_redirect_show_struct);
  363. // uart_rs232_init(Console_UID, cmd_rcv);
  364. cmd_out("%s", BOOT_LOGO_INFO);
  365. return 0;
  366. }