• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
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 #include <stdint.h>
16 #include <string.h>
17 #include <stdbool.h>
18 #include "command.h"
19 #include "console.h"
20 #include "lnx_list.h"
21 #if PLF_PMIC
22 #include "pmic_api.h"
23 #if (PLF_PMIC_VER_LITE && PLF_EXT_CS1000)
24 #include "cs1000_psi_api.h"
25 #endif
26 #endif
27 
28 #if CONSOLE_GLOBAL_DEBUG_MODE
29 #define CMDISR_SUPER_STR    "#6*"
30 #endif /* CONSOLE_GLOBAL_DEBUG_MODE */
31 
32 #define IS_PMIC_SRAM_VALID(addr)    (((unsigned int)(addr) >> 24) == (CS_PMIC_RAM_BASE >> 24)) // 0x01000000 ~ 0x01FFFFFF
33 #define IS_PMIC_REG_VALID(addr)     (((unsigned int)(addr) >> 20) == (CS_PMIC_REG_BASE >> 20)) // 0x50000000 ~ 0x500FFFFF
34 
35 #define CONFIG_SYS_CBSIZE   64
36 #define CONFIG_SYS_PROMPT   "cs> "
37 #define CONFIG_SYS_MAXARGS  16
38 #define CONFIG_LINE_BYTES   16
39 
40 #define CONFIG_CMDTBL_SIZE  36
41 #define CONFIG_CMDBUF_SIZE  4
42 
43 typedef struct {
44     struct list_head entry;
45     char buffer[CONFIG_SYS_CBSIZE];
46 } cmd_buf_node_t;
47 
48 static const char erase_seq[] = "\b \b";        /* erase sequence       */
49 static const char   tab_seq[] = "    ";         /* used to expand TABs  */
50 static char console_buffer[CONFIG_SYS_CBSIZE];  /* console I/O buffer   */
51 
52 static cmd_buf_node_t cmd_buf_tab[CONFIG_CMDBUF_SIZE];
53 static struct list_head cmd_free_list;
54 static struct list_head cmd_pend_list;
55 
56 static cmd_tbl_t cmd_tbl_list[CONFIG_CMDTBL_SIZE] = { {0,}, };
57 static unsigned int cmd_tbl_curidx = 0;
58 
59 #define isblank(c)      ((c) == ' ' || (c) == '\t')
60 #define isascii(c)      (((unsigned char)(c)) <= 0x7F)
61 
isprint(unsigned char c)62 __STATIC_INLINE int isprint(unsigned char c)
63 {
64     if ((c >= 0x1F) && (c <= 0x7E))
65         return 1;
66     return 0;
67 }
68 
isdigit(unsigned char c)69 __STATIC_INLINE int isdigit(unsigned char c)
70 {
71     return ((c >= '0') && (c <='9'));
72 }
73 
isxdigit(unsigned char c)74 __STATIC_INLINE int isxdigit(unsigned char c)
75 {
76     if ((c >= '0') && (c <='9'))
77         return 1;
78     if ((c >= 'a') && (c <='f'))
79         return 1;
80     if ((c >= 'A') && (c <='F'))
81         return 1;
82     return 0;
83 }
84 
islower(unsigned char c)85 __STATIC_INLINE int islower(unsigned char c)
86 {
87     return ((c >= 'a') && (c <='z'));
88 }
89 
isupper(unsigned char c)90 __STATIC_INLINE int isupper(unsigned char c)
91 {
92     return ((c >= 'A') && (c <='Z'));
93 }
94 
tolower(unsigned char c)95 __STATIC_INLINE unsigned char tolower(unsigned char c)
96 {
97     if (isupper(c))
98         c -= 'A'-'a';
99     return c;
100 }
101 
toupper(unsigned char c)102 __STATIC_INLINE unsigned char toupper(unsigned char c)
103 {
104     if (islower(c))
105         c -= 'a'-'A';
106     return c;
107 }
108 
make_argv(char * s,char * argv[])109 __STATIC_INLINE int make_argv(char *s, char *argv[])
110 {
111     int argc = 0;
112 
113     while (argc < CONFIG_SYS_MAXARGS) {
114         /* skip any white space */
115         while (isblank(*s)) {
116             ++s;
117         }
118 
119         if (*s == '\0') {       /* end of line, no more args */
120             argv[argc] = 0;
121             return argc;
122         }
123 
124         if(*s == '\"') {        /* args with quotation marks */
125             s++;                /* the first quotation mark */
126 
127             argv[argc++] = s;   /* begin of argument string */
128 
129             while(*s && (*s != '\"')) { /* the second quotation mark */
130                 ++s;
131             }
132         } else {
133             argv[argc++] = s;   /* begin of argument string */
134 
135             /* find end of string */
136             while(*s && !isblank(*s)) {
137                 ++s;
138             }
139         }
140 
141         if (*s == '\0') {       /* end of line, no more args */
142             argv[argc] = 0;
143             return argc;
144         }
145 
146         *s++ = '\0';         /* terminate current arg */
147     }
148 
149     console_putf("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS);
150 
151     return argc;
152 }
153 
find_cmd(const char * cmd)154 __STATIC_INLINE cmd_tbl_t * find_cmd(const char *cmd)
155 {
156     cmd_tbl_t *cmdtp;
157     cmd_tbl_t *cmdtp_temp = &cmd_tbl_list[0];    /* Init value */
158     const char *p;
159     unsigned int len;
160     int n_found = 0;
161     int i;
162 
163     p = strchr(cmd, '.');
164     len = (p == NULL) ? strlen(cmd) : (unsigned int)(p - cmd);
165 
166     for (i = 0; i < (int)cmd_tbl_curidx; i++) {
167         cmdtp = &cmd_tbl_list[i];
168         if (strncmp(cmd, cmdtp->name, len) == 0) {
169             if (len == strlen(cmdtp->name))
170                 return cmdtp;      /* full match */
171 
172             cmdtp_temp = cmdtp;    /* abbreviated command ? */
173             n_found++;
174         }
175     }
176     if (n_found == 1) {  /* exactly one match */
177         return cmdtp_temp;
178     }
179 
180     return 0;   /* not found or ambiguous command */
181 }
182 
183 /**
184  * Call a command function.
185  *
186  * @param cmdtp     Pointer to the command to execute
187  * @param argc      Number of arguments (arg 0 must be the command text)
188  * @param argv      Arguments
189  * @return 0 if command succeeded, else non-zero
190  */
cmd_call(cmd_tbl_t * cmdtp,int argc,char * const argv[])191 __STATIC_INLINE int cmd_call(cmd_tbl_t *cmdtp, int argc, char *const argv[])
192 {
193     int result;
194     result = (cmdtp->cmd)(argc, argv);
195     if (result) {
196         console_putf("Command failed, result=%d\n", result);
197     }
198     return result;
199 }
200 
cmd_process(int argc,char * const argv[])201 __STATIC_INLINE int cmd_process(int argc, char *const argv[])
202 {
203     cmd_tbl_t *cmdtp;
204 
205     /* Look up command in command table */
206     cmdtp = find_cmd(argv[0]);
207     if (cmdtp == NULL) {
208         console_putf("Unknown command '%s'\n", argv[0]);
209         return -1;
210     }
211 
212     /* found - check max args */
213     if (argc > cmdtp->maxargs) {
214         console_putf("Usage:\n%s\n", cmdtp->usage);
215         return -1;
216     }
217 
218     /* If OK so far, then do the command */
219     if (cmd_call(cmdtp, argc, argv)) {
220         return -1;
221     }
222 
223     return 0;
224 }
225 
cmd_run(char * cmd)226 static int cmd_run(char *cmd)
227 {
228     char *argv[CONFIG_SYS_MAXARGS + 1];    /* NULL terminated */
229     int argc;
230 
231     /* separate into argv */
232     argc = make_argv(cmd, argv);
233     if (argc == 0) {
234         return -1;    /* no command at all */
235     }
236 
237     if (cmd_process(argc, argv)) {
238         return -1;
239     }
240 
241     return 0;
242 }
243 
delete_char(char * buffer,char * p,int * colp,int * np,int plen)244 static char *delete_char(char *buffer, char *p, int *colp, int *np, int plen)
245 {
246     char *s;
247 
248     if (*np == 0) {
249         return p;
250     }
251 
252     if (*(--p) == '\t') {           /* will retype the whole line */
253         while (*colp > plen) {
254             console_puts(erase_seq);
255             (*colp)--;
256         }
257         for (s = buffer; s < p; ++s) {
258             if (*s == '\t') {
259                 console_puts(tab_seq + ((*colp) & 0x07));
260                 *colp += 8 - ((*colp) & 0x07);
261             } else {
262                 ++(*colp);
263                 console_putc(*s);
264             }
265         }
266     } else {
267         console_puts(erase_seq);
268         (*colp)--;
269     }
270     (*np)--;
271 
272     return p;
273 }
274 
readchar_into_buffer(const char c,char * prompt)275 static int readchar_into_buffer(const char c, char *prompt) {
276     static char *p   = console_buffer;
277     static int  n    = 0;   /* buffer index         */
278     static int  plen = 0;   /* prompt length        */
279     static int  col;        /* output column cnt    */
280 
281     if (prompt) {
282         plen = strlen(prompt);
283         p = console_buffer;
284         n = 0;
285         return 0;
286     }
287     col = plen;
288 
289     /*
290      * Special character handling
291      */
292     switch (c) {
293         case '\r':                  /* Enter            */
294         case '\n':
295             *p = '\0';
296             console_puts("\r\n");
297             return (p - console_buffer);
298 
299         case '\0':                  /* nul              */
300             return -1;
301 
302         case 0x03:                  /* ^C - break       */
303             console_buffer[0] = '\0';  /* discard input */
304             return 0;
305 
306         case 0x15:                  /* ^U - erase line  */
307             while (col > plen) {
308                 console_puts(erase_seq);
309                 --col;
310             }
311             p = console_buffer;
312             n = 0;
313             return -1;
314 
315         case 0x17:                  /* ^W - erase word  */
316             p = delete_char(console_buffer, p, &col, &n, plen);
317             while ((n > 0) && (*p != ' ')) {
318                 p = delete_char(console_buffer, p, &col, &n, plen);
319             }
320             return -1;
321 
322         case 0x08:                  /* ^H  - backspace  */
323         case 0x7F:                  /* DEL - backspace  */
324             p = delete_char(console_buffer, p, &col, &n, plen);
325             return -1;
326 
327         default:
328             /*
329              * Must be a normal character then
330              */
331             if (n < CONFIG_SYS_CBSIZE - 2) {
332                 if (c == '\t') {    /* expand TABs      */
333                     console_puts(tab_seq + (col & 0x07));
334                     col += 8 - (col & 0x07);
335                 } else {
336                     ++col;          /* Echo input       */
337                     console_putc(c);
338                 }
339                 *p++ = c;
340                 ++n;
341             } else {                /* Buffer full      */
342                 console_putc('\a');
343             }
344     }
345 
346     return -1;
347 }
348 
349 /*
350  * print data block
351  */
print_buffer(uint32_t addr,uint32_t count,uint8_t width,bool ascii_on)352 void print_buffer(uint32_t addr, uint32_t count, uint8_t width, bool ascii_on)
353 {
354     uint32_t nbytes;
355 
356     if ((count == 0) || !((width == 4) || (width == 2) || (width == 1))) {
357         return;
358     }
359     addr &= ~((uint32_t)width - 0x01UL);
360     nbytes = count * width;
361 
362     /* print lines */
363     do {
364         uint8_t  *str = (uint8_t *)addr;
365         uint32_t linebytes = 0;
366         uint32_t i = 0;
367 
368         console_putf("%08x:", addr);
369 
370         linebytes = (nbytes > CONFIG_LINE_BYTES) ? CONFIG_LINE_BYTES : nbytes;
371 
372         #if PLF_PMIC
373         if (IS_PMIC_SRAM_VALID(addr) || IS_PMIC_REG_VALID(addr)) {
374             ascii_on = false;
375             for (i = 0; i < linebytes; i += 4) {
376                 uint32_t rdata = PMIC_MEM_READ(addr);
377                 if(width == 4) {
378                     console_putf(" %08X", rdata);
379                 } else if(width == 2) {
380                     console_putf(" %04X %04X", (uint16_t)rdata, (uint16_t)(rdata >> 16));
381                 } else {
382                     console_putf(" %02X %02X %02X %02X", (uint8_t)rdata, (uint8_t)(rdata >> 8),
383                         (uint8_t)(rdata >> 16), (uint8_t)(rdata >> 24));
384                 }
385                 addr += 4;
386             }
387         } else
388         #endif
389         for (i = 0; i < linebytes; i += width) {
390             if(width == 4) {
391                 console_putf(" %08X", *((uint32_t *)addr));
392             } else if(width == 2) {
393                 console_putf(" %04X", *((uint16_t *)addr));
394             } else {
395                 console_putf(" %02X", *((uint8_t *)addr));
396             }
397             addr += width;
398         }
399 
400         if (ascii_on) {
401             for (i = linebytes; i < CONFIG_LINE_BYTES; i++) {
402                 if (((i - linebytes) & ((uint32_t)width - 0x01UL)) == 0x00UL) {
403                     console_putc(' ');
404                 }
405                 console_puts("  ");
406             }
407             console_puts("    ");
408 
409             /* print ASCII */
410             for (i = 0; i < (linebytes + 0); i++) {
411                 if (isascii(str[i]) && isprint(str[i])) {
412                     console_putc(str[i]);
413                 } else {
414                     console_putc('.');
415                 }
416             }
417         }
418 
419         console_puts("\r\n");
420         nbytes -= linebytes;
421     } while(nbytes > 0);
422 }
423 
do_auto_download(int argc,char * argv[])424 int do_auto_download(int argc, char *argv[])
425 {
426     printf("%s: reboot to download ...\n");
427     pmic_chip_reboot();
428 }
429 
do_help(int argc,char * argv[])430 int do_help(int argc, char *argv[])
431 {
432     cmd_tbl_t *cmdtemp = &cmd_tbl_list[0];    /*Init value */
433     int i = 0;
434 
435     console_putf("\r\n");
436     for (i = 1; i < cmd_tbl_curidx; i++) {
437         cmdtemp = &cmd_tbl_list[i];
438         if(cmdtemp->usage) {
439             console_putf("%s\r\n", cmdtemp->usage);
440         }
441     }
442     return 0;
443 }
444 
do_mem_read(int argc,char * argv[])445 int do_mem_read(int argc, char *argv[])
446 {
447     uint32_t addr, cnt = 1;
448     int size;
449 
450     if(argc < 2) {
451         return -1;
452     }
453 
454     addr = console_cmd_strtoul(argv[1], NULL, 16);
455 
456     if(argc > 2) {
457         cnt = console_cmd_strtoul(argv[2], NULL, 0);
458     }
459 
460     if (argc > 3) {
461         size = console_cmd_strtoul(argv[3], NULL, 0);
462         if ((4 != size) && (2 != size) && (1 != size)) {
463             console_putf("Unknown data size:%d\n", size);
464             return -2;
465         }
466     } else {
467         size = 4;
468     }
469 
470     /* Compatible with previous version which cnt always = 1 */
471     if(cnt == 1) {
472         #if PLF_PMIC
473         if (IS_PMIC_SRAM_VALID(addr) || IS_PMIC_REG_VALID(addr)) {
474             console_putf("[0x%08X] = 0x%08X\n", addr, PMIC_MEM_READ(addr));
475         } else
476         #endif
477         if(size == 4) {
478             console_putf("[0x%08lX] = 0x%08lX\n", addr & 0xFFFFFFFC,
479                 *((volatile uint32_t*)(addr & 0xFFFFFFFC)));
480         } else if(size == 2) {
481             console_putf("[0x%08lX] = 0x%04X\n", addr & 0xFFFFFFFE,
482                 *((volatile uint16_t*)(addr & 0xFFFFFFFE)));
483         } else if(size == 1) {
484             console_putf("[0x%08lX] = 0x%02X\n", addr,
485                 *((volatile uint8_t*)(addr)));
486         }
487         return 0;
488     }
489 
490     print_buffer(addr, cnt, size, false);
491 
492     return 0;
493 }
494 
do_mem_write(int argc,char * argv[])495 int do_mem_write(int argc, char *argv[])
496 {
497     uint32_t addr;
498     uint32_t value;
499 
500     if ((argc < 3)) {
501         return -1;
502     }
503 
504     addr = console_cmd_strtoul(argv[1], NULL, 16);
505     console_putf("Addr  = 0x%08lX\n", addr);
506 
507     value = console_cmd_strtoul(argv[2], NULL, 16);
508     console_putf("Value = 0x%08lX\n", value);
509 
510     #if PLF_PMIC
511     if (IS_PMIC_SRAM_VALID(addr) || IS_PMIC_REG_VALID(addr)) {
512         PMIC_MEM_WRITE(addr, value);
513     } else
514     #endif
515     *((volatile uint32_t *)addr) = value;
516     console_putf("Write Done\n");
517 
518     return 0;
519 }
520 
521 #if (PLF_PMIC && PLF_PMIC_VER_LITE && PLF_EXT_CS1000)
522 /*
523  * print data block
524  */
aprint_buffer(uint32_t addr,uint32_t count,uint8_t width,bool ascii_on)525 void aprint_buffer(uint32_t addr, uint32_t count, uint8_t width, bool ascii_on)
526 {
527     uint32_t nbytes;
528 
529     if ((count == 0) || !((width == 4) || (width == 2) || (width == 1))) {
530         return;
531     }
532     addr &= ~((uint32_t)width - 0x01UL);
533     nbytes = count * width;
534 
535     /* print lines */
536     do {
537         uint8_t  *str = (uint8_t *)addr;
538         uint32_t linebytes = 0;
539         uint32_t i = 0;
540 
541         console_putf("%08x:", addr);
542 
543         linebytes = (nbytes > CONFIG_LINE_BYTES) ? CONFIG_LINE_BYTES : nbytes;
544 
545         if (IS_PMIC_SRAM_VALID(addr) || IS_PMIC_REG_VALID(addr)) {
546             ascii_on = false;
547             for (i = 0; i < linebytes; i += 4) {
548                 uint32_t rdata = psi_read_op(addr);
549                 if(width == 4) {
550                     console_putf(" %08X", rdata);
551                 } else if(width == 2) {
552                     console_putf(" %04X %04X", (uint16_t)rdata, (uint16_t)(rdata >> 16));
553                 } else {
554                     console_putf(" %02X %02X %02X %02X", (uint8_t)rdata, (uint8_t)(rdata >> 8),
555                         (uint8_t)(rdata >> 16), (uint8_t)(rdata >> 24));
556                 }
557                 addr += 4;
558             }
559         }
560 
561         if (ascii_on) {
562             for (i = linebytes; i < CONFIG_LINE_BYTES; i++) {
563                 if (((i - linebytes) & ((uint32_t)width - 0x01UL)) == 0x00UL) {
564                     console_putc(' ');
565                 }
566                 console_puts("  ");
567             }
568             console_puts("    ");
569 
570             /* print ASCII */
571             for (i = 0; i < (linebytes + 0); i++) {
572                 if (isascii(str[i]) && isprint(str[i])) {
573                     console_putc(str[i]);
574                 } else {
575                     console_putc('.');
576                 }
577             }
578         }
579 
580         console_puts("\r\n");
581         nbytes -= linebytes;
582     } while(nbytes > 0);
583 }
584 
do_amem_read(int argc,char * argv[])585 int do_amem_read(int argc, char *argv[])
586 {
587     uint32_t addr, cnt = 1;
588     int size;
589 
590     if(argc < 2) {
591         return -1;
592     }
593 
594     addr = console_cmd_strtoul(argv[1], NULL, 16);
595 
596     if(argc > 2) {
597         cnt = console_cmd_strtoul(argv[2], NULL, 0);
598     }
599 
600     if (argc > 3) {
601         size = console_cmd_strtoul(argv[3], NULL, 0);
602         if ((4 != size) && (2 != size) && (1 != size)) {
603             console_putf("Unknown data size:%d\n", size);
604             return -2;
605         }
606     } else {
607         size = 4;
608     }
609 
610     if (!(IS_PMIC_SRAM_VALID(addr) || IS_PMIC_REG_VALID(addr))) {
611         return -3;
612     }
613 
614     /* Compatible with previous version which cnt always = 1 */
615     if(cnt == 1) {
616         if (IS_PMIC_SRAM_VALID(addr) || IS_PMIC_REG_VALID(addr)) {
617             console_putf("[0x%08X] = 0x%08X\n", addr, psi_read_op(addr));
618         }
619         return 0;
620     }
621 
622     aprint_buffer(addr, cnt, size, false);
623 
624     return 0;
625 }
626 
do_amem_write(int argc,char * argv[])627 int do_amem_write(int argc, char *argv[])
628 {
629     uint32_t addr;
630     uint32_t value;
631 
632     if ((argc < 3)) {
633         return -1;
634     }
635 
636     addr = console_cmd_strtoul(argv[1], NULL, 16);
637     console_putf("Addr  = 0x%08lX\n", addr);
638 
639     value = console_cmd_strtoul(argv[2], NULL, 16);
640     console_putf("Value = 0x%08lX\n", value);
641 
642     if (IS_PMIC_SRAM_VALID(addr) || IS_PMIC_REG_VALID(addr)) {
643         psi_write_op(addr, value);
644     } else {
645         return -2;
646     }
647     console_putf("Write Done\n");
648 
649     return 0;
650 }
651 #endif
652 
653 /**
654  * Public function
655  */
command_init(void)656 void command_init(void)
657 {
658     int i;
659     CONSOLE_CRITICAL_START();
660     INIT_LIST_HEAD(&cmd_free_list);
661     INIT_LIST_HEAD(&cmd_pend_list);
662     for (i = 0; i < CONFIG_CMDBUF_SIZE; i++) {
663         cmd_buf_node_t *buf = &(cmd_buf_tab[i]);
664         list_add(&buf->entry, &cmd_free_list);
665     }
666     CONSOLE_CRITICAL_END();
667     console_cmd_add("help", " help info", 1, do_help);
668     console_cmd_add("r", "  r addr <cnt> <size>", 4, do_mem_read);
669     console_cmd_add("w", "  w addr val", 3, do_mem_write);
670     #if (PLF_PMIC && PLF_PMIC_VER_LITE && PLF_EXT_CS1000)
671     console_cmd_add("ar", " ar addr <cnt> <size>", 4, do_amem_read);
672     console_cmd_add("aw", " aw addr val", 3, do_amem_write);
673     #endif
674     console_cmd_add("auto_dl", "  auto_dl: auto download image", 1, do_auto_download);
675 }
676 
677 /**
678  * called in isr
679  */
command_handle_char(char ch)680 int command_handle_char(char ch)
681 {
682     int len = readchar_into_buffer(ch, 0);
683     if (len >= 0) {
684         if (len) {
685             #if CONSOLE_GLOBAL_DEBUG_MODE
686             if ((strlen(CMDISR_SUPER_STR) == len) && !strcmp(CMDISR_SUPER_STR, console_buffer)) {
687                 uint32_t regCTRL = __get_CONTROL();
688                 uint32_t regXPSR = __get_xPSR();
689                 uint32_t regPSP  = __get_PSP();
690                 uint32_t regMSP  = __get_MSP();
691                 uint32_t regPMSK = __get_PRIMASK();
692                 uint32_t regBPRI = __get_BASEPRI();
693                 console_putf("CONTROL=%08x, xPSR   =%08x\r\n"
694                             "PSP    =%08x, MSP    =%08x\r\n"
695                             "PRIMASK=%08x, BASEPRI=%08x\r\n",
696                             regCTRL, regXPSR, regPSP, regMSP, regPMSK, regBPRI);
697                 if (regMSP) {
698                     int32_t idx;
699                     uint32_t addr = regMSP & ~0x0FUL;
700                     console_putf("\nDumpMSP:");
701                     for (idx = 0; idx < 64; idx++) {
702                         if (!(addr & 0x0FUL)) {
703                             console_putf("\n[%08x]:", addr);
704                         }
705                         console_putf(" %08X", *((uint32_t *)addr));
706                         addr += 4;
707                     }
708                 }
709                 if (regPSP) {
710                     int32_t idx;
711                     uint32_t addr = regPSP & ~0x0FUL;
712                     console_putf("\nDumpPSP:");
713                     for (idx = 0; idx < 64; idx++) {
714                         if (!(addr & 0x0FUL)) {
715                             console_putf("\n[%08x]:", addr);
716                         }
717                         console_putf(" %08X", *((uint32_t *)addr));
718                         addr += 4;
719                     }
720                 }
721                 len = 0;
722                 console_puts("\r\n" CONFIG_SYS_PROMPT);
723             } else
724             #endif /* CONSOLE_GLOBAL_DEBUG_MODE */
725             if (!list_empty(&cmd_free_list)) {
726                 cmd_buf_node_t *buf = list_first_entry(&cmd_free_list, cmd_buf_node_t, entry);
727                 strcpy(buf->buffer, console_buffer);
728                 list_move_tail(&(buf->entry), &cmd_pend_list);
729             } else {
730                 console_puts("err: cmd_free_list empty\r\n");
731             }
732         } else {
733             console_puts(CONFIG_SYS_PROMPT);
734         }
735         readchar_into_buffer('0', CONFIG_SYS_PROMPT);
736     }
737     return len;
738 }
739 
command_add(const char * name,const char * usage,int maxargs,cmd_func_t func)740 int command_add(const char *name, const char *usage, int maxargs, cmd_func_t func)
741 {
742     cmd_tbl_t *tmp_cmd;
743 
744     if(CONFIG_CMDTBL_SIZE <= cmd_tbl_curidx) {
745         console_putf("No more cmds supported.\n");
746         return -1;
747     }
748 
749     tmp_cmd = &(cmd_tbl_list[cmd_tbl_curidx]);
750     cmd_tbl_curidx++;
751     tmp_cmd->name = name;
752     tmp_cmd->usage = usage;
753     tmp_cmd->maxargs = maxargs;
754     tmp_cmd->cmd = func;
755 
756     return 0;
757 }
758 
759 /**
760  * called in task
761  */
command_parser(void)762 void command_parser(void)
763 {
764     cmd_buf_node_t *buf;
765 
766     CONSOLE_CRITICAL_START();
767     buf = list_empty(&cmd_pend_list) ? NULL : list_first_entry(&cmd_pend_list, cmd_buf_node_t, entry);
768     CONSOLE_CRITICAL_END();
769 
770     while (buf) {
771         if(cmd_run(buf->buffer) < 0) {
772             console_puts("command fail\r\n");
773         }
774         console_puts(CONFIG_SYS_PROMPT);
775 
776         CONSOLE_CRITICAL_START();
777         list_move_tail(&(buf->entry), &cmd_free_list);
778         buf = list_empty(&cmd_pend_list) ? NULL : list_first_entry(&cmd_pend_list, cmd_buf_node_t, entry);
779         CONSOLE_CRITICAL_END();
780     }
781 }
782 
command_strtoul(const char * cp,char ** endp,unsigned int base)783 unsigned int command_strtoul(const char *cp, char **endp, unsigned int base)
784 {
785     unsigned int result = 0, value;
786 
787     if (*cp == '0') {
788         cp++;
789         if ((tolower(*cp) == 'x') && isxdigit(*(cp + 1))) {
790             base = 16;
791             cp++;
792         }
793         if (!base) {
794             base = 8;
795         }
796     }
797     if (!base) {
798         base = 10;
799     }
800     while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp - '0' : (islower(*cp)
801         ? toupper(*cp) : *cp) - 'A' + 10) < base) {
802         result = result * base + value;
803         cp++;
804     }
805     if (endp)
806         *endp = (char *)cp;
807     return result;
808 }
809 
command_pend_list_empty(void)810 unsigned int command_pend_list_empty(void)
811 {
812     int ret;
813     CONSOLE_CRITICAL_START();
814     ret = list_empty(&cmd_pend_list);
815     CONSOLE_CRITICAL_END();
816     return ret;
817 }
818