diff options
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/K32L2A31A/utilities/fsl_shell.c')
-rw-r--r-- | lib/chibios-contrib/ext/mcux-sdk/devices/K32L2A31A/utilities/fsl_shell.c | 1085 |
1 files changed, 1085 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/K32L2A31A/utilities/fsl_shell.c b/lib/chibios-contrib/ext/mcux-sdk/devices/K32L2A31A/utilities/fsl_shell.c new file mode 100644 index 000000000..2cc75f02e --- /dev/null +++ b/lib/chibios-contrib/ext/mcux-sdk/devices/K32L2A31A/utilities/fsl_shell.c | |||
@@ -0,0 +1,1085 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015, Freescale Semiconductor, Inc. | ||
3 | * Copyright 2016-2020 NXP | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * SPDX-License-Identifier: BSD-3-Clause | ||
7 | * | ||
8 | * POSIX getopt for Windows | ||
9 | * Code given out at the 1985 UNIFORUM conference in Dallas. | ||
10 | * | ||
11 | * From [email protected] (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985 | ||
12 | * Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET | ||
13 | * Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP | ||
14 | * Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix | ||
15 | * From: [email protected] (Moderator, John Quarterman) | ||
16 | * Newsgroups: mod.std.unix | ||
17 | * Subject: public domain AT&T getopt source | ||
18 | * Message-ID: <[email protected]> | ||
19 | * Date: 3 Nov 85 19:34:15 GMT | ||
20 | * Date-Received: 4 Nov 85 12:25:09 GMT | ||
21 | * Organization: IEEE/P1003 Portable Operating System Environment Committee | ||
22 | * Lines: 91 | ||
23 | * Approved: [email protected] | ||
24 | * Here's something you've all been waiting for: the AT&T public domain | ||
25 | * source for getopt(3). It is the code which was given out at the 1985 | ||
26 | * UNIFORUM conference in Dallas. I obtained it by electronic mail | ||
27 | * directly from AT&T. The people there assure me that it is indeed | ||
28 | * in the public domain | ||
29 | * There is no manual page. That is because the one they gave out at | ||
30 | * UNIFORUM was slightly different from the current System V Release 2 | ||
31 | * manual page. The difference apparently involved a note about the | ||
32 | * famous rules 5 and 6, recommending using white space between an option | ||
33 | * and its first argument, and not grouping options that have arguments. | ||
34 | * Getopt itself is currently lenient about both of these things White | ||
35 | * space is allowed, but not mandatory, and the last option in a group can | ||
36 | * have an argument. That particular version of the man page evidently | ||
37 | * has no official existence, and my source at AT&T did not send a copy. | ||
38 | * The current SVR2 man page reflects the actual behavor of this getopt. | ||
39 | * However, I am not about to post a copy of anything licensed by AT&T. | ||
40 | */ | ||
41 | |||
42 | #include <assert.h> | ||
43 | #include <stdarg.h> | ||
44 | #include <stdlib.h> | ||
45 | #include <stdio.h> | ||
46 | |||
47 | #include "fsl_common.h" | ||
48 | #include "fsl_str.h" | ||
49 | |||
50 | #include "fsl_component_generic_list.h" | ||
51 | #include "fsl_component_serial_manager.h" | ||
52 | |||
53 | #include "fsl_shell.h" | ||
54 | |||
55 | /* | ||
56 | * The OSA_USED macro can only be defined when the OSA component is used. | ||
57 | * If the source code of the OSA component does not exist, the OSA_USED cannot be defined. | ||
58 | * OR, If OSA component is not added into project event the OSA source code exists, the OSA_USED | ||
59 | * also cannot be defined. | ||
60 | * The source code path of the OSA component is <MCUXpresso_SDK>/components/osa. | ||
61 | * | ||
62 | */ | ||
63 | #if defined(OSA_USED) | ||
64 | |||
65 | #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U)) | ||
66 | #include "fsl_component_common_task.h" | ||
67 | #else | ||
68 | #include "fsl_os_abstraction.h" | ||
69 | #endif | ||
70 | |||
71 | #endif | ||
72 | |||
73 | /******************************************************************************* | ||
74 | * Definitions | ||
75 | ******************************************************************************/ | ||
76 | #define KEY_ESC (0x1BU) | ||
77 | #define KET_DEL (0x7FU) | ||
78 | |||
79 | #define SHELL_EVENT_DATA_ARRIVED (1U << 0) | ||
80 | #define SHELL_EVENT_DATA_SENT (1U << 1) | ||
81 | |||
82 | #define SHELL_SPRINTF_BUFFER_SIZE (64U) | ||
83 | |||
84 | /*! @brief A type for the handle special key. */ | ||
85 | typedef enum _fun_key_status | ||
86 | { | ||
87 | kSHELL_Normal = 0U, /*!< Normal key */ | ||
88 | kSHELL_Special = 1U, /*!< Special key */ | ||
89 | kSHELL_Function = 2U, /*!< Function key */ | ||
90 | } fun_key_status_t; | ||
91 | |||
92 | /*! @brief Data structure for Shell environment. */ | ||
93 | typedef struct _shell_context_handle | ||
94 | { | ||
95 | list_label_t commandContextListHead; /*!< Command shellContextHandle list queue head */ | ||
96 | serial_handle_t serialHandle; /*!< Serial manager handle */ | ||
97 | uint8_t | ||
98 | serialWriteHandleBuffer[SERIAL_MANAGER_WRITE_HANDLE_SIZE]; /*!< The buffer for serial manager write handle */ | ||
99 | serial_write_handle_t serialWriteHandle; /*!< The serial manager write handle */ | ||
100 | uint8_t serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE]; /*!< The buffer for serial manager read handle */ | ||
101 | serial_read_handle_t serialReadHandle; /*!< The serial manager read handle */ | ||
102 | char *prompt; /*!< Prompt string */ | ||
103 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
104 | |||
105 | #if defined(OSA_USED) | ||
106 | |||
107 | #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U)) | ||
108 | common_task_message_t commontaskMsg; /*!< Message for common task */ | ||
109 | #else | ||
110 | uint8_t event[OSA_EVENT_HANDLE_SIZE]; /*!< Event instance */ | ||
111 | uint8_t taskId[OSA_TASK_HANDLE_SIZE]; /*!< Task handle */ | ||
112 | #endif | ||
113 | |||
114 | #endif | ||
115 | |||
116 | #endif | ||
117 | char line[SHELL_BUFFER_SIZE]; /*!< Consult buffer */ | ||
118 | char hist_buf[SHELL_HISTORY_COUNT][SHELL_BUFFER_SIZE]; /*!< History buffer*/ | ||
119 | char printBuffer[SHELL_SPRINTF_BUFFER_SIZE]; /*!< Buffer for print */ | ||
120 | uint32_t printLength; /*!< All length has been printed */ | ||
121 | uint16_t hist_current; /*!< Current history command in hist buff*/ | ||
122 | uint16_t hist_count; /*!< Total history command in hist buff*/ | ||
123 | enum _fun_key_status stat; /*!< Special key status */ | ||
124 | uint8_t cmd_num; /*!< Number of user commands */ | ||
125 | uint8_t l_pos; /*!< Total line position */ | ||
126 | uint8_t c_pos; /*!< Current line position */ | ||
127 | volatile uint8_t notificationPost; /*!< The serial manager notification is post */ | ||
128 | uint8_t exit; /*!< Exit Flag*/ | ||
129 | uint8_t printBusy; /*!< Print is busy */ | ||
130 | } shell_context_handle_t; | ||
131 | |||
132 | #if 0 | ||
133 | #define SHELL_STRUCT_OFFSET(type, field) ((size_t) & (((type *)0)->field)) | ||
134 | #define SHEEL_COMMAND_POINTER(node) \ | ||
135 | ((shell_command_t *)(((uint32_t)(node)) - SHELL_STRUCT_OFFSET(shell_command_t, link))) | ||
136 | #else | ||
137 | #define SHEEL_COMMAND_POINTER(node) \ | ||
138 | ((shell_command_t *)(((uint32_t)(node)) - (sizeof(shell_command_t) - sizeof(list_element_t)))) | ||
139 | #endif | ||
140 | /******************************************************************************* | ||
141 | * Prototypes | ||
142 | ******************************************************************************/ | ||
143 | static shell_status_t SHELL_HelpCommand(shell_handle_t shellHandle, int32_t argc, char **argv); /*!< help command */ | ||
144 | |||
145 | static shell_status_t SHELL_ExitCommand(shell_handle_t shellHandle, int32_t argc, char **argv); /*!< exit command */ | ||
146 | |||
147 | static int32_t SHELL_ParseLine(const char *cmd, uint32_t len, char *argv[]); /*!< parse line command */ | ||
148 | |||
149 | static int32_t SHELL_StringCompare(const char *str1, const char *str2, int32_t count); /*!< compare string command */ | ||
150 | |||
151 | static void SHELL_ProcessCommand(shell_context_handle_t *shellContextHandle, const char *cmd); /*!< process a command */ | ||
152 | |||
153 | static void SHELL_GetHistoryCommand(shell_context_handle_t *shellContextHandle, | ||
154 | uint8_t hist_pos); /*!< get commands history */ | ||
155 | |||
156 | static void SHELL_AutoComplete(shell_context_handle_t *shellContextHandle); /*!< auto complete command */ | ||
157 | |||
158 | static shell_status_t SHELL_GetChar(shell_context_handle_t *shellContextHandle, | ||
159 | uint8_t *ch); /*!< get a char from communication interface */ | ||
160 | |||
161 | static void SHELL_WriteWithCopy(shell_handle_t shellHandle, const char *buffer, uint32_t length); | ||
162 | |||
163 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
164 | static void SHELL_Task(void *param); /*!< Shell task*/ | ||
165 | #endif | ||
166 | |||
167 | /******************************************************************************* | ||
168 | * Variables | ||
169 | ******************************************************************************/ | ||
170 | |||
171 | static SHELL_COMMAND_DEFINE(help, "\r\n\"help\": List all the registered commands\r\n", SHELL_HelpCommand, 0); | ||
172 | static SHELL_COMMAND_DEFINE(exit, "\r\n\"exit\": Exit program\r\n", SHELL_ExitCommand, 0); | ||
173 | |||
174 | static char s_paramBuffer[SHELL_BUFFER_SIZE]; | ||
175 | |||
176 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
177 | #if defined(OSA_USED) | ||
178 | #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U)) | ||
179 | #else | ||
180 | /* | ||
181 | * \brief Defines the serial manager task's stack | ||
182 | */ | ||
183 | static OSA_TASK_DEFINE(SHELL_Task, SHELL_TASK_PRIORITY, 1, SHELL_TASK_STACK_SIZE, false); | ||
184 | #endif | ||
185 | #endif /* OSA_USED */ | ||
186 | #endif /* SHELL_NON_BLOCKING_MODE */ | ||
187 | /******************************************************************************* | ||
188 | * Code | ||
189 | ******************************************************************************/ | ||
190 | |||
191 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
192 | static void SHELL_SerialManagerRxCallback(void *callbackParam, | ||
193 | serial_manager_callback_message_t *message, | ||
194 | serial_manager_status_t status) | ||
195 | { | ||
196 | shell_context_handle_t *shellHandle; | ||
197 | |||
198 | assert(callbackParam); | ||
199 | assert(message); | ||
200 | |||
201 | shellHandle = (shell_context_handle_t *)callbackParam; | ||
202 | |||
203 | if (0U == shellHandle->notificationPost) | ||
204 | { | ||
205 | shellHandle->notificationPost = 1U; | ||
206 | #if defined(OSA_USED) | ||
207 | |||
208 | #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U)) | ||
209 | shellHandle->commontaskMsg.callback = SHELL_Task; | ||
210 | shellHandle->commontaskMsg.callbackParam = shellHandle; | ||
211 | (void)COMMON_TASK_post_message(&shellHandle->commontaskMsg); | ||
212 | #else | ||
213 | (void)OSA_EventSet((osa_event_handle_t)shellHandle->event, SHELL_EVENT_DATA_ARRIVED); | ||
214 | #endif | ||
215 | |||
216 | #else | ||
217 | SHELL_Task(shellHandle); | ||
218 | #endif | ||
219 | } | ||
220 | } | ||
221 | #endif | ||
222 | |||
223 | static void SHELL_WriteBuffer(char *buffer, int32_t *indicator, char val, int len) | ||
224 | { | ||
225 | shell_context_handle_t *shellContextHandle; | ||
226 | int i = 0; | ||
227 | shellContextHandle = (shell_context_handle_t *)(void *)buffer; | ||
228 | |||
229 | for (i = 0; i < len; i++) | ||
230 | { | ||
231 | if ((*indicator + 1) >= (int32_t)SHELL_SPRINTF_BUFFER_SIZE) | ||
232 | { | ||
233 | #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1))) | ||
234 | if (NULL == shellContextHandle->serialHandle) | ||
235 | { | ||
236 | for (uint32_t index = 0; index < ((uint32_t)*indicator); index++) | ||
237 | { | ||
238 | (void)putchar(shellContextHandle->printBuffer[index]); | ||
239 | } | ||
240 | } | ||
241 | else | ||
242 | #endif | ||
243 | { | ||
244 | (void)SerialManager_WriteBlocking(shellContextHandle->serialWriteHandle, | ||
245 | (uint8_t *)shellContextHandle->printBuffer, (uint32_t)*indicator); | ||
246 | } | ||
247 | |||
248 | shellContextHandle->printLength += (uint32_t)*indicator; | ||
249 | *indicator = 0; | ||
250 | } | ||
251 | |||
252 | shellContextHandle->printBuffer[*indicator] = val; | ||
253 | (*indicator)++; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | static int SHELL_Sprintf(void *buffer, const char *formatString, va_list ap) | ||
258 | { | ||
259 | shell_context_handle_t *shellContextHandle; | ||
260 | uint32_t length; | ||
261 | shellContextHandle = (shell_context_handle_t *)buffer; | ||
262 | |||
263 | length = (uint32_t)StrFormatPrintf(formatString, ap, (char *)buffer, SHELL_WriteBuffer); | ||
264 | shellContextHandle->printLength += length; | ||
265 | return (int32_t)length; | ||
266 | } | ||
267 | |||
268 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
269 | static void SHELL_Task(void *param) | ||
270 | #else | ||
271 | void SHELL_Task(shell_handle_t shellHandle) | ||
272 | #endif | ||
273 | { | ||
274 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
275 | shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)param; | ||
276 | #else | ||
277 | shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)shellHandle; | ||
278 | #endif | ||
279 | uint8_t ch; | ||
280 | |||
281 | if (NULL != shellContextHandle) | ||
282 | { | ||
283 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
284 | |||
285 | #if defined(OSA_USED) | ||
286 | |||
287 | #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U)) | ||
288 | #else | ||
289 | osa_event_flags_t ev = 0; | ||
290 | |||
291 | do | ||
292 | { | ||
293 | if (KOSA_StatusSuccess == OSA_EventWait((osa_event_handle_t)shellContextHandle->event, osaEventFlagsAll_c, | ||
294 | 0U, osaWaitForever_c, &ev)) | ||
295 | { | ||
296 | if (0U != (ev & SHELL_EVENT_DATA_ARRIVED)) | ||
297 | #endif | ||
298 | |||
299 | #endif | ||
300 | |||
301 | #endif | ||
302 | { | ||
303 | shellContextHandle->notificationPost = 0; | ||
304 | do | ||
305 | { | ||
306 | if ((bool)shellContextHandle->exit) | ||
307 | { | ||
308 | if (shellContextHandle->serialReadHandle != NULL) | ||
309 | { | ||
310 | (void)SerialManager_CloseReadHandle(shellContextHandle->serialReadHandle); | ||
311 | shellContextHandle->serialReadHandle = NULL; | ||
312 | } | ||
313 | if (shellContextHandle->serialWriteHandle != NULL) | ||
314 | { | ||
315 | (void)SerialManager_CloseWriteHandle(shellContextHandle->serialWriteHandle); | ||
316 | shellContextHandle->serialWriteHandle = NULL; | ||
317 | } | ||
318 | break; | ||
319 | } | ||
320 | if (kStatus_SHELL_Success != (shell_status_t)SHELL_GetChar(shellContextHandle, &ch)) | ||
321 | { | ||
322 | /* If error occurred when getting a char, exit the task and waiting the new data arriving. */ | ||
323 | break; | ||
324 | } | ||
325 | |||
326 | /* Special key */ | ||
327 | if (ch == KEY_ESC) | ||
328 | { | ||
329 | shellContextHandle->stat = kSHELL_Special; | ||
330 | continue; | ||
331 | } | ||
332 | else if (shellContextHandle->stat == kSHELL_Special) | ||
333 | { | ||
334 | /* Function key */ | ||
335 | if ((char)ch == '[') | ||
336 | { | ||
337 | shellContextHandle->stat = kSHELL_Function; | ||
338 | continue; | ||
339 | } | ||
340 | shellContextHandle->stat = kSHELL_Normal; | ||
341 | } | ||
342 | else if (shellContextHandle->stat == kSHELL_Function) | ||
343 | { | ||
344 | shellContextHandle->stat = kSHELL_Normal; | ||
345 | |||
346 | switch ((char)ch) | ||
347 | { | ||
348 | /* History operation here */ | ||
349 | case 'A': /* Up key */ | ||
350 | SHELL_GetHistoryCommand(shellContextHandle, (uint8_t)shellContextHandle->hist_current); | ||
351 | if (shellContextHandle->hist_current < (shellContextHandle->hist_count - 1U)) | ||
352 | { | ||
353 | shellContextHandle->hist_current++; | ||
354 | } | ||
355 | break; | ||
356 | case 'B': /* Down key */ | ||
357 | SHELL_GetHistoryCommand(shellContextHandle, (uint8_t)shellContextHandle->hist_current); | ||
358 | if (shellContextHandle->hist_current > 0U) | ||
359 | { | ||
360 | shellContextHandle->hist_current--; | ||
361 | } | ||
362 | break; | ||
363 | case 'D': /* Left key */ | ||
364 | if ((bool)shellContextHandle->c_pos) | ||
365 | { | ||
366 | SHELL_WriteWithCopy(shellContextHandle, "\b", 1); | ||
367 | shellContextHandle->c_pos--; | ||
368 | } | ||
369 | break; | ||
370 | case 'C': /* Right key */ | ||
371 | if (shellContextHandle->c_pos < shellContextHandle->l_pos) | ||
372 | { | ||
373 | (void)SHELL_Write(shellContextHandle, | ||
374 | &shellContextHandle->line[shellContextHandle->c_pos], 1); | ||
375 | shellContextHandle->c_pos++; | ||
376 | } | ||
377 | break; | ||
378 | default: | ||
379 | /* MISRA C-2012 Rule 16.4 */ | ||
380 | break; | ||
381 | } | ||
382 | continue; | ||
383 | } | ||
384 | /* Handle tab key */ | ||
385 | else if ((char)ch == '\t') | ||
386 | { | ||
387 | #if SHELL_AUTO_COMPLETE | ||
388 | /* Move the cursor to the beginning of line */ | ||
389 | uint32_t i; | ||
390 | for (i = 0; i < (uint32_t)shellContextHandle->c_pos; i++) | ||
391 | { | ||
392 | SHELL_WriteWithCopy(shellContextHandle, "\b", 1); | ||
393 | } | ||
394 | /* Do auto complete */ | ||
395 | SHELL_AutoComplete(shellContextHandle); | ||
396 | /* Move position to end */ | ||
397 | shellContextHandle->l_pos = (uint8_t)strlen(shellContextHandle->line); | ||
398 | shellContextHandle->c_pos = shellContextHandle->l_pos; | ||
399 | #endif | ||
400 | continue; | ||
401 | } | ||
402 | /* Handle backspace key */ | ||
403 | else if ((ch == KET_DEL) || ((char)ch == '\b')) | ||
404 | { | ||
405 | /* There must be at last one char */ | ||
406 | if (shellContextHandle->c_pos == 0U) | ||
407 | { | ||
408 | continue; | ||
409 | } | ||
410 | |||
411 | shellContextHandle->l_pos--; | ||
412 | shellContextHandle->c_pos--; | ||
413 | |||
414 | if (shellContextHandle->l_pos > shellContextHandle->c_pos) | ||
415 | { | ||
416 | (void)memmove(&shellContextHandle->line[shellContextHandle->c_pos], | ||
417 | &shellContextHandle->line[shellContextHandle->c_pos + 1U], | ||
418 | (uint32_t)shellContextHandle->l_pos - (uint32_t)shellContextHandle->c_pos); | ||
419 | shellContextHandle->line[shellContextHandle->l_pos] = '\0'; | ||
420 | SHELL_WriteWithCopy(shellContextHandle, "\b", 1); | ||
421 | (void)SHELL_Write(shellContextHandle, &shellContextHandle->line[shellContextHandle->c_pos], | ||
422 | strlen(&shellContextHandle->line[shellContextHandle->c_pos])); | ||
423 | SHELL_WriteWithCopy(shellContextHandle, " \b", 3); | ||
424 | |||
425 | /* Reset position */ | ||
426 | uint32_t i; | ||
427 | for (i = (uint32_t)shellContextHandle->c_pos; i <= (uint32_t)shellContextHandle->l_pos; i++) | ||
428 | { | ||
429 | SHELL_WriteWithCopy(shellContextHandle, "\b", 1); | ||
430 | } | ||
431 | } | ||
432 | else /* Normal backspace operation */ | ||
433 | { | ||
434 | SHELL_WriteWithCopy(shellContextHandle, "\b \b", 3); | ||
435 | shellContextHandle->line[shellContextHandle->l_pos] = '\0'; | ||
436 | } | ||
437 | continue; | ||
438 | } | ||
439 | else | ||
440 | { | ||
441 | /* MISRA C-2012 Rule 15.7 */ | ||
442 | } | ||
443 | |||
444 | /* Input too long */ | ||
445 | if (shellContextHandle->l_pos >= (SHELL_BUFFER_SIZE - 1U)) | ||
446 | { | ||
447 | shellContextHandle->l_pos = 0U; | ||
448 | } | ||
449 | |||
450 | /* Handle end of line, break */ | ||
451 | if (((char)ch == '\r') || ((char)ch == '\n')) | ||
452 | { | ||
453 | static char endoflinechar = '\0'; | ||
454 | |||
455 | if (((uint8_t)endoflinechar != 0U) && ((uint8_t)endoflinechar != ch)) | ||
456 | { | ||
457 | continue; | ||
458 | } | ||
459 | else | ||
460 | { | ||
461 | endoflinechar = (char)ch; | ||
462 | /* Print new line. */ | ||
463 | SHELL_WriteWithCopy(shellContextHandle, "\r\n", 2U); /* MISRA C-2012 Rule 7.4 */ | ||
464 | /* If command line is not NULL, will start process it. */ | ||
465 | if (0U != strlen(shellContextHandle->line)) | ||
466 | { | ||
467 | SHELL_ProcessCommand(shellContextHandle, shellContextHandle->line); | ||
468 | } | ||
469 | /* Print prompt. */ | ||
470 | (void)SHELL_Write(shellContextHandle, shellContextHandle->prompt, | ||
471 | strlen(shellContextHandle->prompt)); | ||
472 | /* Reset all params */ | ||
473 | shellContextHandle->c_pos = shellContextHandle->l_pos = 0; | ||
474 | shellContextHandle->hist_current = 0; | ||
475 | (void)memset(shellContextHandle->line, 0, sizeof(shellContextHandle->line)); | ||
476 | continue; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | /* Normal character */ | ||
481 | if (shellContextHandle->c_pos < shellContextHandle->l_pos) | ||
482 | { | ||
483 | (void)memmove(&shellContextHandle->line[shellContextHandle->c_pos + 1U], | ||
484 | &shellContextHandle->line[shellContextHandle->c_pos], | ||
485 | (uint32_t)shellContextHandle->l_pos - (uint32_t)shellContextHandle->c_pos); | ||
486 | shellContextHandle->line[shellContextHandle->c_pos] = (char)ch; | ||
487 | (void)SHELL_Write(shellContextHandle, &shellContextHandle->line[shellContextHandle->c_pos], | ||
488 | strlen(&shellContextHandle->line[shellContextHandle->c_pos])); | ||
489 | /* Move the cursor to new position */ | ||
490 | uint32_t i; | ||
491 | for (i = (uint32_t)shellContextHandle->c_pos; i < (uint32_t)shellContextHandle->l_pos; i++) | ||
492 | { | ||
493 | SHELL_WriteWithCopy(shellContextHandle, "\b", 1); | ||
494 | } | ||
495 | } | ||
496 | else | ||
497 | { | ||
498 | shellContextHandle->line[shellContextHandle->l_pos] = (char)ch; | ||
499 | (void)SHELL_Write(shellContextHandle, &shellContextHandle->line[shellContextHandle->l_pos], 1); | ||
500 | } | ||
501 | |||
502 | ch = 0; | ||
503 | shellContextHandle->l_pos++; | ||
504 | shellContextHandle->c_pos++; | ||
505 | } while (0U == shellContextHandle->exit); | ||
506 | } | ||
507 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
508 | |||
509 | #if defined(OSA_USED) | ||
510 | |||
511 | #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U)) | ||
512 | #else | ||
513 | } | ||
514 | } while (1U == gUseRtos_c); /* USE_RTOS = 0 for BareMetal and 1 for OS */ | ||
515 | #endif | ||
516 | |||
517 | #endif | ||
518 | |||
519 | #endif | ||
520 | } | ||
521 | } | ||
522 | |||
523 | static shell_status_t SHELL_HelpCommand(shell_handle_t shellHandle, int32_t argc, char **argv) | ||
524 | { | ||
525 | shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)shellHandle; | ||
526 | shell_command_t *shellCommandContextHandle; | ||
527 | list_element_handle_t p = LIST_GetHead(&shellContextHandle->commandContextListHead); | ||
528 | |||
529 | while (p != NULL) | ||
530 | { | ||
531 | shellCommandContextHandle = SHEEL_COMMAND_POINTER(p); | ||
532 | if ((shellCommandContextHandle->pcHelpString != NULL) && (bool)strlen(shellCommandContextHandle->pcHelpString)) | ||
533 | { | ||
534 | (void)SHELL_Write(shellContextHandle, shellCommandContextHandle->pcHelpString, | ||
535 | strlen(shellCommandContextHandle->pcHelpString)); | ||
536 | } | ||
537 | |||
538 | p = LIST_GetNext(p); | ||
539 | } | ||
540 | return kStatus_SHELL_Success; | ||
541 | } | ||
542 | |||
543 | static shell_status_t SHELL_ExitCommand(shell_handle_t shellHandle, int32_t argc, char **argv) | ||
544 | { | ||
545 | shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)shellHandle; | ||
546 | /* Skip warning */ | ||
547 | SHELL_WriteWithCopy(shellContextHandle, "\r\nSHELL exited\r\n", strlen("\r\nSHELL exited\r\n")); | ||
548 | shellContextHandle->exit = (uint8_t) true; | ||
549 | return kStatus_SHELL_Success; | ||
550 | } | ||
551 | |||
552 | static void SHELL_ProcessCommand(shell_context_handle_t *shellContextHandle, const char *cmd) | ||
553 | { | ||
554 | shell_command_t *tmpCommand = NULL; | ||
555 | const char *tmpCommandString; | ||
556 | int32_t argc; | ||
557 | char *argv[SHELL_BUFFER_SIZE] = {0}; | ||
558 | list_element_handle_t p; | ||
559 | uint8_t flag = 1; | ||
560 | uint8_t tmpCommandLen; | ||
561 | uint8_t tmpLen; | ||
562 | uint8_t i = 0; | ||
563 | |||
564 | tmpLen = (uint8_t)strlen(cmd); | ||
565 | argc = SHELL_ParseLine(cmd, tmpLen, argv); | ||
566 | |||
567 | if ((argc > 0)) | ||
568 | { | ||
569 | p = LIST_GetHead(&shellContextHandle->commandContextListHead); | ||
570 | while (p != NULL) | ||
571 | { | ||
572 | tmpCommand = SHEEL_COMMAND_POINTER(p); | ||
573 | tmpCommandString = tmpCommand->pcCommand; | ||
574 | tmpCommandLen = (uint8_t)strlen(tmpCommandString); | ||
575 | /* Compare with space or end of string */ | ||
576 | if ((cmd[tmpCommandLen] == ' ') || (cmd[tmpCommandLen] == (char)0x00)) | ||
577 | { | ||
578 | if (SHELL_StringCompare(tmpCommandString, argv[0], (int32_t)tmpCommandLen) == 0) | ||
579 | { | ||
580 | /* support commands with optional number of parameters */ | ||
581 | if (tmpCommand->cExpectedNumberOfParameters == (uint8_t)SHELL_IGNORE_PARAMETER_COUNT) | ||
582 | { | ||
583 | flag = 0; | ||
584 | } | ||
585 | else if ((tmpCommand->cExpectedNumberOfParameters == 0U) && (argc == 1)) | ||
586 | { | ||
587 | flag = 0; | ||
588 | } | ||
589 | else if (tmpCommand->cExpectedNumberOfParameters > 0U) | ||
590 | { | ||
591 | if ((argc - 1) == (int32_t)tmpCommand->cExpectedNumberOfParameters) | ||
592 | { | ||
593 | flag = 0; | ||
594 | } | ||
595 | } | ||
596 | else | ||
597 | { | ||
598 | flag = 1; | ||
599 | } | ||
600 | break; | ||
601 | } | ||
602 | } | ||
603 | p = LIST_GetNext(p); | ||
604 | } | ||
605 | if (NULL == p) | ||
606 | { | ||
607 | tmpCommand = NULL; | ||
608 | } | ||
609 | } | ||
610 | |||
611 | if ((tmpCommand != NULL) && (flag == 1U)) | ||
612 | { | ||
613 | SHELL_WriteWithCopy( | ||
614 | shellContextHandle, | ||
615 | "\r\nIncorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n", | ||
616 | strlen( | ||
617 | "\r\nIncorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n")); | ||
618 | } | ||
619 | else if (tmpCommand != NULL) | ||
620 | { | ||
621 | tmpLen = (uint8_t)strlen(cmd); | ||
622 | /* Compare with last command. Push back to history buffer if different */ | ||
623 | if (tmpLen != (uint8_t)SHELL_StringCompare(cmd, shellContextHandle->hist_buf[0], (int32_t)strlen(cmd))) | ||
624 | { | ||
625 | for (i = SHELL_HISTORY_COUNT - 1U; i > 0U; i--) | ||
626 | { | ||
627 | (void)memset(shellContextHandle->hist_buf[i], (int)'\0', SHELL_BUFFER_SIZE); | ||
628 | tmpLen = (uint8_t)strlen(shellContextHandle->hist_buf[i - 1U]); | ||
629 | (void)memcpy(shellContextHandle->hist_buf[i], shellContextHandle->hist_buf[i - 1U], tmpLen); | ||
630 | } | ||
631 | (void)memset(shellContextHandle->hist_buf[0], (int)'\0', SHELL_BUFFER_SIZE); | ||
632 | tmpLen = (uint8_t)strlen(cmd); | ||
633 | (void)memcpy(shellContextHandle->hist_buf[0], cmd, tmpLen); | ||
634 | if (shellContextHandle->hist_count < SHELL_HISTORY_COUNT) | ||
635 | { | ||
636 | shellContextHandle->hist_count++; | ||
637 | } | ||
638 | } | ||
639 | (void)tmpCommand->pFuncCallBack(shellContextHandle, argc, argv); | ||
640 | } | ||
641 | else | ||
642 | { | ||
643 | SHELL_WriteWithCopy( | ||
644 | shellContextHandle, | ||
645 | "\r\nCommand not recognized. Enter 'help' to view a list of available commands.\r\n\r\n", | ||
646 | strlen("\r\nCommand not recognized. Enter 'help' to view a list of available commands.\r\n\r\n")); | ||
647 | } | ||
648 | } | ||
649 | |||
650 | static void SHELL_GetHistoryCommand(shell_context_handle_t *shellContextHandle, uint8_t hist_pos) | ||
651 | { | ||
652 | uint32_t i; | ||
653 | uint32_t tmp; | ||
654 | |||
655 | if (shellContextHandle->hist_buf[0][0] == '\0') | ||
656 | { | ||
657 | shellContextHandle->hist_current = 0; | ||
658 | return; | ||
659 | } | ||
660 | |||
661 | #if 0 /*hist_pos is passed from hist_current. And hist_current is only changed in case 'A'/'B',as hist_count is 3 \ | ||
662 | most, it can't be more than 3 */ | ||
663 | if (hist_pos >= SHELL_HISTORY_COUNT) | ||
664 | { | ||
665 | hist_pos = SHELL_HISTORY_COUNT - 1U; | ||
666 | } | ||
667 | #endif | ||
668 | |||
669 | tmp = strlen(shellContextHandle->line); | ||
670 | /* Clear current if have */ | ||
671 | if (tmp > 0U) | ||
672 | { | ||
673 | (void)memset(shellContextHandle->line, (int)'\0', tmp); | ||
674 | for (i = 0U; i < tmp; i++) | ||
675 | { | ||
676 | SHELL_WriteWithCopy(shellContextHandle, "\b \b", 3); | ||
677 | } | ||
678 | } | ||
679 | |||
680 | shellContextHandle->l_pos = (uint8_t)strlen(shellContextHandle->hist_buf[hist_pos]); | ||
681 | shellContextHandle->c_pos = shellContextHandle->l_pos; | ||
682 | (void)memcpy(shellContextHandle->line, shellContextHandle->hist_buf[hist_pos], shellContextHandle->l_pos); | ||
683 | (void)SHELL_Write(shellContextHandle, shellContextHandle->hist_buf[hist_pos], | ||
684 | strlen(shellContextHandle->hist_buf[hist_pos])); | ||
685 | } | ||
686 | |||
687 | static void SHELL_AutoComplete(shell_context_handle_t *shellContextHandle) | ||
688 | { | ||
689 | int32_t minLen; | ||
690 | list_element_handle_t p; | ||
691 | shell_command_t *tmpCommand = NULL; | ||
692 | const char *namePtr; | ||
693 | const char *cmdName; | ||
694 | |||
695 | minLen = (int32_t)SHELL_BUFFER_SIZE; | ||
696 | namePtr = NULL; | ||
697 | |||
698 | /* Empty tab, list all commands */ | ||
699 | if (shellContextHandle->line[0] == '\0') | ||
700 | { | ||
701 | (void)SHELL_HelpCommand(shellContextHandle, 0, NULL); | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | SHELL_WriteWithCopy(shellContextHandle, "\r\n", 2); | ||
706 | |||
707 | /* Do auto complete */ | ||
708 | p = LIST_GetHead(&shellContextHandle->commandContextListHead); | ||
709 | while (p != NULL) | ||
710 | { | ||
711 | tmpCommand = SHEEL_COMMAND_POINTER(p); | ||
712 | cmdName = tmpCommand->pcCommand; | ||
713 | if (SHELL_StringCompare(shellContextHandle->line, cmdName, (int32_t)strlen(shellContextHandle->line)) == 0) | ||
714 | { | ||
715 | /* Show possible matches */ | ||
716 | (void)SHELL_Printf(shellContextHandle, "%s ", cmdName); | ||
717 | if (minLen > ((int32_t)strlen(cmdName))) | ||
718 | { | ||
719 | namePtr = cmdName; | ||
720 | minLen = (int32_t)strlen(namePtr); | ||
721 | } | ||
722 | } | ||
723 | p = LIST_GetNext(p); | ||
724 | } | ||
725 | /* Auto complete string */ | ||
726 | if (namePtr != NULL) | ||
727 | { | ||
728 | (void)memcpy(shellContextHandle->line, namePtr, (uint32_t)minLen); | ||
729 | } | ||
730 | SHELL_PrintPrompt(shellContextHandle); | ||
731 | (void)SHELL_Write(shellContextHandle, shellContextHandle->line, strlen(shellContextHandle->line)); | ||
732 | return; | ||
733 | } | ||
734 | |||
735 | static int32_t SHELL_StringCompare(const char *str1, const char *str2, int32_t count) | ||
736 | { | ||
737 | while ((bool)(count--)) | ||
738 | { | ||
739 | if (*str1++ != *str2++) | ||
740 | { | ||
741 | return (int32_t)(*(str1 - 1) - *(str2 - 1)); | ||
742 | } | ||
743 | } | ||
744 | return 0; | ||
745 | } | ||
746 | |||
747 | static int32_t SHELL_ParseLine(const char *cmd, uint32_t len, char *argv[]) | ||
748 | { | ||
749 | uint32_t argc; | ||
750 | char *p; | ||
751 | uint32_t position; | ||
752 | |||
753 | /* Init params */ | ||
754 | (void)memset(s_paramBuffer, (int)'\0', len + 1U); | ||
755 | (void)memcpy(s_paramBuffer, cmd, len); | ||
756 | |||
757 | p = s_paramBuffer; | ||
758 | position = 0; | ||
759 | argc = 0; | ||
760 | |||
761 | while (position < len) | ||
762 | { | ||
763 | /* Skip all blanks */ | ||
764 | while ((position < len) && ((char)(*p) == ' ')) | ||
765 | { | ||
766 | *p = '\0'; | ||
767 | p++; | ||
768 | position++; | ||
769 | } | ||
770 | |||
771 | if (position >= len) | ||
772 | { | ||
773 | break; | ||
774 | } | ||
775 | |||
776 | /* Process begin of a string */ | ||
777 | if (*p == '"') | ||
778 | { | ||
779 | p++; | ||
780 | position++; | ||
781 | argv[argc] = p; | ||
782 | argc++; | ||
783 | /* Skip this string */ | ||
784 | while ((*p != '"') && (position < len)) | ||
785 | { | ||
786 | p++; | ||
787 | position++; | ||
788 | } | ||
789 | /* Skip '"' */ | ||
790 | *p = '\0'; | ||
791 | p++; | ||
792 | position++; | ||
793 | } | ||
794 | else /* Normal char */ | ||
795 | { | ||
796 | argv[argc] = p; | ||
797 | argc++; | ||
798 | while (((char)*p != ' ') && (position < len)) | ||
799 | { | ||
800 | p++; | ||
801 | position++; | ||
802 | } | ||
803 | } | ||
804 | } | ||
805 | return (int32_t)argc; | ||
806 | } | ||
807 | |||
808 | static shell_status_t SHELL_GetChar(shell_context_handle_t *shellContextHandle, uint8_t *ch) | ||
809 | { | ||
810 | shell_status_t status; | ||
811 | |||
812 | #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1))) | ||
813 | if (NULL == shellContextHandle->serialHandle) | ||
814 | { | ||
815 | int ret; | ||
816 | ret = getchar(); | ||
817 | if (ret > 0) | ||
818 | { | ||
819 | *ch = (uint8_t)ret; | ||
820 | status = kStatus_SHELL_Success; | ||
821 | } | ||
822 | else | ||
823 | { | ||
824 | status = kStatus_SHELL_Error; | ||
825 | } | ||
826 | } | ||
827 | else | ||
828 | #endif | ||
829 | { | ||
830 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
831 | uint32_t length = 0; | ||
832 | |||
833 | (void)SerialManager_TryRead(shellContextHandle->serialReadHandle, ch, 1, &length); | ||
834 | |||
835 | if (length > 0U) | ||
836 | { | ||
837 | status = kStatus_SHELL_Success; | ||
838 | } | ||
839 | else | ||
840 | { | ||
841 | status = kStatus_SHELL_Error; | ||
842 | } | ||
843 | #else | ||
844 | status = (shell_status_t)SerialManager_ReadBlocking(shellContextHandle->serialReadHandle, ch, 1); | ||
845 | #endif | ||
846 | } | ||
847 | |||
848 | return status; | ||
849 | } | ||
850 | |||
851 | shell_status_t SHELL_Init(shell_handle_t shellHandle, serial_handle_t serialHandle, char *prompt) | ||
852 | { | ||
853 | shell_context_handle_t *shellContextHandle; | ||
854 | serial_manager_status_t status = kStatus_SerialManager_Error; | ||
855 | (void)status; | ||
856 | |||
857 | assert(shellHandle); | ||
858 | #if !(!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1))) | ||
859 | assert(serialHandle); | ||
860 | #endif | ||
861 | assert(prompt); | ||
862 | assert(SHELL_HANDLE_SIZE >= sizeof(shell_context_handle_t)); | ||
863 | |||
864 | shellContextHandle = (shell_context_handle_t *)shellHandle; | ||
865 | |||
866 | /* memory set for shellHandle */ | ||
867 | (void)memset(shellHandle, 0, SHELL_HANDLE_SIZE); | ||
868 | |||
869 | #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1))) | ||
870 | if (NULL == serialHandle) | ||
871 | { | ||
872 | } | ||
873 | else | ||
874 | #endif | ||
875 | { | ||
876 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
877 | |||
878 | #if defined(OSA_USED) | ||
879 | |||
880 | #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U)) | ||
881 | (void)COMMON_TASK_init(); | ||
882 | #else | ||
883 | if (KOSA_StatusSuccess != OSA_EventCreate((osa_event_handle_t)shellContextHandle->event, 1U)) | ||
884 | { | ||
885 | return kStatus_SHELL_Error; | ||
886 | } | ||
887 | |||
888 | if (KOSA_StatusSuccess != | ||
889 | OSA_TaskCreate((osa_task_handle_t)shellContextHandle->taskId, OSA_TASK(SHELL_Task), shellContextHandle)) | ||
890 | { | ||
891 | return kStatus_SHELL_Error; | ||
892 | } | ||
893 | #endif | ||
894 | |||
895 | #endif | ||
896 | |||
897 | #endif | ||
898 | } | ||
899 | |||
900 | shellContextHandle->prompt = prompt; | ||
901 | shellContextHandle->serialHandle = serialHandle; | ||
902 | |||
903 | #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1))) | ||
904 | if (NULL == serialHandle) | ||
905 | { | ||
906 | } | ||
907 | else | ||
908 | #endif | ||
909 | { | ||
910 | shellContextHandle->serialWriteHandle = (serial_write_handle_t)&shellContextHandle->serialWriteHandleBuffer[0]; | ||
911 | status = SerialManager_OpenWriteHandle(shellContextHandle->serialHandle, shellContextHandle->serialWriteHandle); | ||
912 | assert(kStatus_SerialManager_Success == status); | ||
913 | |||
914 | shellContextHandle->serialReadHandle = (serial_read_handle_t)&shellContextHandle->serialReadHandleBuffer[0]; | ||
915 | status = SerialManager_OpenReadHandle(shellContextHandle->serialHandle, shellContextHandle->serialReadHandle); | ||
916 | assert(kStatus_SerialManager_Success == status); | ||
917 | |||
918 | #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) | ||
919 | status = SerialManager_InstallRxCallback(shellContextHandle->serialReadHandle, SHELL_SerialManagerRxCallback, | ||
920 | shellContextHandle); | ||
921 | assert(kStatus_SerialManager_Success == status); | ||
922 | #endif | ||
923 | (void)status; | ||
924 | } | ||
925 | |||
926 | (void)SHELL_RegisterCommand(shellContextHandle, SHELL_COMMAND(help)); | ||
927 | (void)SHELL_RegisterCommand(shellContextHandle, SHELL_COMMAND(exit)); | ||
928 | |||
929 | SHELL_WriteWithCopy(shellContextHandle, "\r\nSHELL build: ", strlen("\r\nSHELL build: ")); | ||
930 | SHELL_WriteWithCopy(shellContextHandle, __DATE__, strlen(__DATE__)); | ||
931 | SHELL_WriteWithCopy(shellContextHandle, "\r\nCopyright 2020 NXP\r\n", strlen("\r\nCopyright 2020 NXP\r\n")); | ||
932 | SHELL_PrintPrompt(shellContextHandle); | ||
933 | |||
934 | return kStatus_SHELL_Success; | ||
935 | } | ||
936 | |||
937 | shell_status_t SHELL_RegisterCommand(shell_handle_t shellHandle, shell_command_t *shellCommand) | ||
938 | { | ||
939 | shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)shellHandle; | ||
940 | assert(shellHandle); | ||
941 | assert(shellCommand); | ||
942 | |||
943 | /* memory set for shellHandle */ | ||
944 | (void)memset(&shellCommand->link, 0, sizeof(shellCommand->link)); | ||
945 | |||
946 | (void)LIST_AddTail(&shellContextHandle->commandContextListHead, &shellCommand->link); | ||
947 | |||
948 | return kStatus_SHELL_Success; | ||
949 | } | ||
950 | |||
951 | shell_status_t SHELL_UnregisterCommand(shell_command_t *shellCommand) | ||
952 | { | ||
953 | assert(shellCommand); | ||
954 | |||
955 | (void)LIST_RemoveElement(&shellCommand->link); | ||
956 | |||
957 | /* memory set for shellHandle */ | ||
958 | (void)memset(&shellCommand->link, 0, sizeof(shellCommand->link)); | ||
959 | |||
960 | return kStatus_SHELL_Success; | ||
961 | } | ||
962 | |||
963 | shell_status_t SHELL_Write(shell_handle_t shellHandle, char *buffer, uint32_t length) | ||
964 | { | ||
965 | shell_context_handle_t *shellContextHandle; | ||
966 | uint32_t primask; | ||
967 | shell_status_t status; | ||
968 | |||
969 | assert(shellHandle); | ||
970 | assert(buffer); | ||
971 | |||
972 | if (!(bool)length) | ||
973 | { | ||
974 | return kStatus_SHELL_Success; | ||
975 | } | ||
976 | |||
977 | shellContextHandle = (shell_context_handle_t *)shellHandle; | ||
978 | |||
979 | primask = DisableGlobalIRQ(); | ||
980 | if ((bool)shellContextHandle->printBusy) | ||
981 | { | ||
982 | EnableGlobalIRQ(primask); | ||
983 | return kStatus_SHELL_Error; | ||
984 | } | ||
985 | shellContextHandle->printBusy = 1U; | ||
986 | EnableGlobalIRQ(primask); | ||
987 | #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1))) | ||
988 | if (NULL == shellContextHandle->serialHandle) | ||
989 | { | ||
990 | status = kStatus_SHELL_Success; | ||
991 | for (uint32_t index = 0; index < length; index++) | ||
992 | { | ||
993 | (void)putchar(buffer[index]); | ||
994 | } | ||
995 | } | ||
996 | else | ||
997 | #endif | ||
998 | { | ||
999 | status = (shell_status_t)SerialManager_WriteBlocking(shellContextHandle->serialWriteHandle, (uint8_t *)buffer, | ||
1000 | length); | ||
1001 | } | ||
1002 | |||
1003 | shellContextHandle->printBusy = 0U; | ||
1004 | |||
1005 | return status; | ||
1006 | } | ||
1007 | |||
1008 | /* For MISRA to fix const */ | ||
1009 | static void SHELL_WriteWithCopy(shell_handle_t shellHandle, const char *buffer, uint32_t length) | ||
1010 | { | ||
1011 | char s_shellWriteCopyBuffer[128]; | ||
1012 | |||
1013 | assert(length <= 128UL); | ||
1014 | |||
1015 | (void)memcpy(s_shellWriteCopyBuffer, buffer, length); | ||
1016 | (void)SHELL_Write(shellHandle, s_shellWriteCopyBuffer, length); | ||
1017 | } | ||
1018 | |||
1019 | int SHELL_Printf(shell_handle_t shellHandle, const char *formatString, ...) | ||
1020 | { | ||
1021 | shell_context_handle_t *shellContextHandle; | ||
1022 | uint32_t length; | ||
1023 | uint32_t primask; | ||
1024 | va_list ap; | ||
1025 | |||
1026 | assert(shellHandle); | ||
1027 | assert(formatString); | ||
1028 | |||
1029 | shellContextHandle = (shell_context_handle_t *)shellHandle; | ||
1030 | |||
1031 | primask = DisableGlobalIRQ(); | ||
1032 | if ((bool)shellContextHandle->printBusy) | ||
1033 | { | ||
1034 | EnableGlobalIRQ(primask); | ||
1035 | return -1; | ||
1036 | } | ||
1037 | shellContextHandle->printBusy = 1U; | ||
1038 | EnableGlobalIRQ(primask); | ||
1039 | |||
1040 | va_start(ap, formatString); | ||
1041 | |||
1042 | shellContextHandle->printLength = 0U; | ||
1043 | length = (uint32_t)SHELL_Sprintf(shellHandle, formatString, ap); | ||
1044 | #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1))) | ||
1045 | if (NULL == shellContextHandle->serialHandle) | ||
1046 | { | ||
1047 | for (uint32_t index = 0; index < length; index++) | ||
1048 | { | ||
1049 | (void)putchar(shellContextHandle->printBuffer[index]); | ||
1050 | } | ||
1051 | } | ||
1052 | else | ||
1053 | #endif | ||
1054 | { | ||
1055 | (void)SerialManager_WriteBlocking(shellContextHandle->serialWriteHandle, | ||
1056 | (uint8_t *)shellContextHandle->printBuffer, length); | ||
1057 | } | ||
1058 | va_end(ap); | ||
1059 | |||
1060 | shellContextHandle->printBusy = 0U; | ||
1061 | return (int32_t)shellContextHandle->printLength; | ||
1062 | } | ||
1063 | |||
1064 | void SHELL_ChangePrompt(shell_handle_t shellHandle, char *prompt) | ||
1065 | { | ||
1066 | shell_context_handle_t *shellContextHandle; | ||
1067 | assert(shellHandle); | ||
1068 | assert(prompt); | ||
1069 | |||
1070 | shellContextHandle = (shell_context_handle_t *)shellHandle; | ||
1071 | |||
1072 | shellContextHandle->prompt = prompt; | ||
1073 | SHELL_PrintPrompt(shellContextHandle); | ||
1074 | } | ||
1075 | |||
1076 | void SHELL_PrintPrompt(shell_handle_t shellHandle) | ||
1077 | { | ||
1078 | shell_context_handle_t *shellContextHandle; | ||
1079 | assert(shellHandle); | ||
1080 | |||
1081 | shellContextHandle = (shell_context_handle_t *)shellHandle; | ||
1082 | |||
1083 | SHELL_WriteWithCopy(shellContextHandle, "\r\n", 2U); /* MISRA C-2012 Rule 7.4 */ | ||
1084 | (void)SHELL_Write(shellContextHandle, shellContextHandle->prompt, strlen(shellContextHandle->prompt)); | ||
1085 | } | ||