Paparazzi UAS  v6.2_unstable
Paparazzi is a free software Unmanned Aircraft System.
microrlShell.c
Go to the documentation of this file.
1 
9 #include <string.h>
10 #include "microrl/microrlShell.h"
11 #include "microrl/microrl.h"
12 #include "printf.h"
13 //#include "stdutil.h"
14 
15 
16 #define printScreen(...) {chprintf (chpg, __VA_ARGS__); chprintf (chpg, "\r\n");}
17 
18 typedef struct {
19  void (*altFunc) (uint8_t c, uint32_t mode);
21 } AltCbParam;
22 
23 static void cmd_info(BaseSequentialStream *lchp, int argc,
24  const char * const argv[]);
25 
26 
30  event_source_t shell_terminated;
31 
32 static MUTEX_DECL(mut);
33 static microrl_t rl;
34 static BaseSequentialStream *chpg;
35 static const ShellCommand *staticCommands = NULL;
36 static const char * complWorlds[64];
40 #if SHELL_DYNAMIC_ENTRIES_NUMBER // compatibility with legacy static only behavior
42 #else
43 static const ShellCommand localCommands[] = {
44 #endif
45  {"info", cmd_info},
46  {NULL, NULL}
47 };
48 
49 static AltCbParam altCbParam = {.altFunc = NULL, .param = 0};
50 
51 void microrlPrint (const char * str)
52 {
53  int i = 0;
54 
55  while (str[i] != 0) {
56  streamPut(chpg, str[i++]);
57  }
58 }
59 
60 void microrlExecute (int argc, const char * const *argv)
61 {
62  const ShellCommand *scp = staticCommands;
63  const char *name = argv[0];
64 
65  chMtxLock(&mut);
66 
67  while (scp->sc_name != NULL) {
68  if (strcasecmp(scp->sc_name, name) == 0) {
69  scp->sc_function(chpg, argc-1, &argv[1]);
70  goto exit;
71  }
72  scp++;
73  }
74 
75  scp = localCommands;
76  while (scp->sc_name != NULL) {
77  if (strcasecmp(scp->sc_name, name) == 0) {
78  scp->sc_function(chpg, argc-1, &argv[1]);
79  goto exit;
80  }
81  scp++;
82  }
83 
84  exit:
85  chMtxUnlock(&mut);
86 }
87 
88 const char ** microrlComplet (int argc, const char * const * argv)
89 {
90  uint32_t j = 0;
91 
92  complWorlds [0] = NULL;
93  chMtxLock(&mut);
94 
95  // if there is token in cmdline
96  if (argc == 1) {
97  // get last entered token
98  const char *bit = argv[argc-1];
99  // iterate through our available token and match it
100  for (const ShellCommand *scp = localCommands;
101  scp->sc_name != NULL; scp++) {
102  // if token is matched (text is part of our token starting from 0 char)
103  if (strstr(scp->sc_name, bit) == scp->sc_name) {
104  // add it to completion set
105  complWorlds[j++] = scp->sc_name;
106  }
107  }
108  for (const ShellCommand *scp = staticCommands;
109  scp->sc_name != NULL; scp++) {
110  // if token is matched (text is part of our token starting from 0 char)
111  if (strstr(scp->sc_name, bit) == scp->sc_name) {
112  // add it to completion set
113  complWorlds[j++] = scp->sc_name;
114  }
115  }
116  } else { // if there is no token in cmdline, just print all available token
117  for (const ShellCommand *scp = localCommands; scp->sc_name != NULL; scp++)
118  complWorlds[j++] = scp->sc_name;
119  for (const ShellCommand *scp = staticCommands; scp->sc_name != NULL; scp++)
120  complWorlds[j++] = scp->sc_name;
121  }
122 
123  // note! last ptr in array always must be NULL!!!
124  complWorlds[j] = NULL;
125  chMtxUnlock(&mut);
126  // return set of variants
127  return complWorlds;
128 }
129 
130 
131 void microrlSigint (void)
132 {
133  chprintf (chpg, "^C catched!\n\r");
134 }
135 
136 
137 static void usage(BaseSequentialStream *lchp, char *p) {
138 
139  chprintf(lchp, "Usage: %s\r\n", p);
140 }
141 
142 
143 
144 static void cmd_info(BaseSequentialStream *lchp, int argc, const char * const argv[]) {
145 
146  (void)argv;
147  if (argc > 0) {
148  usage(lchp, "info");
149  return;
150  }
151 
152  /*
153  Bits 31:16 REV_ID[15:0] Revision identifier
154  This field indicates the revision of the device.
155  STM32F405xx/07xx and STM32F415xx/17xx devices:
156  0x1000 = Revision A
157  0x1001 = Revision Z
158  0x1003 = Revision 1
159  0x1007 = Revision 2
160  0x100F= Revision Y
161  STM32F42xxx and STM32F43xxx devices:
162  0x1000 = Revision A
163  0x1003 = Revision Y
164  0x1007 = Revision 1
165  0x2001= Revision 3
166  Bits 15:12 Reserved, must be kept at reset value.
167  Bits 11:0 DEV_ID[11:0]: Device identifier (STM32F405xx/07xx and STM32F415xx/17xx)
168  The device ID is 0x413.
169  Bits 11:0 DEV_ID[11:0]: Device identifier (STM32F42xxx and STM32F43xxx)
170  The device ID is 0x419
171 
172 
173  F7
174  Bits 31:16 REV_ID[15:0] Revision identifier
175  This field indicates the revision of the device:
176  0x1000 = Revision A
177  0x1001 = Revision Z
178  Bits 15:12 Reserved, must be kept at reset value.
179  Bits 11:0 DEV_ID[11:0]: Device identifier
180  The device ID is 0x449.
181 
182 
183  L47x 49x
184  Bits 31:16 REV_ID[15:0] Revision identifier
185  This field indicates the revision of the device.
186  For STM32L475xx/476xx/486xx devices
187  0x1000: Rev 1
188  0x1001: Rev 2
189  0x1003: Rev 3
190  0x1007: Rev 4
191  For STM32L496xx/4A6xx devices
192  0x1000: Rev A
193  0x2000: Rev B
194 
195  Bits 11:0 DEV_ID[11:0]: Device identifier
196  The device ID is:
197  0x461 for STM32L496xx/4A6xx devices
198  0x415 for STM32L475xx/476xx/486xx devices.
199  */
200 
201 
202  const uint16_t mcu_revid = (DBGMCU->IDCODE & DBGMCU_IDCODE_REV_ID) >> 16;
203  const uint16_t mcu_devid = DBGMCU->IDCODE & DBGMCU_IDCODE_DEV_ID;
204  char *mcu_devid_str ="not known, please fix microrlShell.c";
205  char mcu_revid_chr = '?';
206 
207  switch (mcu_devid) {
208  case 0x415 : mcu_devid_str = "STM32L475xx/476xx/486xx devices";
209  switch (mcu_revid) {
210  case 0x1000 : mcu_revid_chr = '1'; break;
211  case 0x1001 : mcu_revid_chr = '2'; break;
212  case 0x1003 : mcu_revid_chr = '3'; break;
213  case 0x1007 : mcu_revid_chr = '4'; break;
214  }
215  break;
216  case 0x461 : mcu_devid_str = "STM32L496xx/4A6xx devices";
217  switch (mcu_revid) {
218  case 0x1000 : mcu_revid_chr = 'A'; break;
219  case 0x2000 : mcu_revid_chr = 'B'; break;
220  }
221  break;
222  case 0x411 : mcu_devid_str = "STM32F2xx and *EARLY* STM32F40x and 41x";
223  switch (mcu_revid) {
224  case 0x1000 : mcu_revid_chr = 'A'; break;
225  case 0x1001 : mcu_revid_chr = 'Z'; break;
226  case 0x2000 : mcu_revid_chr = 'B'; break;
227  case 0x2001 : mcu_revid_chr = 'Y'; break;
228  case 0x2003 : mcu_revid_chr = 'X'; break;
229  }
230  break;
231  case 0x413 : mcu_devid_str = "STM32F40x and 41x";
232  switch (mcu_revid) {
233  case 0x1000 : mcu_revid_chr = 'A'; break;
234  case 0x1001 : mcu_revid_chr = 'Z'; break;
235  case 0x1003 : mcu_revid_chr = '1'; break;
236  case 0x1007 : mcu_revid_chr = '2'; break;
237  case 0x100F : mcu_revid_chr = 'Y'; break;
238  }
239  break;
240  case 0x419 : mcu_devid_str = "STM32F42x and F43x";
241  switch (mcu_revid) {
242  case 0x1000 : mcu_revid_chr = 'A'; break;
243  case 0x1003 : mcu_revid_chr = 'Y'; break;
244  case 0x1007 : mcu_revid_chr = '1'; break;
245  case 0x2001 : mcu_revid_chr = '3'; break;
246  }
247  break;
248  case 0x449 : mcu_devid_str = "STM32F74x and STM32F75x";
249  switch (mcu_revid) {
250  case 0x1000 : mcu_revid_chr = 'A'; break;
251  case 0x1001 : mcu_revid_chr = 'Z'; break;
252  }
253  break;
254  case 0x451 : mcu_devid_str = "STM32F76x and STM32F77x";
255  switch (mcu_revid) {
256  case 0x1000 : mcu_revid_chr = 'A'; break;
257  case 0x1001 : mcu_revid_chr = 'Z'; break;
258  }
259  break;
260  case 0x435 : mcu_devid_str = "STM32L43x";
261  switch (mcu_revid) {
262  case 0x1000 : mcu_revid_chr = 'A'; break;
263  case 0x1001 : mcu_revid_chr = 'Z'; break;
264  }
265  break;
266  case 0x446 : mcu_devid_str = "STM32F303xD/E and STM32F398xE";
267  switch (mcu_revid) {
268  case 0x1001 : mcu_revid_chr = 'Z'; break;
269  case 0x1003 : mcu_revid_chr = 'Y'; break;
270  }
271  break;
272  }
273 
274  chprintf(lchp, "Kernel: %s\r\n", CH_KERNEL_VERSION);
275 #ifdef HAL_VERSION
276  chprintf(lchp, "Hal: %s\r\n", HAL_VERSION);
277 #endif
278 
279 #ifdef CH_COMPILER_NAME
280  chprintf(lchp, "Compiler: %s\r\n", CH_COMPILER_NAME);
281 #endif
282 #ifdef PORT_COMPILER_NAME
283  chprintf(lchp, "Compiler: %s\r\n", PORT_COMPILER_NAME);
284 #endif
285 
286 #ifdef CH_ARCHITECTURE_NAME
287  chprintf(lchp, "Architecture: %s\r\n", CH_ARCHITECTURE_NAME);
288 #endif
289 #ifdef PORT_ARCHITECTURE_NAME
290  chprintf(lchp, "Architecture: %s\r\n", PORT_ARCHITECTURE_NAME);
291 #endif
292 
293 
294 #ifdef CH_CORE_VARIANT_NAME
295  chprintf(lchp, "Core Variant: %s\r\n", CH_CORE_VARIANT_NAME);
296 #endif
297 #ifdef PORT_CORE_VARIANT_NAME
298  chprintf(lchp, "Core Variant: %s\r\n", PORT_CORE_VARIANT_NAME);
299 #endif
300 #ifdef STM32_SYSCLK
301 #pragma GCC diagnostic push
302 #pragma GCC diagnostic ignored "-Wdouble-promotion"
303  chprintf(lchp, "Main STM32_SYSCLK frequency %.2f Mhz\r\n", STM32_SYSCLK/1e6f);
304 #pragma GCC diagnostic pop
305 #endif
306 
307 #ifdef CH_PORT_INFO
308  chprintf(lchp, "Port Info: %s\r\n", CH_PORT_INFO);
309 #endif
310 #ifdef PORT_INFO
311  chprintf(lchp, "Port Info: %s\r\n", PORT_INFO);
312 #endif
313 
314 #ifdef PLATFORM_NAME
315  chprintf(lchp, "Platform: %s\r\n", PLATFORM_NAME);
316 #endif
317 
318 #ifdef BOARD_NAME
319  chprintf(lchp, "Board: %s\r\n", BOARD_NAME);
320 #endif
321 
322  chprintf(lchp, "Chip Revision: %s REV '%c' (0x%x:0x%x)\r\n", mcu_devid_str, mcu_revid_chr, mcu_devid, mcu_revid);
323 
324 #if (!defined STM32_USE_REVISION_A_FIX) || (STM32_USE_REVISION_A_FIX == 0)
325  if ((mcu_devid == 0x413) && (mcu_revid_chr == 'A')) {
326  chprintf(lchp, "Chip Revision: %s REV '%c' PLEASE define STM32_USE_REVISION_A_FIX in mcuconf.h !!\r\n",
327  mcu_devid_str, mcu_revid_chr);
328  }
329 #endif
330 
331 #ifdef __DATE__
332 #ifdef __TIME__
333  chprintf(lchp, "Build time: %s%s%s\r\n", __DATE__, " - ", __TIME__);
334 #endif
335 #endif
336 
337  chprintf(lchp, "systime= %lu\r\n", (unsigned long)chVTGetSystemTimeX());
338 }
339 
340 
350 static THD_FUNCTION(shell_thread, p) {
351  msg_t msg = MSG_OK;
352  chpg = ((ShellConfig *)p)->sc_channel;
353  staticCommands = ((ShellConfig *)p)->sc_commands;
354 
355  chRegSetThreadName("Enhanced_shell");
356  printScreen ("ChibiOS/RT Enhanced Shell");
357  while (!chThdShouldTerminateX()) {
358  uint8_t c;
359  if (streamRead(chpg, &c, 1) > 0) {
360  if (altCbParam.altFunc == NULL) {
361  microrl_insert_char (&rl, c);
362  } else {
364  }
365  }
366  }
367  /* Atomically broadcasting the event source and terminating the thread,
368  there is not a chSysUnlock() because the thread terminates upon return.*/
369  printScreen ("exit");
370  chSysLock();
371  chEvtBroadcastI(&shell_terminated);
372  chThdExitS(msg);
373 }
374 
378 void shellInit(void) {
379  chEvtObjectInit(&shell_terminated);
384 }
385 
396 #if CH_CFG_USE_HEAP && CH_CFG_USE_DYNAMIC
397 thread_t *shellCreateFromHeap(const ShellConfig *scp, size_t size, tprio_t prio) {
398  return chThdCreateFromHeap(NULL, size, "shell", prio, shell_thread, (void *)scp);
399 }
400 #endif
401 
402 
412  thread_t *shellCreateStatic(const ShellConfig *scp, void *wsp,
413  size_t size, tprio_t prio) {
414  return chThdCreateStatic(wsp, size, prio, shell_thread, (void *)scp);
415 }
416 
417 #if SHELL_DYNAMIC_ENTRIES_NUMBER
418 
427 bool shellAddEntry(const ShellCommand sc)
428 {
430  static const int len = (sizeof(localCommands) / sizeof(localCommands[0]))
431  -1U;
432  chMtxLock(&mut);
433  while ((lcp->sc_function != NULL) &&
434  (strcmp(lcp->sc_name, sc.sc_name) != 0) &&
435  ((lcp - localCommands) < len))
436  lcp++;
437 
438  if ((lcp - localCommands) == len) {
439  chMtxUnlock(&mut);
440  return false;
441  }
442  lcp->sc_function = sc.sc_function;
443  lcp->sc_name = sc.sc_function == NULL ? NULL : sc.sc_name;
444  *(++lcp) = (ShellCommand){NULL, NULL};
445 
446  chMtxUnlock(&mut);
447  return true;
448 }
449 #endif
450 
451 void modeAlternate(void (*funcp) (uint8_t c, uint32_t mode), uint32_t mode)
452 {
453  chMtxLock(&mut);
454  altCbParam.altFunc = funcp;
456  chMtxUnlock(&mut);
457 }
458 
459 void modeShell(void)
460 {
461  chMtxLock(&mut);
462  altCbParam.altFunc = NULL;
463  chMtxUnlock(&mut);
464  printScreen ("retour au shell");
465 }
466 
467 
468 
MUTEX_DECL
static MUTEX_DECL(mut)
uint32_t
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
uint8_t
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98
shellInit
void shellInit(void)
Shell manager initialization.
Definition: microrlShell.c:378
modeAlternate
void modeAlternate(void(*funcp)(uint8_t c, uint32_t mode), uint32_t mode)
Definition: microrlShell.c:451
usage
static void usage(BaseSequentialStream *lchp, char *p)
Definition: microrlShell.c:137
chprintf
void chprintf(BaseSequentialStream *lchp, const char *fmt,...)
Definition: printf.c:395
AltCbParam::altFunc
void(* altFunc)(uint8_t c, uint32_t mode)
Definition: microrlShell.c:19
microrl_t
Definition: microrl.h:65
shellCreateStatic
thread_t * shellCreateStatic(const ShellConfig *scp, void *wsp, size_t size, tprio_t prio)
Spawns a new shell.
Definition: microrlShell.c:412
BOARD_NAME
#define BOARD_NAME
Definition: board.h:37
microrlSigint
void microrlSigint(void)
Definition: microrlShell.c:131
microrlComplet
const char ** microrlComplet(int argc, const char *const *argv)
Definition: microrlShell.c:88
msg
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
Definition: high_speed_logger_direct_memory.c:134
THD_FUNCTION
static THD_FUNCTION(shell_thread, p)
Shell thread function.
Definition: microrlShell.c:350
printf.h
Mini printf-like functionality.
ShellCommand
Custom command entry type.
Definition: microrlShell.h:30
localCommands
static const ShellCommand localCommands[]
Array of the default and dynamic commands.
Definition: microrlShell.c:43
altCbParam
static AltCbParam altCbParam
Definition: microrlShell.c:49
staticCommands
static const ShellCommand * staticCommands
Definition: microrlShell.c:35
AltCbParam::param
uint32_t param
Definition: microrlShell.c:20
microrl_set_complete_callback
void microrl_set_complete_callback(microrl_t *pThis, const char **(*get_completion)(int, const char *const *))
Definition: microrl.c:353
shell_terminated
event_source_t shell_terminated
Shell termination event source.
Definition: microrlShell.c:30
mut
static pthread_mutex_t mut
Definition: catia.c:23
microrlExecute
void microrlExecute(int argc, const char *const *argv)
Definition: microrlShell.c:60
SHELL_DYNAMIC_ENTRIES_NUMBER
#define SHELL_DYNAMIC_ENTRIES_NUMBER
Definition: microrlShell.h:15
complWorlds
static const char * complWorlds[64]
Definition: microrlShell.c:36
modeShell
void modeShell(void)
Definition: microrlShell.c:459
AltCbParam
Definition: microrlShell.c:18
chpg
static BaseSequentialStream * chpg
Definition: microrlShell.c:34
microrl_init
void microrl_init(microrl_t *pThis, void(*print)(const char *))
Definition: microrl.c:329
cmd_info
static void cmd_info(BaseSequentialStream *lchp, int argc, const char *const argv[])
Definition: microrlShell.c:144
microrlShell.h
Simple CLI shell header.
ShellConfig
Shell descriptor type.
Definition: microrlShell.h:38
rl
static microrl_t rl
Definition: microrlShell.c:33
ShellCommand::sc_function
shellcmd_f * sc_function
Command function.
Definition: microrlShell.h:32
STM32_SYSCLK
#define STM32_SYSCLK
Definition: sys_time_arch.c:43
ShellCommand::sc_name
const char * sc_name
Command name.
Definition: microrlShell.h:31
printScreen
#define printScreen(...)
Definition: microrlShell.c:16
microrl_set_execute_callback
void microrl_set_execute_callback(microrl_t *pThis, void(*execute)(int, const char *const *))
Definition: microrl.c:360
mode
static uint8_t mode
mode holds the current sonar mode mode = 0 used at high altitude, uses 16 wave patterns mode = 1 used...
Definition: sonar_bebop.c:69
microrl_insert_char
void microrl_insert_char(microrl_t *pThis, int ch)
Definition: microrl.c:576
microrl.h
uint16_t
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
microrl_set_sigint_callback
void microrl_set_sigint_callback(microrl_t *pThis, void(*sigintf)(void))
Definition: microrl.c:366
p
static float p[2][2]
Definition: ins_alt_float.c:268
microrlPrint
void microrlPrint(const char *str)
Definition: microrlShell.c:51