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