1 /*
2 * Copyright (C) 2022 Beken Corporation
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdlib.h>
17 #include "sys_rtos.h"
18 #include <os/os.h>
19 #include <common/bk_kernel_err.h>
20
21 #include "bk_cli.h"
22 #include "stdarg.h"
23 #include <common/bk_include.h>
24 #include <os/mem.h>
25 #include <os/str.h>
26 #include "bk_phy.h"
27 #include "cli.h"
28 #include "cli_config.h"
29 #include <components/log.h>
30 #include <driver/uart.h>
31 #include "bk_rtos_debug.h"
32 #if CONFIG_SHELL_ASYNCLOG
33 #include "components/shell_task.h"
34 #endif
35 #include "bk_uart_debug.h"
36 #include "bk_api_cli.h"
37 #if (CONFIG_SLAVE_CORE && CONFIG_MEDIA)
38 #include "media_common.h"
39 #endif
40
41 #ifdef CONFIG_MEDIA
42 #include "media_cli.h"
43 #endif
44
45
46 #define TAG "cli"
47
48 static struct cli_st *pCli = NULL;
49
50 #if (!CONFIG_SHELL_ASYNCLOG)
51 beken_semaphore_t log_rx_interrupt_sema = NULL;
52 #endif
53
54 static uint16_t s_running_command_index = MAX_COMMANDS;
55 #if CFG_CLI_DEBUG
56 static uint8_t s_running_status = 0;
57 #endif
58
59 extern int cli_putstr(const char *msg);
60 extern int hexstr2bin(const char *hex, u8 *buf, size_t len);
61
62 #if CONFIG_CAMERA
63 extern int video_demo_register_cmd(void);
64 #endif
65
66 #if CONFIG_BKREG
67 #define BKREG_MAGIC_WORD0 (0x01)
68 #define BKREG_MAGIC_WORD1 (0xE0)
69 #define BKREG_MAGIC_WORD2 (0xFC)
70 #define BKREG_MIN_LEN 3
71 #endif
72
73 #define SHELL_TASK_PRIORITY 1
74
75 /* Find the command 'name' in the cli commands table.
76 * If len is 0 then full match will be performed else upto len bytes.
77 * Returns: a pointer to the corresponding cli_command struct or NULL.
78 */
lookup_command(char * name,int len)79 const struct cli_command *lookup_command(char *name, int len)
80 {
81 int i = 0;
82 int n = 0;
83
84 while (i < MAX_COMMANDS && n < pCli->num_commands) {
85 if (pCli->commands[i]->name == NULL) {
86 i++;
87 continue;
88 }
89
90 /* See if partial or full match is expected */
91 if (len != 0) {
92 if (!os_strncmp(pCli->commands[i]->name, name, len)) {
93 s_running_command_index = i;
94 return pCli->commands[i];
95 }
96 } else {
97 if (!os_strcmp(pCli->commands[i]->name, name)) {
98 s_running_command_index = i;
99 return pCli->commands[i];
100 }
101 }
102
103 i++;
104 n++;
105 }
106
107 return NULL;
108 }
109
lookup_cmd_table(const struct cli_command * cmd_table,int table_items,char * name,int len)110 int lookup_cmd_table(const struct cli_command *cmd_table, int table_items, char *name, int len)
111 {
112 int i;
113
114 for (i = 0; i < table_items; i++)
115 {
116 if (cmd_table[i].name == NULL)
117 {
118 continue;
119 }
120
121 /* See if partial or full match is expected */
122 if (len != 0)
123 {
124 if (!os_strncmp(cmd_table[i].name, name, len))
125 {
126 return i;
127 }
128 }
129 else
130 {
131 if (!os_strcmp(cmd_table[i].name, name))
132 {
133 return i;
134 }
135 }
136 }
137
138 return -1;
139 }
140
141 #if (CONFIG_SHELL_ASYNCLOG && !CONFIG_ATE_TEST)
142
143 /* Parse input line and locate arguments (if any), keeping count of the number
144 * of arguments and their locations. Look up and call the corresponding cli
145 * function if one is found and pass it the argv array.
146 *
147 * Returns: 0 on success: the input line contained at least a function name and
148 * that function exists and was called.
149 * 1 on lookup failure: there is no corresponding function for the
150 * input line.
151 * 2 on invalid syntax: the arguments list couldn't be parsed
152 */
handle_shell_input(char * inbuf,int in_buf_size,char * outbuf,int out_buf_size)153 int handle_shell_input(char *inbuf, int in_buf_size, char * outbuf, int out_buf_size)
154 {
155 struct {
156 unsigned inArg: 1;
157 unsigned inQuote: 1;
158 unsigned done: 1;
159 unsigned limQ : 1;
160 unsigned isD : 2;
161 } stat;
162 static char *argv[16];
163 int argc = 0;
164 int i = 0;
165 const struct cli_command *command = NULL;
166 const char *p;
167
168 os_memset((void *)&argv, 0, sizeof(argv));
169 os_memset(&stat, 0, sizeof(stat));
170
171 if(outbuf != NULL)
172 os_memset(outbuf, 0, out_buf_size);
173
174 if (inbuf[i] == '\0')
175 return 0;
176
177 do {
178 switch (inbuf[i]) {
179 case '\0':
180 if (((argc == 0)||(stat.isD == 1))||(stat.limQ)||(stat.inQuote))
181 {
182 if(outbuf != NULL)
183 strcpy(&outbuf[0], "syntax error\r\n");
184 return 2;
185 }
186 stat.done = 1;
187 break;
188
189 case '"':
190 if (i > 0 && inbuf[i - 1] == '\\' && stat.inArg) {
191 os_memcpy(&inbuf[i - 1], &inbuf[i],
192 os_strlen(&inbuf[i]) + 1);
193 --i;
194 break;
195 }
196 if (!stat.inQuote && stat.inArg)
197 break;
198 if (stat.inQuote && !stat.inArg)
199 {
200 if(outbuf != NULL)
201 strcpy(&outbuf[0], "syntax error\r\n");
202 return 2;
203 }
204
205 if (!stat.inQuote && !stat.inArg) {
206 stat.inArg = 1;
207 stat.inQuote = 1;
208 argc++;
209 argv[argc - 1] = &inbuf[i + 1];
210 } else if (stat.inQuote && stat.inArg) {
211 stat.inArg = 0;
212 stat.inQuote = 0;
213 inbuf[i] = '\0';
214 }
215 break;
216
217 case ' ':
218 if (i > 0 && inbuf[i - 1] == '\\' && stat.inArg) {
219 os_memcpy(&inbuf[i - 1], &inbuf[i],
220 os_strlen(&inbuf[i]) + 1);
221 --i;
222 break;
223 }
224 if (!stat.inQuote && stat.inArg) {
225 stat.inArg = 0;
226 inbuf[i] = '\0';
227 }
228 break;
229
230 case '=':
231 if(argc == 1) {
232 inbuf[i] = '\0';
233 stat.inArg = 0;
234 stat.isD = 1;
235 }
236 else if(argc == 0){
237 if(outbuf != NULL)
238 strcpy(&outbuf[0], "syntax error\r\n");
239 return 2;
240 }
241 break;
242
243 case ',':
244 if((stat.isD == 1)&&(argc == 1)) ///=,
245 {
246 if(outbuf != NULL)
247 strcpy(&outbuf[0], "syntax error\r\n");
248 return 2;
249 }
250 if(!stat.inQuote && stat.inArg) {
251 stat.inArg = 0;
252 inbuf[i] = '\0';
253 stat.limQ = 1;
254 }
255 break;
256
257 default:
258 if (!stat.inArg) {
259 stat.inArg = 1;
260 argc++;
261 argv[argc - 1] = &inbuf[i];
262 stat.limQ = 0;
263 if(stat.isD == 1) {
264 stat.isD = 2;
265 }
266 }
267 break;
268 }
269 } while (!stat.done && ++i < in_buf_size);
270
271 if (stat.inQuote)
272 {
273 if(outbuf != NULL)
274 strcpy(&outbuf[0], "syntax error\r\n");
275 return 2;
276 }
277
278 if (argc < 1)
279 {
280 if(outbuf != NULL)
281 strcpy(&outbuf[0], "argc = 0\r\n");
282 return 0;
283 }
284
285 /*
286 * Some comamands can allow extensions like foo.a, foo.b and hence
287 * compare commands before first dot.
288 */
289 i = ((p = os_strchr(argv[0], '.')) == NULL) ? 0 :
290 (p - argv[0]);
291 command = lookup_command(argv[0], i);
292 if (command == NULL)
293 {
294 if(outbuf != NULL)
295 sprintf(&outbuf[0], "cmd: %s NOT found.\r\n", inbuf);
296 return 1;
297 }
298
299 #if CONFIG_STA_PS
300 /*if cmd,exit dtim ps*/
301 if (os_strncmp(command->name, "ps", 2)) {
302 }
303 #endif
304
305 #if CFG_CLI_DEBUG
306 s_running_status |= CLI_COMMAND_IS_RUNNING;
307 command->function(outbuf, out_buf_size , argc, argv);
308 s_running_status &= ~CLI_COMMAND_IS_RUNNING;
309 #else
310 command->function(outbuf, out_buf_size , argc, argv);
311 #endif
312
313 return 0;
314 }
315
316 #elif CONFIG_ATE_TEST
317 static beken_semaphore_t ate_test_semaphore = NULL;
ate_uart_rx_isr(uart_id_t id,void * param)318 static void ate_uart_rx_isr(uart_id_t id, void *param)
319 {
320 int ret;
321
322 ret = rtos_set_semaphore(&ate_test_semaphore);
323 if(kNoErr !=ret)
324 os_printf("ate_uart_rx_isr: ATE set sema failed\r\n");
325 }
326
ate_uart_tx_isr(uart_id_t id,void * param)327 static void ate_uart_tx_isr(uart_id_t id, void *param)
328 {
329 bk_uart_disable_tx_interrupt(CONFIG_UART_PRINT_PORT);
330 }
331
cli_ate_main(uint32_t data)332 static void cli_ate_main(uint32_t data)
333 {
334
335 char *msg = NULL;
336 int ret = -1;
337 int cnt = 0;
338 uint8_t rx_data;
339
340 if(NULL == ate_test_semaphore)
341 {
342 ret = rtos_init_semaphore(&ate_test_semaphore, 1);
343 if (kNoErr != ret)
344 os_printf("cli_ate_main: ATE create background sema failed\r\n");
345 }
346
347 bk_uart_disable_sw_fifo(CONFIG_UART_PRINT_PORT);
348 bk_uart_register_rx_isr(CONFIG_UART_PRINT_PORT, (uart_isr_t)ate_uart_rx_isr, NULL);
349 bk_uart_enable_rx_interrupt(CONFIG_UART_PRINT_PORT);
350
351 bk_uart_register_tx_isr(CONFIG_UART_PRINT_PORT, (uart_isr_t)ate_uart_tx_isr, NULL);
352 bk_uart_enable_tx_interrupt(CONFIG_UART_PRINT_PORT);
353
354 send_device_id();
355 ate_test_multiple_cpus_init();
356
357 while (1) {
358
359 ret = rtos_get_semaphore(&ate_test_semaphore, BEKEN_WAIT_FOREVER);
360 if(kNoErr == ret) {
361 while(1) /* read all data from rx-FIFO. */
362 {
363 ret = uart_read_byte_ex(CONFIG_UART_PRINT_PORT, &rx_data);
364 if (ret == -1)
365 break;
366
367 pCli->inbuf[cnt] = (char)rx_data;
368 cnt++;
369
370 if(cnt >= INBUF_SIZE)
371 break;
372 }
373
374 bkreg_run_command1(pCli->inbuf, cnt);
375
376 if (cnt > 0) {
377 for (int i = 0;i < cnt; i++)
378 pCli->inbuf[i] = 0;
379 cnt = 0;
380 }
381 }
382
383 msg = pCli->inbuf;
384 if (os_strcmp(msg, EXIT_MSG) == 0)
385 break;
386 }
387
388 os_printf("CLI exited\r\n");
389 os_free(pCli);
390 pCli = NULL;
391
392 rtos_delete_thread(NULL);
393 }
394
395 #else
396
397 /* Parse input line and locate arguments (if any), keeping count of the number
398 * of arguments and their locations. Look up and call the corresponding cli
399 * function if one is found and pass it the argv array.
400 *
401 * Returns: 0 on success: the input line contained at least a function name and
402 * that function exists and was called.
403 * 1 on lookup failure: there is no corresponding function for the
404 * input line.
405 * 2 on invalid syntax: the arguments list couldn't be parsed
406 */
handle_input(char * inbuf)407 static int handle_input(char *inbuf)
408 {
409 struct {
410 unsigned inArg: 1;
411 unsigned inQuote: 1;
412 unsigned done: 1;
413 unsigned limQ : 1;
414 unsigned isD : 2;
415 } stat;
416 static char *argv[16];
417 int argc = 0;
418 int i = 0;
419 const struct cli_command *command = NULL;
420 const char *p;
421
422 os_memset((void *)&argv, 0, sizeof(argv));
423 os_memset(&stat, 0, sizeof(stat));
424
425 if (inbuf[i] == '\0')
426 return 0;
427
428 do {
429 switch (inbuf[i]) {
430 case '\0':
431 if (((argc == 0)||(stat.isD == 1))||(stat.limQ)||(stat.inQuote))
432 return 2;
433 stat.done = 1;
434 break;
435
436 case '"':
437 if (i > 0 && inbuf[i - 1] == '\\' && stat.inArg) {
438 os_memcpy(&inbuf[i - 1], &inbuf[i],
439 os_strlen(&inbuf[i]) + 1);
440 --i;
441 break;
442 }
443 if (!stat.inQuote && stat.inArg)
444 break;
445 if (stat.inQuote && !stat.inArg)
446 return 2;
447
448 if (!stat.inQuote && !stat.inArg) {
449 stat.inArg = 1;
450 stat.inQuote = 1;
451 argc++;
452 argv[argc - 1] = &inbuf[i + 1];
453 } else if (stat.inQuote && stat.inArg) {
454 stat.inArg = 0;
455 stat.inQuote = 0;
456 inbuf[i] = '\0';
457 }
458 break;
459
460 case ' ':
461 if (i > 0 && inbuf[i - 1] == '\\' && stat.inArg) {
462 os_memcpy(&inbuf[i - 1], &inbuf[i],
463 os_strlen(&inbuf[i]) + 1);
464 --i;
465 break;
466 }
467 if (!stat.inQuote && stat.inArg) {
468 stat.inArg = 0;
469 inbuf[i] = '\0';
470 }
471 break;
472
473 case '=':
474 if(argc == 1) {
475 inbuf[i] = '\0';
476 stat.inArg = 0;
477 stat.isD = 1;
478 }
479 else if(argc == 0){
480 os_printf("The data does not conform to the regulations %d\r\n",__LINE__);
481 return 2;
482 }
483 break;
484
485 case ',':
486 if((stat.isD == 1)&&(argc == 1)) ///=,
487 {
488 os_printf("The data does not conform to the regulations %d\r\n",__LINE__);
489 return 2;
490 }
491 if(!stat.inQuote && stat.inArg) {
492 stat.inArg = 0;
493 inbuf[i] = '\0';
494 stat.limQ = 1;
495 }
496 break;
497
498 default:
499 if (!stat.inArg) {
500 stat.inArg = 1;
501 argc++;
502 argv[argc - 1] = &inbuf[i];
503 stat.limQ = 0;
504 if(stat.isD == 1) {
505 stat.isD = 2;
506 }
507 }
508 break;
509 }
510 } while (!stat.done && ++i < INBUF_SIZE);
511
512 if (stat.inQuote)
513 return 2;
514
515 if (argc < 1)
516 return 0;
517
518 if (!pCli->echo_disabled)
519 os_printf("\r\n");
520
521 /*
522 * Some comamands can allow extensions like foo.a, foo.b and hence
523 * compare commands before first dot.
524 */
525 i = ((p = os_strchr(argv[0], '.')) == NULL) ? 0 :
526 (p - argv[0]);
527 command = lookup_command(argv[0], i);
528 if (command == NULL)
529 return 1;
530
531 os_memset(pCli->outbuf, 0, OUTBUF_SIZE);
532 cli_putstr("\r\n");
533
534 #if CONFIG_STA_PS
535 /*if cmd,exit dtim ps*/
536 if (os_strncmp(command->name, "ps", 2)) {
537 }
538 #endif
539
540 #if CFG_CLI_DEBUG
541 s_running_status |= CLI_COMMAND_IS_RUNNING;
542 command->function(pCli->outbuf, OUTBUF_SIZE, argc, argv);
543 s_running_status &= ~CLI_COMMAND_IS_RUNNING;
544 #else
545 command->function(pCli->outbuf, OUTBUF_SIZE, argc, argv);
546 #endif
547 cli_putstr(pCli->outbuf);
548 return 0;
549 }
550
551 /* Perform basic tab-completion on the input buffer by string-matching the
552 * current input line against the cli functions table. The current input line
553 * is assumed to be NULL-terminated. */
tab_complete(char * inbuf,unsigned int * bp)554 static void tab_complete(char *inbuf, unsigned int *bp)
555 {
556 int i, n, m;
557 const char *fm = NULL;
558
559 os_printf("\r\n");
560
561 /* show matching commands */
562 for (i = 0, n = 0, m = 0; i < MAX_COMMANDS && n < pCli->num_commands;
563 i++) {
564 if (pCli->commands[i]->name != NULL) {
565 if (!os_strncmp(inbuf, pCli->commands[i]->name, *bp)) {
566 m++;
567 if (m == 1)
568 fm = pCli->commands[i]->name;
569 else if (m == 2)
570 os_printf("%s %s ", fm,
571 pCli->commands[i]->name);
572 else
573 os_printf("%s ",
574 pCli->commands[i]->name);
575 }
576 n++;
577 }
578 }
579
580 /* there's only one match, so complete the line */
581 if (m == 1 && fm) {
582 n = os_strlen(fm) - *bp;
583 if (*bp + n < INBUF_SIZE) {
584 os_memcpy(inbuf + *bp, fm + *bp, n);
585 *bp += n;
586 inbuf[(*bp)++] = ' ';
587 inbuf[*bp] = '\0';
588 }
589 }
590
591 /* just redraw input line */
592 os_printf("%s%s", PROMPT, inbuf);
593 }
594 /* Get an input line.
595 *
596 * Returns: 1 if there is input, 0 if the line should be ignored. */
get_input(char * inbuf,unsigned int * bp)597 static int get_input(char *inbuf, unsigned int *bp)
598 {
599 if (inbuf == NULL) {
600 os_printf("inbuf_null\r\n");
601 return 0;
602 }
603
604 while (cli_getchar(&inbuf[*bp]) == 1) {
605 #if CONFIG_BKREG
606 if ((0x01U == (UINT8)inbuf[*bp]) && (*bp == 0)) {
607 (*bp)++;
608 continue;
609 } else if ((0xe0U == (UINT8)inbuf[*bp]) && (*bp == 1)) {
610 (*bp)++;
611 continue;
612 } else if ((0xfcU == (UINT8)inbuf[*bp]) && (*bp == 2)) {
613 (*bp)++;
614 continue;
615 } else {
616 if ((0x01U == (UINT8)inbuf[0])
617 && (0xe0U == (UINT8)inbuf[1])
618 && (0xfcU == (UINT8)inbuf[2])
619 && (*bp == 3)) {
620 uint8_t ch = inbuf[*bp];
621 uint8_t left = ch, len = 4 + (uint8_t)ch;
622 inbuf[*bp] = ch;
623 (*bp)++;
624
625 if (ch >= INBUF_SIZE) {
626 os_printf("Error: input buffer overflow\r\n");
627 os_printf(PROMPT);
628 *bp = 0;
629 return 0;
630 }
631
632 while (left--) {
633 if (0 == cli_getchar((char *)&ch))
634 break;
635
636 inbuf[*bp] = ch;
637 (*bp)++;
638 }
639
640 bkreg_run_command(inbuf, len);
641 os_memset(inbuf, 0, len);
642 *bp = 0;
643 continue;
644 }
645 }
646 #endif
647 if (inbuf[*bp] == RET_CHAR)
648 continue;
649 if (inbuf[*bp] == END_CHAR) { /* end of input line */
650 inbuf[*bp] = '\0';
651 *bp = 0;
652 return 1;
653 }
654
655 if ((inbuf[*bp] == 0x08) || /* backspace */
656 (inbuf[*bp] == 0x7f)) { /* DEL */
657 if (*bp > 0) {
658 (*bp)--;
659 if (!pCli->echo_disabled)
660 os_printf("%c %c", 0x08, 0x08);
661 }
662 continue;
663 }
664
665 if (inbuf[*bp] == '\t') {
666 inbuf[*bp] = '\0';
667 tab_complete(inbuf, bp);
668 continue;
669 }
670
671 if (!pCli->echo_disabled)
672 os_printf("%c", inbuf[*bp]);
673
674 (*bp)++;
675 if (*bp >= INBUF_SIZE) {
676 os_printf("Error: input buffer overflow\r\n");
677 os_printf(PROMPT);
678 *bp = 0;
679 return 0;
680 }
681 }
682
683 return 0;
684 }
685
686 /* Print out a bad command string, including a hex
687 * representation of non-printable characters.
688 * Non-printable characters show as "\0xXX".
689 */
print_bad_command(char * cmd_string)690 static void print_bad_command(char *cmd_string)
691 {
692 if (cmd_string != NULL) {
693 char *c = cmd_string;
694 os_printf("command '");
695 while (*c != '\0') {
696 if (is_print(*c))
697 os_printf("%c", *c);
698 else
699 os_printf("\\0x%x", *c);
700 ++c;
701 }
702 os_printf("' not found\r\n");
703 }
704 }
705
706 /* Main CLI processing thread
707 *
708 * Waits to receive a command buffer pointer from an input collector, and
709 * then processes. Note that it must cleanup the buffer when done with it.
710 *
711 * Input collectors handle their own lexical analysis and must pass complete
712 * command lines to CLI.
713 */
714 void icu_struct_dump(void);
715
cli_main(uint32_t data)716 static void cli_main(uint32_t data)
717 {
718
719 char *msg = NULL;
720 int ret;
721
722 #if CONFIG_RF_OTA_TEST
723 demo_sta_app_init("CMW-AP", "12345678");
724 #endif /* CONFIG_RF_OTA_TEST*/
725
726 bk_uart_enable_rx_interrupt(CONFIG_UART_PRINT_PORT);
727
728 while (1) {
729
730 if (get_input(pCli->inbuf, &pCli->bp)) {
731 msg = pCli->inbuf;
732
733 if (os_strcmp(msg, EXIT_MSG) == 0)
734 break;
735
736 ret = handle_input(msg);
737 if (ret == 1)
738 print_bad_command(msg);
739 else if (ret == 2)
740 os_printf("syntax error\r\n");
741
742 os_printf(PROMPT);
743 }
744 }
745
746 os_printf("CLI exited\r\n");
747 os_free(pCli);
748 pCli = NULL;
749
750 rtos_delete_thread(NULL);
751 }
752
753 #endif // #if (!CONFIG_SHELL_ASYNCLOG)
754
755 void help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
756 void cli_sort_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv);
757
758 extern const struct cli_command * cli_debug_cmd_table(int *num);
759
cli_debug_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)760 void cli_debug_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
761 {
762 int i, tbl_num = 0;
763 const struct cli_command *cmd_tbl;
764
765 if (argc < 2)
766 {
767 if(pcWriteBuffer != NULL)
768 strcpy(&pcWriteBuffer[0], "argc < 2\r\n");
769 return;
770 }
771
772 cmd_tbl = cli_debug_cmd_table(&tbl_num);
773
774 i = lookup_cmd_table(cmd_tbl, tbl_num, argv[1], 0);
775
776 if (i < 0)
777 {
778 if(pcWriteBuffer != NULL)
779 sprintf(&pcWriteBuffer[0], "cmd: %s NOT found.\r\n", argv[1]);
780 return;
781 }
782
783 cmd_tbl[i].function(pcWriteBuffer, xWriteBufferLen , argc - 1, &argv[1]);
784
785 }
786
log_setting_cmd(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)787 static void log_setting_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
788 {
789 int echo_level;
790 int level;
791 int sync_lvl;
792
793 if (argc > 1)
794 {
795 echo_level = strtoul(argv[1], NULL, 0);
796
797 #if (CONFIG_SHELL_ASYNCLOG)
798 shell_echo_set(echo_level);
799 #else
800 if(echo_level)
801 echo_level = 0;
802 else
803 echo_level = 1;
804 pCli->echo_disabled = echo_level;
805 #endif //#if (CONFIG_SHELL_ASYNCLOG)
806 }
807
808 #if (CONFIG_SHELL_ASYNCLOG)
809 if (argc > 2)
810 {
811 level = strtoul(argv[2], NULL, 0);
812 shell_set_log_level(level);
813 }
814 if (argc > 3)
815 {
816 sync_lvl = strtoul(argv[3], NULL, 0);
817 bk_set_printf_sync(sync_lvl);
818 }
819 #endif
820
821 #if (CONFIG_SHELL_ASYNCLOG)
822 echo_level = shell_echo_get();
823 level = shell_get_log_level();
824 sync_lvl = bk_get_printf_sync();
825
826 sprintf(pcWriteBuffer, "log: echo %d, level %d, sync %d.\r\n", echo_level, level, sync_lvl);
827 #else
828
829 sprintf(pcWriteBuffer,"log: echo %d.\r\n", pCli->echo_disabled ? 0 : 1);
830 #endif //#if (CONFIG_SHELL_ASYNCLOG)
831
832 return;
833
834 (void)level;
835 (void)sync_lvl;
836
837 }
838
839 #if (CONFIG_SHELL_ASYNCLOG && CONFIG_MASTER_CORE)
840 #if 0
841 #define CPU1_CMD_BUF_SIZE 128
842 static char cpu1_cmd_buf[CPU1_CMD_BUF_SIZE];
843 void cli_cpu1_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
844 {
845 int i;
846 int buf_len = 0;
847 int str_len = 0;
848
849 for(i = 1; i < argc; i++)
850 {
851 str_len = strlen(argv[i]);
852 if ((buf_len + str_len + 3) < CPU1_CMD_BUF_SIZE)
853 {
854 os_memcpy(&cpu1_cmd_buf[buf_len], argv[i], str_len);
855 buf_len += str_len;
856 cpu1_cmd_buf[buf_len++] = ' ';
857 }
858 else
859 break;
860 }
861
862 cpu1_cmd_buf[buf_len++] = '\r';
863 cpu1_cmd_buf[buf_len++] = '\n';
864
865 shell_cmd_forward(cpu1_cmd_buf, buf_len);
866 }
867 #endif
868
869 /* it is a new implementation of the cli_cpu1_command, combine cpu1 cmd & paramters into argv[0] buffer. */
cli_cpu1_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)870 void cli_cpu1_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
871 {
872 int i, j;
873 int buf_len = 0;
874 int str_len = 0;
875
876 for(i = 1; i < argc; i++)
877 {
878 str_len = strlen(argv[i]);
879 for(j = 0; j < str_len; j++)
880 {
881 if(argv[i][j] == ' ')
882 {
883 break;
884 }
885 }
886
887 if(j < str_len) /* contains ' ' in string. */
888 {
889 argv[0][buf_len++] = '"';
890 for(j = 0; j < str_len; j++)
891 {
892 if(argv[i][j] == '"')
893 {
894 argv[0][buf_len++] = '\\';
895 }
896 argv[0][buf_len++] = argv[i][j];
897 }
898 argv[0][buf_len++] = '"';
899 }
900 else
901 {
902 memcpy(&argv[0][buf_len], argv[i], str_len);
903 buf_len += str_len;
904 argv[0][buf_len++] = ' ';
905 }
906 }
907
908 argv[0][buf_len++] = '\r';
909 argv[0][buf_len++] = '\n';
910
911 shell_cmd_forward(argv[0], buf_len);
912 }
913
914 #endif
915
916 #if (CONFIG_SHELL_ASYNCLOG)
cli_log_statist(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)917 void cli_log_statist(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
918 {
919 int data_cnt, i, buf_len = 0;
920 u32 log_statist[5];
921 data_cnt = shell_get_log_statist(log_statist, ARRAY_SIZE(log_statist));
922
923 if(data_cnt == 0)
924 {
925 strcpy(pcWriteBuffer, "\r\n Nothing \r\n");
926 return;
927 }
928
929 buf_len = sprintf(&pcWriteBuffer[0], "\r\nlog overflow: %d.", log_statist[0]);
930 buf_len += sprintf(&pcWriteBuffer[buf_len], "\r\nlog out count: %d.", log_statist[1]);
931
932 for(i = 2; i < data_cnt; i++)
933 {
934 buf_len += sprintf(&pcWriteBuffer[buf_len], "\r\nBuffer[%d] run out count: %d.", i - 2, log_statist[i]);
935 }
936
937 return;
938
939 }
940
cli_log_disable(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)941 static void cli_log_disable(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
942 {
943 if (argc < 3)
944 {
945 int i = 0, buf_len = 0;
946 char * mod_name;
947
948 buf_len = sprintf(&pcWriteBuffer[0], "Usage: modlog tag_name on/off\r\n");
949
950 while(1)
951 {
952 mod_name = bk_get_disable_mod(&i);
953
954 if(mod_name != NULL)
955 {
956 if(buf_len == 0)
957 {
958 buf_len = sprintf(&pcWriteBuffer[0], "disabled mod list:\r\n%s\r\n", mod_name);
959 }
960 else
961 {
962 buf_len += sprintf(&pcWriteBuffer[buf_len], "%s\r\n", mod_name);
963 }
964 }
965 else
966 break;
967 }
968
969 return;
970 }
971
972 if (!os_strcasecmp(argv[2], "on"))
973 {
974 bk_disable_mod_printf(argv[1], 0);
975 }
976 else if (!os_strcasecmp(argv[2], "off"))
977 {
978 bk_disable_mod_printf(argv[1], 1);
979 }
980 }
981 #endif
982
983 #if CONFIG_BKREG
984 #define BKCMD_RXSENS_R 'r'
985 #define BKCMD_RXSENS_X 'x'
986 #define BKCMD_RXSENS_s 's'
987
988 #define BKCMD_TXEVM_T 't'
989 #define BKCMD_TXEVM_X 'x'
990 #define BKCMD_TXEVM_E 'e'
991
bkreg_cmd_handle_input(char * inbuf,int len)992 void bkreg_cmd_handle_input(char *inbuf, int len)
993 {
994 if (((char)BKREG_MAGIC_WORD0 == inbuf[0])
995 && ((char)BKREG_MAGIC_WORD1 == inbuf[1])
996 && ((char)BKREG_MAGIC_WORD2 == inbuf[2])) {
997 if (cli_getchars(inbuf, len)) {
998 bkreg_run_command(inbuf, len);
999 os_memset(inbuf, 0, len);
1000 }
1001 } else if ((((char)BKCMD_RXSENS_R == inbuf[0])
1002 && ((char)BKCMD_RXSENS_X == inbuf[1])
1003 && ((char)BKCMD_RXSENS_s == inbuf[2]))
1004 || (((char)BKCMD_TXEVM_T == inbuf[0])
1005 && ((char)BKCMD_TXEVM_X == inbuf[1])
1006 && ((char)BKCMD_TXEVM_E == inbuf[2]))) {
1007 if (cli_getchars(inbuf, len)) {
1008 #if (CONFIG_SHELL_ASYNCLOG)
1009 handle_shell_input(inbuf, len, 0, 0);
1010 #else //#if (CONFIG_SHELL_ASYNCLOG)
1011 handle_input(inbuf);
1012 #endif // #if (CONFIG_SHELL_ASYNCLOG)
1013 os_memset(inbuf, 0, len);
1014 }
1015 }
1016
1017 }
1018 #endif
1019
1020 static const struct cli_command built_ins[] = {
1021 {"help", NULL, help_command},
1022 {"log", "log [echo(0,1)] [level(0~5)] [sync(0,1)]", log_setting_cmd},
1023 // {"sort", NULL, cli_sort_command},
1024 {"debug", "debug cmd [param] (ex:debug help)", cli_debug_command},
1025 #if (CONFIG_SHELL_ASYNCLOG && CONFIG_MASTER_CORE)
1026 {"cpu1", "cpu1 cmd (ex:cpu1 help)", cli_cpu1_command},
1027 #endif
1028 #if (CONFIG_SHELL_ASYNCLOG)
1029 {"loginfo", "log statistics.", cli_log_statist},
1030 {"modlog", "modlog tag_name on/off", cli_log_disable},
1031 #endif
1032 };
1033
_cli_name_cmp(const void * a,const void * b)1034 static int _cli_name_cmp(const void *a, const void *b)
1035 {
1036 struct cli_command *cli0, *cli1;
1037
1038 cli0 = *(struct cli_command **)a;
1039 cli1 = *(struct cli_command **)b;
1040
1041 if ((NULL == a) || (NULL == b))
1042 return 0;
1043
1044 return os_strcmp(cli0->name, cli1->name);
1045 }
1046
cli_sort_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)1047 void cli_sort_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
1048 {
1049 uint32_t build_in_count;
1050 GLOBAL_INT_DECLARATION();
1051
1052 build_in_count = sizeof(built_ins) / sizeof(struct cli_command);
1053
1054 os_printf("cmd_count:%d, built_in_count:%d\r\n", pCli->num_commands, build_in_count);
1055
1056 GLOBAL_INT_DISABLE();
1057 qsort(&pCli->commands[build_in_count], pCli->num_commands - build_in_count, sizeof(struct cli_command *), _cli_name_cmp);
1058 GLOBAL_INT_RESTORE();
1059 }
1060
1061 /* Built-in "help" command: prints all registered commands and their help
1062 * text string, if any. */
help_command(char * pcWriteBuffer,int xWriteBufferLen,int argc,char ** argv)1063 void help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv)
1064 {
1065 int i, n;
1066 uint32_t build_in_count = sizeof(built_ins) / sizeof(struct cli_command);
1067
1068 #if (DEBUG)
1069 build_in_count++; //For command: micodebug
1070 #endif
1071
1072 os_printf("====Build-in Commands====\r\n");
1073 for (i = 0, n = 0; i < MAX_COMMANDS && n < pCli->num_commands; i++) {
1074 if (pCli->commands[i]->name) {
1075 if (pCli->commands[i]->help)
1076 os_printf("%s: %s\r\n", pCli->commands[i]->name,
1077 pCli->commands[i]->help ?
1078 pCli->commands[i]->help : "");
1079 else
1080 os_printf("%s\r\n", pCli->commands[i]->name);
1081
1082 n++;
1083 if (n == build_in_count)
1084 os_printf("\r\n====User Commands====\r\n");
1085
1086 if((n & 0x0f) == 0)
1087 rtos_delay_milliseconds(50);
1088 }
1089 }
1090 }
1091
cli_register_command(const struct cli_command * command)1092 int cli_register_command(const struct cli_command *command)
1093 {
1094 int i;
1095 if (!command->name || !command->function)
1096 return 1;
1097
1098 if (pCli->num_commands < MAX_COMMANDS) {
1099 /* Check if the command has already been registered.
1100 * Return 0, if it has been registered.
1101 */
1102 for (i = 0; i < pCli->num_commands; i++) {
1103 if (pCli->commands[i] == command)
1104 return 0;
1105 }
1106 pCli->commands[pCli->num_commands++] = command;
1107 return 0;
1108 }
1109
1110 return 1;
1111 }
1112
cli_unregister_command(const struct cli_command * command)1113 int cli_unregister_command(const struct cli_command *command)
1114 {
1115 int i;
1116 if (!command->name || !command->function)
1117 return 1;
1118
1119 for (i = 0; i < pCli->num_commands; i++) {
1120 if (pCli->commands[i] == command) {
1121 pCli->num_commands--;
1122 int remaining_cmds = pCli->num_commands - i;
1123 if (remaining_cmds > 0) {
1124 os_memmove(&pCli->commands[i], &pCli->commands[i + 1],
1125 (remaining_cmds *
1126 sizeof(struct cli_command *)));
1127 }
1128 pCli->commands[pCli->num_commands] = NULL;
1129 return 0;
1130 }
1131 }
1132
1133 return 1;
1134 }
1135
1136
cli_register_commands(const struct cli_command * commands,int num_commands)1137 int cli_register_commands(const struct cli_command *commands, int num_commands)
1138 {
1139 int i;
1140 for (i = 0; i < num_commands; i++)
1141 if (cli_register_command(commands++))
1142 return 1;
1143 return 0;
1144 }
1145
cli_unregister_commands(const struct cli_command * commands,int num_commands)1146 int cli_unregister_commands(const struct cli_command *commands,
1147 int num_commands)
1148 {
1149 int i;
1150 for (i = 0; i < num_commands; i++)
1151 if (cli_unregister_command(commands++))
1152 return 1;
1153
1154 return 0;
1155 }
1156
1157 /* ========= CLI input&output APIs ============ */
cli_printf(const char * msg,...)1158 int cli_printf(const char *msg, ...)
1159 {
1160 va_list ap;
1161 char *pos, message[256];
1162 int sz;
1163 int nMessageLen = 0;
1164
1165 os_memset(message, 0, 256);
1166 pos = message;
1167
1168 sz = 0;
1169 va_start(ap, msg);
1170 nMessageLen = vsnprintf(pos, 256 - sz, msg, ap);
1171 va_end(ap);
1172
1173 if (nMessageLen <= 0) return 0;
1174
1175 cli_putstr((const char *)message);
1176 return 0;
1177 }
1178
cli_putstr(const char * msg)1179 int cli_putstr(const char *msg)
1180 {
1181 if (msg[0] != 0)
1182 uart_write_string(CLI_UART, msg);
1183 return 0;
1184 }
1185
cli_getchar(char * inbuf)1186 int cli_getchar(char *inbuf)
1187 {
1188 if (bk_uart_read_bytes(CLI_UART, inbuf, 1, CLI_GETCHAR_TIMEOUT) > 0)
1189 return 1;
1190 else
1191 return 0;
1192 }
1193
cli_getchars(char * inbuf,int len)1194 int cli_getchars(char *inbuf, int len)
1195 {
1196 if (bk_uart_read_bytes(CLI_UART, inbuf, len, CLI_GETCHAR_TIMEOUT) > 0)
1197 return 1;
1198 else
1199 return 0;
1200 }
1201
cli_getchars_prefetch(char * inbuf,int len)1202 int cli_getchars_prefetch(char *inbuf, int len)
1203 {
1204 return 0;
1205 }
1206
cli_get_all_chars_len(void)1207 int cli_get_all_chars_len(void)
1208 {
1209 return uart_get_length_in_buffer(CLI_UART);
1210 }
1211
1212 static const struct cli_command user_clis[] = {
1213 };
1214
1215 beken_thread_t cli_thread_handle = NULL;
bk_cli_init(void)1216 int bk_cli_init(void)
1217 {
1218 int ret;
1219
1220 pCli = (struct cli_st *)os_malloc(sizeof(struct cli_st));
1221 if (pCli == NULL)
1222 return kNoMemoryErr;
1223
1224 os_memset((void *)pCli, 0, sizeof(struct cli_st));
1225
1226 if (cli_register_commands(&built_ins[0],
1227 sizeof(built_ins) / sizeof(struct cli_command)))
1228 goto init_general_err;
1229
1230 if (cli_register_commands(user_clis, sizeof(user_clis) / sizeof(struct cli_command)))
1231 goto init_general_err;
1232
1233 #if (CLI_CFG_WIFI == 1)
1234 cli_wifi_init();
1235 #endif
1236
1237 #if (CLI_CFG_NETIF == 1)
1238 cli_netif_init();
1239 #endif
1240
1241 #if (CLI_CFG_BLE == 1)
1242 cli_ble_init();
1243 #endif
1244
1245 #if (CLI_CFG_MISC == 1)
1246 cli_misc_init();
1247 #endif
1248
1249 #if (CLI_CFG_MEM == 1)
1250 cli_mem_init();
1251 #endif
1252
1253 #if (CLI_CFG_AIRKISS == 1)
1254 cli_airkiss_init();
1255 #endif
1256
1257 #if (CLI_CFG_PHY == 1)
1258 cli_phy_init();
1259 #endif
1260
1261 #if (CLI_CFG_IPERF == 1)
1262 cli_phy_init();
1263 #endif
1264
1265 #if (CLI_CFG_TIMER == 1)
1266 cli_timer_init();
1267 #endif
1268
1269 #if (CLI_CFG_WDT == 1)
1270 cli_wdt_init();
1271 #endif
1272
1273 #if (CLI_CFG_TRNG == 1)
1274 cli_trng_init();
1275 #endif
1276
1277 #if (CLI_CFG_EFUSE == 1)
1278 cli_efuse_init();
1279 #endif
1280
1281 #if (CLI_CFG_DMA == 1)
1282 cli_dma_init();
1283 #endif
1284
1285 #if (CLI_CFG_GPIO == 1)
1286 cli_gpio_init();
1287 #endif
1288
1289 #if (CLI_CFG_OS == 1)
1290 cli_os_init();
1291 #endif
1292
1293 #if (CLI_CFG_OTA == 1)
1294 cli_ota_init();
1295 #endif
1296
1297 #if (CLI_CFG_FLASH == 1)
1298 cli_flash_init();
1299 #endif
1300
1301 #if (CLI_CFG_FLASH == 1)
1302 cli_flash_test_init();
1303 #endif
1304
1305 #if (CLI_CFG_SDIO_HOST == 1)
1306 cli_sdio_host_init();
1307 #endif
1308
1309 #if (CLI_CFG_KEYVALUE == 1)
1310 cli_keyVaule_init();
1311 #endif
1312
1313 #if (CLI_CFG_MATTER == 1)
1314 cli_matter_init();
1315 #endif
1316
1317 #if (CLI_CFG_UART == 1)
1318 cli_uart_init();
1319 #endif
1320
1321 #if (CLI_CFG_SPI == 1)
1322 cli_spi_init();
1323 #endif
1324
1325 #if (CLI_CFG_QSPI == 1)
1326 cli_qspi_init();
1327 #endif
1328
1329 #if (CONFIG_AON_RTC_TEST == 1)
1330 cli_aon_rtc_init();
1331 #endif
1332
1333 #if (CLI_CFG_I2C == 1)
1334 cli_i2c_init();
1335 #endif
1336
1337 #if (CLI_CFG_JPEGENC == 1)
1338 cli_jpeg_init();
1339 #endif
1340
1341 #if (CLI_CFG_ADC == 1)
1342 cli_adc_init();
1343 #endif
1344
1345 #if (CLI_CFG_SD == 1)
1346 cli_sd_init();
1347 #endif
1348
1349 #if (CLI_FATFS == 1)
1350 cli_fatfs_init();
1351 #endif
1352
1353 #if (CLI_CFG_TEMP_DETECT == 1)
1354 cli_temp_detect_init();
1355 #endif
1356
1357 #if (CLI_CFG_SECURITY == 1)
1358 cli_security_init();
1359 #endif
1360
1361 #if (CLI_CFG_MICO == 1)
1362 cli_mico_init();
1363 #endif
1364
1365 #if (CLI_CFG_EVENT == 1)
1366 cli_event_init();
1367 #endif
1368
1369 #if (CLI_CFG_PWR == 1)
1370 cli_pwr_init();
1371 #endif
1372
1373 #if (CLI_CFG_REG == 1)
1374 cli_reg_init();
1375 #endif
1376
1377 #if CONFIG_CAMERA
1378 if (video_demo_register_cmd())
1379 goto init_general_err;
1380 #endif
1381 #if (CONFIG_SOC_BK7271)
1382 #if CONFIG_BT
1383 bk7271_ble_cli_init();
1384 #endif
1385 #if CONFIG_USB_HOST
1386 bk7271_dsp_cli_init();
1387 #endif
1388 #endif
1389
1390 #if (CONFIG_SOC_BK7256XX)
1391 #if CONFIG_USB_HOST
1392 usb_cli_init();
1393 #endif
1394 #endif
1395
1396 #if (CLI_CFG_PWM == 1)
1397 cli_pwm_init();
1398 #endif
1399
1400 #if (CLI_CFG_IPERF == 1)
1401 cli_iperf_init();
1402 #endif
1403
1404 #if CONFIG_LWIP
1405 //cli_lwip_init();
1406 #endif
1407
1408 #if (CLI_CFG_EXCEPTION == 1)
1409 cli_exception_init();
1410 #endif
1411
1412 #if (CLI_CFG_ICU == 1)
1413 cli_icu_init();
1414 #endif
1415
1416 #if (CLI_CFG_VAULT == 1)
1417 cli_vault_init();
1418 #endif
1419
1420 #if (CLI_CFG_AUD == 1)
1421 cli_aud_init();
1422 #endif
1423
1424 #if (CLI_CFG_AUD_INTF == 1)
1425 cli_aud_intf_init();
1426 #endif
1427
1428 #if (CLI_CFG_AUD_CP0 == 1)
1429 cli_aud_cp0_init();
1430 #endif
1431
1432 #if (CLI_CFG_FFT == 1)
1433 cli_fft_init();
1434 #endif
1435
1436 #if (CLI_CFG_SBC == 1)
1437 cli_sbc_init();
1438 #endif
1439
1440 #if (CLI_CFG_I2S == 1)
1441 cli_i2s_init();
1442 #endif
1443
1444 #if (CONFIG_TOUCH)
1445 cli_touch_init();
1446 #endif
1447
1448 #if (CLI_CFG_LCD == 1)
1449 cli_lcd_init();
1450 #endif
1451
1452 #if (CLI_CFG_DMA2D == 1)
1453 cli_dma2d_init();
1454 #endif
1455
1456 #if (CLI_CFG_CALENDAR == 1)
1457 cli_calendar_init();
1458 #endif
1459
1460 #if (CLI_CFG_UVC == 1)
1461 cli_uvc_init();
1462 #endif
1463
1464 #if (CONFIG_AT_CMD)
1465 cli_at_init();
1466 #endif
1467
1468 #if (CLI_CFG_JPEGDEC == 1)
1469 cli_jpegdec_init();
1470 #endif
1471
1472 #if (CLI_CFG_AEC == 1)
1473 cli_aec_init();
1474 #endif
1475
1476 #if (CLI_CFG_G711 == 1)
1477 cli_g711_init();
1478 #endif
1479
1480 #if (CLI_CFG_MP3 == 1)
1481 cli_mp3_init();
1482 #endif
1483
1484 #if (CLI_CFG_DVP == 1)
1485 cli_dvp_init();
1486 #endif
1487
1488 #if (CONFIG_DOORBELL == 1)
1489 //#if (CONFIG_DUAL_CORE)
1490 cli_doorbell_init();
1491 //#endif
1492 #endif
1493
1494 #if (CONFIG_MEDIA == 1)
1495 media_cli_init();
1496 #endif
1497
1498 #if (CLI_CFG_PSRAM)
1499 cli_psram_init();
1500 #endif
1501
1502
1503 /* sort cmds after registered all cmds. */
1504 cli_sort_command(NULL, 0, 0, NULL);
1505
1506 #if CONFIG_SHELL_ASYNCLOG
1507 #if CONFIG_ATE_TEST
1508 ret = rtos_create_thread(&cli_thread_handle,
1509 SHELL_TASK_PRIORITY,
1510 "cli",
1511 (beken_thread_function_t)cli_ate_main /*cli_main*/,
1512 4096,
1513 0);
1514 #else
1515 ret = rtos_create_thread(&cli_thread_handle,
1516 SHELL_TASK_PRIORITY,
1517 "cli",
1518 (beken_thread_function_t)shell_task /*cli_main*/,
1519 4096,
1520 0);
1521 #endif
1522 #else // #if CONFIG_SHELL_ASYNCLOG
1523 ret = rtos_create_thread(&cli_thread_handle,
1524 BEKEN_DEFAULT_WORKER_PRIORITY,
1525 "cli",
1526 (beken_thread_function_t)cli_main,
1527 4096,
1528 0);
1529 #endif // #if CONFIG_SHELL_ASYNCLOG
1530 if (ret != kNoErr) {
1531 os_printf("Error: Failed to create cli thread: %d\r\n",
1532 ret);
1533 goto init_general_err;
1534 }
1535
1536 pCli->initialized = 1;
1537 #if (!CONFIG_SHELL_ASYNCLOG)
1538 pCli->echo_disabled = 0;
1539 #endif
1540
1541 #if (CONFIG_SLAVE_CORE && CONFIG_MEDIA)
1542 ret = common_mb_init();
1543 if (ret != kNoErr) {
1544 os_printf("Error: Failed to create common_mb thread: %d\r\n", ret);
1545 }
1546 #endif
1547
1548 return kNoErr;
1549
1550 init_general_err:
1551 if (pCli) {
1552 os_free(pCli);
1553 pCli = NULL;
1554 }
1555
1556 return kGeneralErr;
1557 }
1558
1559 #if CFG_CLI_DEBUG
cli_show_running_command(void)1560 void cli_show_running_command(void)
1561 {
1562 if (s_running_command_index < MAX_COMMANDS) {
1563 const struct cli_command *cmd = pCli->commands[s_running_command_index];
1564
1565 CLI_LOGI("last cli command[%d]: %s(%s)\n", s_running_command_index, cmd->name,
1566 (s_running_status & CLI_COMMAND_IS_RUNNING) ? "running" : "stopped");
1567 rtos_dump_task_list();
1568 rtos_dump_backtrace();
1569 } else
1570 CLI_LOGI("no command running\n");
1571 }
1572 #endif
1573
1574 // eof
1575
1576