• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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