1 /*
2  * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3  */
4 
5 #if AOS_COMP_CLI
6 
7 #include <stdlib.h>
8 #include <unistd.h>
9 
10 #include "k_api.h"
11 #include "aos/cli.h"
12 #include "aos/kernel.h"
13 #include "debug_api.h"
14 
15 
16 #if (RHINO_CONFIG_UCLI)
17     #include "ucli.h"
18 #endif
19 
20 #if defined (__CC_ARM) && defined(__MICROLIB)
21     #define TOSTR(s) #s
22 #else
23     #define TOSTR
24 #endif
25 
26 
27 static void version_cmd(char *buf, int32_t len, int32_t argc, char **argv);
28 static void uptime_cmd(char *buf, int32_t len, int32_t argc, char **argv);
29 static void debug_cmd(char *buf, int32_t len, int32_t argc, char **argv);
30 static void msleep_cmd(char *buf, int32_t len, int32_t argc, char **argv);
31 
32 static void devname_cmd(char *buf, int32_t len, int32_t argc, char **argv);
33 static void pmem_cmd(char *buf, int32_t len, int32_t argc, char **argv);
34 static void mmem_cmd(char *buf, int32_t len, int32_t argc, char **argv);
35 static void func_cmd(char *buf, int32_t len, int32_t argc, char **argv);
36 static void debug_panic_runto_cli(char *buf, int32_t len, int32_t argc, char **argv);
37 
38 static const struct cli_command built_ins[] = {
39     { "debug", "show debug info", debug_cmd },
40     /*aos_rhino*/
41     { "sysver", "system version", version_cmd },
42     { "time", "system time", uptime_cmd },
43     { "msleep", "sleep miliseconds", msleep_cmd },
44     { "p", "print memory", pmem_cmd },
45     { "m", "modify memory", mmem_cmd },
46     { "f", "run a function", func_cmd },
47     { "devname", "print device name", devname_cmd },
48     { "err2cli", "set exec runto cli", debug_panic_runto_cli },
49 };
50 
debug_cmd(char * buf,int32_t len,int32_t argc,char ** argv)51 static void debug_cmd(char *buf, int32_t len, int32_t argc, char **argv)
52 {
53     debug_overview(aos_cli_printf);
54 }
55 
version_cmd(char * buf,int32_t len,int32_t argc,char ** argv)56 static void version_cmd(char *buf, int32_t len, int32_t argc, char **argv)
57 {
58 #ifdef OSAL_RHINO
59     aos_cli_printf("kernel version :%d\r\n", (int32_t)krhino_version_get());
60 #else
61     aos_cli_printf("kernel version :posix\r\n");
62 #endif
63 }
64 
uptime_cmd(char * buf,int32_t len,int32_t argc,char ** argv)65 static void uptime_cmd(char *buf, int32_t len, int32_t argc, char **argv)
66 {
67     aos_cli_printf("UP time %ld ms\r\n", (long)krhino_sys_time_get());
68 }
69 
msleep_cmd(char * buf,int32_t len,int32_t argc,char ** argv)70 static void msleep_cmd(char *buf, int32_t len, int32_t argc, char **argv)
71 {
72     int seconds;
73 
74     if (argc != 2) {
75         aos_cli_printf("Usage: msleep seconds\r\n");
76         return;
77     }
78 
79     seconds = atoi(argv[1]);
80     if (seconds > 0) {
81         krhino_task_sleep(krhino_ms_to_ticks(seconds));
82     } else {
83         aos_cli_printf("invalid param %s\r\n", argv[1]);
84     }
85 }
86 
devname_cmd(char * buf,int32_t len,int32_t argc,char ** argv)87 static void devname_cmd(char *buf, int32_t len, int32_t argc, char **argv)
88 {
89 #ifdef SYSINFO_DEVICE_NAME
90     aos_cli_printf("device name: %s\r\n", TOSTR(SYSINFO_DEVICE_NAME));
91 #else
92     aos_cli_printf("device name: not defined on board\r\n");
93 #endif
94 }
95 
96 uint32_t __attribute__((weak)) _system_ram_start = 0;
97 uint32_t __attribute__((weak)) _system_ram_len   = 0;
98 
pmem_cmd(char * buf,int32_t len,int32_t argc,char ** argv)99 static void pmem_cmd(char *buf, int32_t len, int32_t argc, char **argv)
100 {
101     int32_t i;
102     int32_t nunits = 16;
103     int32_t width  = 4;
104 
105     //char *addr   = NULL;
106     uint32_t addr = 0;
107 
108     switch (argc) {
109         case 4:
110             width = strtoul(argv[3], NULL, 0);
111         case 3:
112             nunits = strtoul(argv[2], NULL, 0);
113             nunits = nunits > 0x400 ? 0x400 : nunits;
114         case 2:
115             if (0 == strcmp(argv[1], "all")) {
116                 aos_cli_printf("ram start: 0x%x  len: 0x%x\n", _system_ram_start, _system_ram_len);
117                 if ((_system_ram_start != 0) && (_system_ram_len != 0)) {
118                     addr   = _system_ram_start;
119                     nunits = _system_ram_len / 4;
120                     width  = 4;
121                 }
122             } else {
123                 addr = strtoul(argv[1], NULL, 0);
124             }
125             break;
126         default:
127             aos_cli_printf("p <addr> <nunits> <width>\r\n"
128                        "addr  : address to display\r\n"
129                        "nunits: number of units to display (default is 16)\r\n"
130                        "width : width of unit, 1/2/4 (default is 4)\r\n");
131             return;
132     }
133 
134     switch (width) {
135         case 1:
136             for (i = 0; i < nunits; i++) {
137                 if (i % 16 == 0) {
138                     aos_cli_printf("0x%08x:", addr);
139                 }
140                 aos_cli_printf(" %02x", *(unsigned char *)addr);
141                 addr += 1;
142                 if (i % 16 == 15) {
143                     aos_cli_printf("\r\n");
144                 }
145             }
146             break;
147         case 2:
148             for (i = 0; i < nunits; i++) {
149                 if (i % 8 == 0) {
150                     aos_cli_printf("0x%08x:", addr);
151                 }
152                 aos_cli_printf(" %04x", *(unsigned short *)addr);
153                 addr += 2;
154                 if (i % 8 == 7) {
155                     aos_cli_printf("\r\n");
156                 }
157             }
158             break;
159         default:
160             for (i = 0; i < nunits; i++) {
161                 if (i % 4 == 0) {
162                     aos_cli_printf("0x%08x:", addr);
163                 }
164                 aos_cli_printf(" %08x", *(unsigned int *)addr);
165                 addr += 4;
166                 if (i % 4 == 3) {
167                     aos_cli_printf("\r\n");
168                 }
169             }
170             break;
171     }
172 }
173 
mmem_cmd(char * buf,int32_t len,int32_t argc,char ** argv)174 static void mmem_cmd(char *buf, int32_t len, int32_t argc, char **argv)
175 {
176     void *addr  = NULL;
177 
178     int32_t  width = 4;
179     uint32_t value = 0;
180 
181     uint32_t old_value;
182     uint32_t new_value;
183 
184     switch (argc) {
185         case 4:
186             width = strtoul(argv[3], NULL, 0);
187         case 3:
188             value = strtoul(argv[2], NULL, 0);
189         case 2:
190             addr = (void *)strtoul(argv[1], NULL, 0);
191             break;
192         default:
193             aos_cli_printf("m <addr> <value> <width>\r\n"
194                        "addr  : address to modify\r\n"
195                        "value : new value (default is 0)\r\n"
196                        "width : width of unit, 1/2/4 (default is 4)\r\n");
197             return;
198     }
199 
200     switch (width) {
201         case 1:
202             old_value = (uint32_t)(*(uint8_t volatile *)addr);
203             *(uint8_t volatile *)addr = (uint8_t)value;
204             new_value = (uint32_t)(*(uint8_t volatile *)addr);
205             break;
206         case 2:
207             old_value = (uint32_t)(*(unsigned short volatile *)addr);
208             *(unsigned short volatile *)addr = (unsigned short)value;
209             new_value = (uint32_t)(*(unsigned short volatile *)addr);
210             break;
211         case 4:
212         default:
213             old_value = *(uint32_t volatile *)addr;
214             *(uint32_t volatile *)addr = (uint32_t)value;
215             new_value = *(uint32_t volatile *)addr;
216             break;
217     }
218     aos_cli_printf("value on 0x%x change from 0x%x to 0x%x.\r\n", (uint32_t)addr,
219                old_value, new_value);
220 }
221 
func_cmd(char * buf,int32_t len,int32_t argc,char ** argv)222 static void func_cmd(char *buf, int32_t len, int32_t argc, char **argv)
223 {
224     uint32_t idx, ret;
225     uint32_t para[8] = {0};
226     typedef uint32_t (*func_ptr_t)(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
227                                    uint32_t a5, uint32_t a6, uint32_t a7, uint32_t a8);
228     func_ptr_t func_ptr;
229 
230     if (argc == 1) {
231         aos_cli_printf("para error\r\n");
232         return;
233     }
234 
235     argc = argc > 10 ? 10 : argc;
236 
237     func_ptr = (func_ptr_t)strtoul(argv[1], NULL, 0);
238     for (idx = 2 ; idx < argc ; idx++) {
239         para[idx - 2] = strtoul(argv[idx], NULL, 0);
240     }
241 
242     aos_cli_printf("function %p runing...\r\n", func_ptr);
243 #ifdef ARCH_CORTEX_M
244     func_ptr = (func_ptr_t)((unsigned int)(func_ptr) + 1);
245 #endif
246     ret = func_ptr(para[0], para[1], para[2], para[3], para[4], para[5], para[6], para[7]);
247     aos_cli_printf("function %p return 0x%x.\r\n", func_ptr, ret);
248 }
249 
250 
debug_panic_runto_cli(char * buf,int32_t len,int32_t argc,char ** argv)251 static void debug_panic_runto_cli(char *buf, int32_t len, int32_t argc, char **argv)
252 {
253     if (argc == 2) {
254         int32_t flag = strtoul(argv[1], NULL, 0);
255         if (flag == 1) {
256             g_crash_not_reboot = OS_PANIC_NOT_REBOOT;
257         } else {
258             g_crash_not_reboot = 0;
259         }
260         aos_cli_printf("set panic_runto_cli flag:0x%x\r\n", g_crash_not_reboot);
261     }
262 }
263 
debug_default_cmds_register(void)264 static void debug_default_cmds_register(void)
265 {
266     int32_t ret;
267 
268     ret = aos_cli_register_commands(built_ins, sizeof(built_ins) / sizeof(struct cli_command));
269     if (ret) {
270         printf("%s %d failed, ret = %d\r\n", __func__, __LINE__, ret);
271     }
272 }
273 
debug_cli_cmd_init(void)274 void debug_cli_cmd_init(void)
275 {
276     debug_default_cmds_register();
277     debug_dumpsys_cmds_register();
278 #if (RHINO_CONFIG_SYS_STATS > 0)
279     debug_cpuusage_cmds_register();
280 #endif
281 }
282 #endif /* #if AOS_COMP_CLI */
283