1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153 |
- /*
- * Copyright (c) 2015, Freescale Semiconductor, Inc.
- * Copyright 2016-2021 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * POSIX getopt for Windows
- * Code given out at the 1985 UNIFORUM conference in Dallas.
- *
- * From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985
- * Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET
- * Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP
- * Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix
- * From: std-unix@ut-sally.UUCP (Moderator, John Quarterman)
- * Newsgroups: mod.std.unix
- * Subject: public domain AT&T getopt source
- * Message-ID: <3352@ut-sally.UUCP>
- * Date: 3 Nov 85 19:34:15 GMT
- * Date-Received: 4 Nov 85 12:25:09 GMT
- * Organization: IEEE/P1003 Portable Operating System Environment Committee
- * Lines: 91
- * Approved: jsq@ut-sally.UUC
- * Here's something you've all been waiting for: the AT&T public domain
- * source for getopt(3). It is the code which was given out at the 1985
- * UNIFORUM conference in Dallas. I obtained it by electronic mail
- * directly from AT&T. The people there assure me that it is indeed
- * in the public domain
- * There is no manual page. That is because the one they gave out at
- * UNIFORUM was slightly different from the current System V Release 2
- * manual page. The difference apparently involved a note about the
- * famous rules 5 and 6, recommending using white space between an option
- * and its first argument, and not grouping options that have arguments.
- * Getopt itself is currently lenient about both of these things White
- * space is allowed, but not mandatory, and the last option in a group can
- * have an argument. That particular version of the man page evidently
- * has no official existence, and my source at AT&T did not send a copy.
- * The current SVR2 man page reflects the actual behavor of this getopt.
- * However, I am not about to post a copy of anything licensed by AT&T.
- */
- #include <assert.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include "fsl_common.h"
- #include "fsl_str.h"
- #include "fsl_component_generic_list.h"
- #include "fsl_component_serial_manager.h"
- #include "fsl_shell.h"
- /*
- * The OSA_USED macro can only be defined when the OSA component is used.
- * If the source code of the OSA component does not exist, the OSA_USED cannot be defined.
- * OR, If OSA component is not added into project event the OSA source code exists, the OSA_USED
- * also cannot be defined.
- * The source code path of the OSA component is <MCUXpresso_SDK>/components/osa.
- *
- */
- #if defined(OSA_USED)
- #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U))
- #include "fsl_component_common_task.h"
- #else
- #include "fsl_os_abstraction.h"
- #endif
- #endif
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- #if defined(OSA_USED)
- #define SHELL_WRITEX SHELL_WriteSynchronization
- #else
- #define SHELL_WRITEX SHELL_Write
- #endif
- #if defined(OSA_USED)
- #if (defined(USE_RTOS) && (USE_RTOS > 0U))
- static OSA_MUTEX_HANDLE_DEFINE(s_shellMutex);
- #define SHELL_MUTEX_CREATE() (void)OSA_MutexCreate(s_shellMutex)
- #define SHELL_ENTER_CRITICAL() (void)OSA_MutexLock(s_shellMutex, osaWaitForever_c)
- #define SHELL_EXIT_CRITICAL() (void)OSA_MutexUnlock(s_shellMutex)
- #else
- #define SHELL_MUTEX_CREATE()
- #define SHELL_ENTER_CRITICAL()
- #define SHELL_EXIT_CRITICAL()
- #endif
- #else
- #ifdef SDK_OS_FREE_RTOS
- #include "FreeRTOS.h"
- #include "queue.h"
- #include "semphr.h"
- static QueueHandle_t s_shellMutex;
- #define SHELL_MUTEX_CREATE() s_shellMutex = xSemaphoreCreateMutex()
- #define SHELL_ENTER_CRITICAL() (void)xSemaphoreTakeRecursive(s_shellMutex, portMAX_DELAY)
- #define SHELL_EXIT_CRITICAL() (void)xSemaphoreGiveRecursive(s_shellMutex)
- #else /* BM case*/
- #define SHELL_MUTEX_CREATE()
- #define SHELL_ENTER_CRITICAL()
- #define SHELL_EXIT_CRITICAL()
- #endif
- #endif
- #define KEY_ESC (0x1BU)
- #define KET_DEL (0x7FU)
- #define SHELL_EVENT_DATA_ARRIVED (1U << 0)
- #define SHELL_EVENT_DATA_SENT (1U << 1)
- #define SHELL_SPRINTF_BUFFER_SIZE (64U)
- /*! @brief A type for the handle special key. */
- typedef enum _fun_key_status
- {
- kSHELL_Normal = 0U, /*!< Normal key */
- kSHELL_Special = 1U, /*!< Special key */
- kSHELL_Function = 2U, /*!< Function key */
- } fun_key_status_t;
- /*! @brief Data structure for Shell environment. */
- typedef struct _shell_context_handle
- {
- list_label_t commandContextListHead; /*!< Command shellContextHandle list queue head */
- serial_handle_t serialHandle; /*!< Serial manager handle */
- uint8_t
- serialWriteHandleBuffer[SERIAL_MANAGER_WRITE_HANDLE_SIZE]; /*!< The buffer for serial manager write handle */
- serial_write_handle_t serialWriteHandle; /*!< The serial manager write handle */
- uint8_t serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE]; /*!< The buffer for serial manager read handle */
- serial_read_handle_t serialReadHandle; /*!< The serial manager read handle */
- char *prompt; /*!< Prompt string */
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- #if defined(OSA_USED)
- #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U))
- common_task_message_t commontaskMsg; /*!< Message for common task */
- #else
- uint8_t event[OSA_EVENT_HANDLE_SIZE]; /*!< Event instance */
- uint8_t taskId[OSA_TASK_HANDLE_SIZE]; /*!< Task handle */
- #endif
- #endif
- #endif
- char line[SHELL_BUFFER_SIZE]; /*!< Consult buffer */
- char hist_buf[SHELL_HISTORY_COUNT][SHELL_BUFFER_SIZE]; /*!< History buffer*/
- char printBuffer[SHELL_SPRINTF_BUFFER_SIZE]; /*!< Buffer for print */
- uint32_t printLength; /*!< All length has been printed */
- uint16_t hist_current; /*!< Current history command in hist buff*/
- uint16_t hist_count; /*!< Total history command in hist buff*/
- enum _fun_key_status stat; /*!< Special key status */
- uint8_t cmd_num; /*!< Number of user commands */
- uint8_t l_pos; /*!< Total line position */
- uint8_t c_pos; /*!< Current line position */
- volatile uint8_t notificationPost; /*!< The serial manager notification is post */
- uint8_t exit; /*!< Exit Flag*/
- uint8_t printBusy : 1; /*!< Print is busy */
- uint8_t taskBusy : 1; /*!< Task is busy */
- } shell_context_handle_t;
- #if 0
- #define SHELL_STRUCT_OFFSET(type, field) ((size_t) & (((type *)0)->field))
- #define SHEEL_COMMAND_POINTER(node) \
- ((shell_command_t *)(((uint32_t)(node)) - SHELL_STRUCT_OFFSET(shell_command_t, link)))
- #else
- #define SHEEL_COMMAND_POINTER(node) \
- ((shell_command_t *)(((uint32_t)(node)) - (sizeof(shell_command_t) - sizeof(list_element_t))))
- #endif
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- static shell_status_t SHELL_HelpCommand(shell_handle_t shellHandle, int32_t argc, char **argv); /*!< help command */
- static shell_status_t SHELL_ExitCommand(shell_handle_t shellHandle, int32_t argc, char **argv); /*!< exit command */
- static int32_t SHELL_ParseLine(const char *cmd, uint32_t len, char *argv[]); /*!< parse line command */
- static int32_t SHELL_StringCompare(const char *str1, const char *str2, int32_t count); /*!< compare string command */
- static void SHELL_ProcessCommand(shell_context_handle_t *shellContextHandle, const char *cmd); /*!< process a command */
- static void SHELL_GetHistoryCommand(shell_context_handle_t *shellContextHandle,
- uint8_t hist_pos); /*!< get commands history */
- static void SHELL_AutoComplete(shell_context_handle_t *shellContextHandle); /*!< auto complete command */
- static shell_status_t SHELL_GetChar(shell_context_handle_t *shellContextHandle,
- uint8_t *ch); /*!< get a char from communication interface */
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- static void SHELL_Task(void *param); /*!< Shell task*/
- #endif
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- static SHELL_COMMAND_DEFINE(help, "\r\n\"help\": List all the registered commands\r\n", SHELL_HelpCommand, 0);
- static SHELL_COMMAND_DEFINE(exit, "\r\n\"exit\": Exit program\r\n", SHELL_ExitCommand, 0);
- static char s_paramBuffer[SHELL_BUFFER_SIZE];
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- #if defined(OSA_USED)
- #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U))
- #else
- /*
- * \brief Defines the serial manager task's stack
- */
- static OSA_TASK_DEFINE(SHELL_Task, SHELL_TASK_PRIORITY, 1, SHELL_TASK_STACK_SIZE, false);
- #endif
- #endif /* OSA_USED */
- #endif /* SHELL_NON_BLOCKING_MODE */
- /*******************************************************************************
- * Code
- ******************************************************************************/
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- static void SHELL_SerialManagerRxCallback(void *callbackParam,
- serial_manager_callback_message_t *message,
- serial_manager_status_t status)
- {
- shell_context_handle_t *shellHandle;
- assert(callbackParam);
- assert(message);
- shellHandle = (shell_context_handle_t *)callbackParam;
- if (0U == shellHandle->notificationPost)
- {
- shellHandle->notificationPost = 1U;
- #if defined(OSA_USED)
- #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U))
- shellHandle->commontaskMsg.callback = SHELL_Task;
- shellHandle->commontaskMsg.callbackParam = shellHandle;
- (void)COMMON_TASK_post_message(&shellHandle->commontaskMsg);
- #else
- (void)OSA_EventSet((osa_event_handle_t)shellHandle->event, SHELL_EVENT_DATA_ARRIVED);
- #endif
- #else
- SHELL_Task(shellHandle);
- #endif
- }
- }
- #endif
- static void SHELL_WriteBuffer(char *buffer, int32_t *indicator, char val, int len)
- {
- shell_context_handle_t *shellContextHandle;
- int i = 0;
- shellContextHandle = (shell_context_handle_t *)(void *)buffer;
- for (i = 0; i < len; i++)
- {
- if ((*indicator + 1) >= (int32_t)SHELL_SPRINTF_BUFFER_SIZE)
- {
- #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1)))
- if (NULL == shellContextHandle->serialHandle)
- {
- for (uint32_t index = 0; index < ((uint32_t)*indicator); index++)
- {
- (void)putchar(shellContextHandle->printBuffer[index]);
- }
- }
- else
- #endif
- {
- (void)SerialManager_WriteBlocking(shellContextHandle->serialWriteHandle,
- (uint8_t *)shellContextHandle->printBuffer, (uint32_t)*indicator);
- }
- shellContextHandle->printLength += (uint32_t)*indicator;
- *indicator = 0;
- }
- shellContextHandle->printBuffer[*indicator] = val;
- (*indicator)++;
- }
- }
- static int SHELL_Sprintf(void *buffer, const char *formatString, va_list ap)
- {
- shell_context_handle_t *shellContextHandle;
- uint32_t length;
- shellContextHandle = (shell_context_handle_t *)buffer;
- length = (uint32_t)StrFormatPrintf(formatString, ap, (char *)buffer, SHELL_WriteBuffer);
- shellContextHandle->printLength += length;
- return (int32_t)length;
- }
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- static void SHELL_Task(void *param)
- #else
- void SHELL_Task(shell_handle_t shellHandle)
- #endif
- {
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)param;
- #else
- shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)shellHandle;
- #endif
- uint8_t ch;
- if (NULL != shellContextHandle)
- {
- uint32_t osaCurrentSr = 0U;
- osaCurrentSr = DisableGlobalIRQ();
- shellContextHandle->notificationPost = 0U;
- if (shellContextHandle->taskBusy > 0U)
- {
- EnableGlobalIRQ(osaCurrentSr);
- return;
- }
- shellContextHandle->taskBusy = 1U;
- EnableGlobalIRQ(osaCurrentSr);
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- #if defined(OSA_USED)
- #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U))
- #else
- osa_event_flags_t ev = 0;
- do
- {
- if (KOSA_StatusSuccess == OSA_EventWait((osa_event_handle_t)shellContextHandle->event, osaEventFlagsAll_c,
- 0U, osaWaitForever_c, &ev))
- {
- if (0U != (ev & SHELL_EVENT_DATA_ARRIVED))
- #endif
- #endif
- #endif
- {
- shellContextHandle->notificationPost = 0U;
- do
- {
- if ((bool)shellContextHandle->exit)
- {
- if (shellContextHandle->serialReadHandle != NULL)
- {
- (void)SerialManager_CloseReadHandle(shellContextHandle->serialReadHandle);
- shellContextHandle->serialReadHandle = NULL;
- }
- if (shellContextHandle->serialWriteHandle != NULL)
- {
- (void)SerialManager_CloseWriteHandle(shellContextHandle->serialWriteHandle);
- shellContextHandle->serialWriteHandle = NULL;
- }
- break;
- }
- if (kStatus_SHELL_Success != (shell_status_t)SHELL_GetChar(shellContextHandle, &ch))
- {
- /* If error occurred when getting a char, exit the task and waiting the new data arriving. */
- break;
- }
- /* Special key */
- if (ch == KEY_ESC)
- {
- shellContextHandle->stat = kSHELL_Special;
- continue;
- }
- else if (shellContextHandle->stat == kSHELL_Special)
- {
- /* Function key */
- if ((char)ch == '[')
- {
- shellContextHandle->stat = kSHELL_Function;
- continue;
- }
- shellContextHandle->stat = kSHELL_Normal;
- }
- else if (shellContextHandle->stat == kSHELL_Function)
- {
- shellContextHandle->stat = kSHELL_Normal;
- switch ((char)ch)
- {
- /* History operation here */
- case 'A': /* Up key */
- SHELL_GetHistoryCommand(shellContextHandle, (uint8_t)shellContextHandle->hist_current);
- if (shellContextHandle->hist_current < (shellContextHandle->hist_count - 1U))
- {
- shellContextHandle->hist_current++;
- }
- break;
- case 'B': /* Down key */
- SHELL_GetHistoryCommand(shellContextHandle, (uint8_t)shellContextHandle->hist_current);
- if (shellContextHandle->hist_current > 0U)
- {
- shellContextHandle->hist_current--;
- }
- break;
- case 'D': /* Left key */
- if ((bool)shellContextHandle->c_pos)
- {
- (void)SHELL_WRITEX(shellContextHandle, "\b", 1);
- shellContextHandle->c_pos--;
- }
- break;
- case 'C': /* Right key */
- if (shellContextHandle->c_pos < shellContextHandle->l_pos)
- {
- (void)SHELL_WRITEX(shellContextHandle,
- &shellContextHandle->line[shellContextHandle->c_pos], 1);
- shellContextHandle->c_pos++;
- }
- break;
- default:
- /* MISRA C-2012 Rule 16.4 */
- break;
- }
- continue;
- }
- /* Handle tab key */
- else if ((char)ch == '\t')
- {
- #if SHELL_AUTO_COMPLETE
- /* Move the cursor to the beginning of line */
- uint32_t i;
- for (i = 0; i < (uint32_t)shellContextHandle->c_pos; i++)
- {
- (void)SHELL_WRITEX(shellContextHandle, "\b", 1);
- }
- /* Do auto complete */
- SHELL_AutoComplete(shellContextHandle);
- /* Move position to end */
- shellContextHandle->l_pos = (uint8_t)strlen(shellContextHandle->line);
- shellContextHandle->c_pos = shellContextHandle->l_pos;
- #endif
- continue;
- }
- /* Handle backspace key */
- else if ((ch == KET_DEL) || ((char)ch == '\b'))
- {
- /* There must be at last one char */
- if (shellContextHandle->c_pos == 0U)
- {
- continue;
- }
- shellContextHandle->l_pos--;
- shellContextHandle->c_pos--;
- if (shellContextHandle->l_pos > shellContextHandle->c_pos)
- {
- (void)memmove(&shellContextHandle->line[shellContextHandle->c_pos],
- &shellContextHandle->line[shellContextHandle->c_pos + 1U],
- (uint32_t)shellContextHandle->l_pos - (uint32_t)shellContextHandle->c_pos);
- shellContextHandle->line[shellContextHandle->l_pos] = '\0';
- (void)SHELL_WRITEX(shellContextHandle, "\b", 1);
- (void)SHELL_WRITEX(shellContextHandle, &shellContextHandle->line[shellContextHandle->c_pos],
- strlen(&shellContextHandle->line[shellContextHandle->c_pos]));
- (void)SHELL_WRITEX(shellContextHandle, " \b", 3);
- /* Reset position */
- uint32_t i;
- for (i = (uint32_t)shellContextHandle->c_pos; i <= (uint32_t)shellContextHandle->l_pos; i++)
- {
- (void)SHELL_WRITEX(shellContextHandle, "\b", 1);
- }
- }
- else /* Normal backspace operation */
- {
- (void)SHELL_WRITEX(shellContextHandle, "\b \b", 3);
- shellContextHandle->line[shellContextHandle->l_pos] = '\0';
- }
- continue;
- }
- else
- {
- /* MISRA C-2012 Rule 15.7 */
- }
- /* Input too long */
- if (shellContextHandle->l_pos >= (SHELL_BUFFER_SIZE - 1U))
- {
- shellContextHandle->l_pos = 0U;
- }
- /* Handle end of line, break */
- if (((char)ch == '\r') || ((char)ch == '\n'))
- {
- static char endoflinechar = '\0';
- if (((uint8_t)endoflinechar != 0U) && ((uint8_t)endoflinechar != ch))
- {
- continue;
- }
- else
- {
- endoflinechar = (char)ch;
- /* Print new line. */
- (void)SHELL_WRITEX(shellContextHandle, "\r\n", 2U);
- /* If command line is not NULL, will start process it. */
- if (0U != strlen(shellContextHandle->line))
- {
- SHELL_ProcessCommand(shellContextHandle, shellContextHandle->line);
- }
- /* Print prompt. */
- (void)SHELL_WRITEX(shellContextHandle, shellContextHandle->prompt,
- strlen(shellContextHandle->prompt));
- /* Reset all params */
- shellContextHandle->c_pos = shellContextHandle->l_pos = 0;
- shellContextHandle->hist_current = 0;
- (void)memset(shellContextHandle->line, 0, sizeof(shellContextHandle->line));
- continue;
- }
- }
- /* Normal character */
- if (shellContextHandle->c_pos < shellContextHandle->l_pos)
- {
- (void)memmove(&shellContextHandle->line[shellContextHandle->c_pos + 1U],
- &shellContextHandle->line[shellContextHandle->c_pos],
- (uint32_t)shellContextHandle->l_pos - (uint32_t)shellContextHandle->c_pos);
- shellContextHandle->line[shellContextHandle->c_pos] = (char)ch;
- (void)SHELL_WRITEX(shellContextHandle, &shellContextHandle->line[shellContextHandle->c_pos],
- strlen(&shellContextHandle->line[shellContextHandle->c_pos]));
- /* Move the cursor to new position */
- uint32_t i;
- for (i = (uint32_t)shellContextHandle->c_pos; i < (uint32_t)shellContextHandle->l_pos; i++)
- {
- (void)SHELL_WRITEX(shellContextHandle, "\b", 1);
- }
- }
- else
- {
- shellContextHandle->line[shellContextHandle->l_pos] = (char)ch;
- (void)SHELL_WRITEX(shellContextHandle, &shellContextHandle->line[shellContextHandle->l_pos], 1);
- }
- ch = 0;
- shellContextHandle->l_pos++;
- shellContextHandle->c_pos++;
- } while (0U == shellContextHandle->exit);
- }
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- #if defined(OSA_USED)
- #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U))
- #else
- }
- } while (1U == gUseRtos_c); /* USE_RTOS = 0 for BareMetal and 1 for OS */
- #endif
- #endif
- #endif
- osaCurrentSr = DisableGlobalIRQ();
- shellContextHandle->taskBusy = 0U;
- EnableGlobalIRQ(osaCurrentSr);
- }
- }
- static shell_status_t SHELL_HelpCommand(shell_handle_t shellHandle, int32_t argc, char **argv)
- {
- shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)shellHandle;
- shell_command_t *shellCommandContextHandle;
- list_element_handle_t p = LIST_GetHead(&shellContextHandle->commandContextListHead);
- while (p != NULL)
- {
- shellCommandContextHandle = SHEEL_COMMAND_POINTER(p);
- if ((shellCommandContextHandle->pcHelpString != NULL) && (bool)strlen(shellCommandContextHandle->pcHelpString))
- {
- (void)SHELL_WRITEX(shellContextHandle, shellCommandContextHandle->pcHelpString,
- strlen(shellCommandContextHandle->pcHelpString));
- }
- p = LIST_GetNext(p);
- }
- return kStatus_SHELL_Success;
- }
- static shell_status_t SHELL_ExitCommand(shell_handle_t shellHandle, int32_t argc, char **argv)
- {
- shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)shellHandle;
- /* Skip warning */
- (void)SHELL_WRITEX(shellContextHandle, "\r\nSHELL exited\r\n", strlen("\r\nSHELL exited\r\n"));
- shellContextHandle->exit = (uint8_t) true;
- return kStatus_SHELL_Success;
- }
- static void SHELL_ProcessCommand(shell_context_handle_t *shellContextHandle, const char *cmd)
- {
- shell_command_t *tmpCommand = NULL;
- const char *tmpCommandString;
- int32_t argc;
- char *argv[SHELL_BUFFER_SIZE] = {0};
- list_element_handle_t p;
- uint8_t flag = 1;
- uint8_t tmpCommandLen;
- uint8_t tmpLen;
- uint8_t i = 0;
- tmpLen = (uint8_t)strlen(cmd);
- argc = SHELL_ParseLine(cmd, tmpLen, argv);
- if ((argc > 0))
- {
- p = LIST_GetHead(&shellContextHandle->commandContextListHead);
- while (p != NULL)
- {
- tmpCommand = SHEEL_COMMAND_POINTER(p);
- tmpCommandString = tmpCommand->pcCommand;
- tmpCommandLen = (uint8_t)strlen(tmpCommandString);
- /* Compare with space or end of string */
- if ((cmd[tmpCommandLen] == ' ') || (cmd[tmpCommandLen] == (char)0x00))
- {
- if (SHELL_StringCompare(tmpCommandString, argv[0], (int32_t)tmpCommandLen) == 0)
- {
- /* support commands with optional number of parameters */
- if (tmpCommand->cExpectedNumberOfParameters == (uint8_t)SHELL_IGNORE_PARAMETER_COUNT)
- {
- flag = 0;
- }
- else if ((tmpCommand->cExpectedNumberOfParameters == 0U) && (argc == 1))
- {
- flag = 0;
- }
- else if (tmpCommand->cExpectedNumberOfParameters > 0U)
- {
- if ((argc - 1) == (int32_t)tmpCommand->cExpectedNumberOfParameters)
- {
- flag = 0;
- }
- }
- else
- {
- flag = 1;
- }
- break;
- }
- }
- p = LIST_GetNext(p);
- }
- if (NULL == p)
- {
- tmpCommand = NULL;
- }
- }
- if ((tmpCommand != NULL) && (flag == 1U))
- {
- (void)SHELL_Write(
- shellContextHandle,
- "\r\nIncorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n",
- strlen(
- "\r\nIncorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n"));
- }
- else if (tmpCommand != NULL)
- {
- tmpLen = (uint8_t)strlen(cmd);
- /* Compare with last command. Push back to history buffer if different */
- if (tmpLen != (uint8_t)SHELL_StringCompare(cmd, shellContextHandle->hist_buf[0], (int32_t)strlen(cmd)))
- {
- for (i = SHELL_HISTORY_COUNT - 1U; i > 0U; i--)
- {
- (void)memset(shellContextHandle->hist_buf[i], (int)'\0', SHELL_BUFFER_SIZE);
- tmpLen = (uint8_t)strlen(shellContextHandle->hist_buf[i - 1U]);
- (void)memcpy(shellContextHandle->hist_buf[i], shellContextHandle->hist_buf[i - 1U], tmpLen);
- }
- (void)memset(shellContextHandle->hist_buf[0], (int)'\0', SHELL_BUFFER_SIZE);
- tmpLen = (uint8_t)strlen(cmd);
- (void)memcpy(shellContextHandle->hist_buf[0], cmd, tmpLen);
- if (shellContextHandle->hist_count < SHELL_HISTORY_COUNT)
- {
- shellContextHandle->hist_count++;
- }
- }
- (void)tmpCommand->pFuncCallBack(shellContextHandle, argc, argv);
- }
- else
- {
- (void)SHELL_Write(
- shellContextHandle,
- "\r\nCommand not recognized. Enter 'help' to view a list of available commands.\r\n\r\n",
- strlen("\r\nCommand not recognized. Enter 'help' to view a list of available commands.\r\n\r\n"));
- }
- }
- static void SHELL_GetHistoryCommand(shell_context_handle_t *shellContextHandle, uint8_t hist_pos)
- {
- uint32_t i;
- uint32_t tmp;
- if (shellContextHandle->hist_buf[0][0] == '\0')
- {
- shellContextHandle->hist_current = 0;
- return;
- }
- #if 0 /*hist_pos is passed from hist_current. And hist_current is only changed in case 'A'/'B',as hist_count is 3 \
- most, it can't be more than 3 */
- if (hist_pos >= SHELL_HISTORY_COUNT)
- {
- hist_pos = SHELL_HISTORY_COUNT - 1U;
- }
- #endif
- tmp = strlen(shellContextHandle->line);
- /* Clear current if have */
- if (tmp > 0U)
- {
- (void)memset(shellContextHandle->line, (int)'\0', tmp);
- for (i = 0U; i < tmp; i++)
- {
- (void)SHELL_WRITEX(shellContextHandle, "\b \b", 3);
- }
- }
- shellContextHandle->l_pos = (uint8_t)strlen(shellContextHandle->hist_buf[hist_pos]);
- shellContextHandle->c_pos = shellContextHandle->l_pos;
- (void)memcpy(shellContextHandle->line, shellContextHandle->hist_buf[hist_pos], shellContextHandle->l_pos);
- (void)SHELL_WRITEX(shellContextHandle, shellContextHandle->hist_buf[hist_pos],
- strlen(shellContextHandle->hist_buf[hist_pos]));
- }
- static void SHELL_AutoComplete(shell_context_handle_t *shellContextHandle)
- {
- int32_t minLen;
- list_element_handle_t p;
- shell_command_t *tmpCommand = NULL;
- const char *namePtr;
- const char *cmdName;
- minLen = (int32_t)SHELL_BUFFER_SIZE;
- namePtr = NULL;
- /* Empty tab, list all commands */
- if (shellContextHandle->line[0] == '\0')
- {
- (void)SHELL_HelpCommand(shellContextHandle, 0, NULL);
- return;
- }
- (void)SHELL_WRITEX(shellContextHandle, "\r\n", 2);
- /* Do auto complete */
- p = LIST_GetHead(&shellContextHandle->commandContextListHead);
- while (p != NULL)
- {
- tmpCommand = SHEEL_COMMAND_POINTER(p);
- cmdName = tmpCommand->pcCommand;
- if (SHELL_StringCompare(shellContextHandle->line, cmdName, (int32_t)strlen(shellContextHandle->line)) == 0)
- {
- /* Show possible matches */
- (void)SHELL_Printf(shellContextHandle, "%s ", cmdName);
- if (minLen > ((int32_t)strlen(cmdName)))
- {
- namePtr = cmdName;
- minLen = (int32_t)strlen(namePtr);
- }
- }
- p = LIST_GetNext(p);
- }
- /* Auto complete string */
- if (namePtr != NULL)
- {
- (void)memcpy(shellContextHandle->line, namePtr, (uint32_t)minLen);
- }
- SHELL_PrintPrompt(shellContextHandle);
- (void)SHELL_WRITEX(shellContextHandle, shellContextHandle->line, strlen(shellContextHandle->line));
- return;
- }
- static int32_t SHELL_StringCompare(const char *str1, const char *str2, int32_t count)
- {
- while ((bool)(count--))
- {
- if (*str1++ != *str2++)
- {
- return (int32_t)(*(str1 - 1) - *(str2 - 1));
- }
- }
- return 0;
- }
- static int32_t SHELL_ParseLine(const char *cmd, uint32_t len, char *argv[])
- {
- uint32_t argc;
- char *p;
- uint32_t position;
- /* Init params */
- (void)memset(s_paramBuffer, (int)'\0', len + 1U);
- (void)memcpy(s_paramBuffer, cmd, len);
- p = s_paramBuffer;
- position = 0;
- argc = 0;
- while (position < len)
- {
- /* Skip all blanks */
- while ((position < len) && ((char)(*p) == ' '))
- {
- *p = '\0';
- p++;
- position++;
- }
- if (position >= len)
- {
- break;
- }
- /* Process begin of a string */
- if (*p == '"')
- {
- p++;
- position++;
- argv[argc] = p;
- argc++;
- /* Skip this string */
- while ((*p != '"') && (position < len))
- {
- p++;
- position++;
- }
- /* Skip '"' */
- *p = '\0';
- p++;
- position++;
- }
- else /* Normal char */
- {
- argv[argc] = p;
- argc++;
- while (((char)*p != ' ') && (position < len))
- {
- p++;
- position++;
- }
- }
- }
- return (int32_t)argc;
- }
- static shell_status_t SHELL_GetChar(shell_context_handle_t *shellContextHandle, uint8_t *ch)
- {
- shell_status_t status;
- #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1)))
- if (NULL == shellContextHandle->serialHandle)
- {
- int ret;
- ret = getchar();
- if (ret > 0)
- {
- *ch = (uint8_t)ret;
- status = kStatus_SHELL_Success;
- }
- else
- {
- status = kStatus_SHELL_Error;
- }
- }
- else
- #endif
- {
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- uint32_t length = 0;
- (void)SerialManager_TryRead(shellContextHandle->serialReadHandle, ch, 1, &length);
- if (length > 0U)
- {
- status = kStatus_SHELL_Success;
- }
- else
- {
- status = kStatus_SHELL_Error;
- }
- #else
- status = (shell_status_t)SerialManager_ReadBlocking(shellContextHandle->serialReadHandle, ch, 1);
- #endif
- }
- return status;
- }
- shell_status_t SHELL_Init(shell_handle_t shellHandle, serial_handle_t serialHandle, char *prompt)
- {
- shell_context_handle_t *shellContextHandle;
- serial_manager_status_t status = kStatus_SerialManager_Error;
- (void)status;
- assert(shellHandle);
- #if !(!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1)))
- assert(serialHandle);
- #endif
- assert(prompt);
- assert(SHELL_HANDLE_SIZE >= sizeof(shell_context_handle_t));
- shellContextHandle = (shell_context_handle_t *)shellHandle;
- /* memory set for shellHandle */
- (void)memset(shellHandle, 0, SHELL_HANDLE_SIZE);
- #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1)))
- if (NULL == serialHandle)
- {
- }
- else
- #endif
- {
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- #if defined(OSA_USED)
- #if (defined(SHELL_USE_COMMON_TASK) && (SHELL_USE_COMMON_TASK > 0U))
- (void)COMMON_TASK_init();
- #else
- if (KOSA_StatusSuccess != OSA_EventCreate((osa_event_handle_t)shellContextHandle->event, 1U))
- {
- return kStatus_SHELL_Error;
- }
- if (KOSA_StatusSuccess !=
- OSA_TaskCreate((osa_task_handle_t)shellContextHandle->taskId, OSA_TASK(SHELL_Task), shellContextHandle))
- {
- return kStatus_SHELL_Error;
- }
- #endif
- #endif
- #endif
- }
- shellContextHandle->prompt = prompt;
- shellContextHandle->serialHandle = serialHandle;
- #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1)))
- if (NULL == serialHandle)
- {
- }
- else
- #endif
- {
- shellContextHandle->serialWriteHandle = (serial_write_handle_t)&shellContextHandle->serialWriteHandleBuffer[0];
- status = SerialManager_OpenWriteHandle(shellContextHandle->serialHandle, shellContextHandle->serialWriteHandle);
- assert(kStatus_SerialManager_Success == status);
- shellContextHandle->serialReadHandle = (serial_read_handle_t)&shellContextHandle->serialReadHandleBuffer[0];
- status = SerialManager_OpenReadHandle(shellContextHandle->serialHandle, shellContextHandle->serialReadHandle);
- assert(kStatus_SerialManager_Success == status);
- #if (defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
- status = SerialManager_InstallRxCallback(shellContextHandle->serialReadHandle, SHELL_SerialManagerRxCallback,
- shellContextHandle);
- assert(kStatus_SerialManager_Success == status);
- #endif
- (void)status;
- }
- (void)SHELL_RegisterCommand(shellContextHandle, SHELL_COMMAND(help));
- (void)SHELL_RegisterCommand(shellContextHandle, SHELL_COMMAND(exit));
- SHELL_MUTEX_CREATE();
- (void)SHELL_Write(shellContextHandle, "\r\nCopyright 2020 NXP\r\n", strlen("\r\nCopyright 2020 NXP\r\n"));
- SHELL_PrintPrompt(shellContextHandle);
- return kStatus_SHELL_Success;
- }
- shell_status_t SHELL_RegisterCommand(shell_handle_t shellHandle, shell_command_t *shellCommand)
- {
- shell_context_handle_t *shellContextHandle = (shell_context_handle_t *)shellHandle;
- assert(shellHandle);
- assert(shellCommand);
- /* memory set for shellHandle */
- (void)memset(&shellCommand->link, 0, sizeof(shellCommand->link));
- (void)LIST_AddTail(&shellContextHandle->commandContextListHead, &shellCommand->link);
- return kStatus_SHELL_Success;
- }
- shell_status_t SHELL_UnregisterCommand(shell_command_t *shellCommand)
- {
- assert(shellCommand);
- (void)LIST_RemoveElement(&shellCommand->link);
- /* memory set for shellHandle */
- (void)memset(&shellCommand->link, 0, sizeof(shellCommand->link));
- return kStatus_SHELL_Success;
- }
- shell_status_t SHELL_Write(shell_handle_t shellHandle, const char *buffer, uint32_t length)
- {
- shell_context_handle_t *shellContextHandle;
- uint32_t primask;
- shell_status_t status;
- assert(shellHandle);
- assert(buffer);
- if (!(bool)length)
- {
- return kStatus_SHELL_Success;
- }
- shellContextHandle = (shell_context_handle_t *)shellHandle;
- primask = DisableGlobalIRQ();
- if ((bool)shellContextHandle->printBusy)
- {
- EnableGlobalIRQ(primask);
- return kStatus_SHELL_Error;
- }
- shellContextHandle->printBusy = 1U;
- EnableGlobalIRQ(primask);
- #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1)))
- if (NULL == shellContextHandle->serialHandle)
- {
- status = kStatus_SHELL_Success;
- for (uint32_t index = 0; index < length; index++)
- {
- (void)putchar(buffer[index]);
- }
- }
- else
- #endif
- {
- status = (shell_status_t)SerialManager_WriteBlocking(shellContextHandle->serialWriteHandle, (uint8_t *)buffer,
- length);
- }
- shellContextHandle->printBusy = 0U;
- return status;
- }
- int SHELL_Printf(shell_handle_t shellHandle, const char *formatString, ...)
- {
- shell_context_handle_t *shellContextHandle;
- uint32_t length;
- uint32_t primask;
- va_list ap;
- assert(shellHandle);
- assert(formatString);
- shellContextHandle = (shell_context_handle_t *)shellHandle;
- primask = DisableGlobalIRQ();
- if ((bool)shellContextHandle->printBusy)
- {
- EnableGlobalIRQ(primask);
- return -1;
- }
- shellContextHandle->printBusy = 1U;
- EnableGlobalIRQ(primask);
- va_start(ap, formatString);
- shellContextHandle->printLength = 0U;
- length = (uint32_t)SHELL_Sprintf(shellHandle, formatString, ap);
- #if (!defined(SDK_DEBUGCONSOLE_UART) && (defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE != 1)))
- if (NULL == shellContextHandle->serialHandle)
- {
- for (uint32_t index = 0; index < length; index++)
- {
- (void)putchar(shellContextHandle->printBuffer[index]);
- }
- }
- else
- #endif
- {
- (void)SerialManager_WriteBlocking(shellContextHandle->serialWriteHandle,
- (uint8_t *)shellContextHandle->printBuffer, length);
- }
- va_end(ap);
- shellContextHandle->printBusy = 0U;
- return (int32_t)shellContextHandle->printLength;
- }
- shell_status_t SHELL_WriteSynchronization(shell_handle_t shellHandle, const char *buffer, uint32_t length)
- {
- shell_status_t status;
- assert(SHELL_checkRunningInIsr() == false);
- SHELL_ENTER_CRITICAL();
- status = SHELL_Write(shellHandle, buffer, length);
- SHELL_EXIT_CRITICAL();
- return status;
- }
- int SHELL_PrintfSynchronization(shell_handle_t shellHandle, const char *formatString, ...)
- {
- shell_status_t status;
- shell_context_handle_t *shellContextHandle;
- va_list ap;
- uint32_t length;
- assert(SHELL_checkRunningInIsr() == false);
- shellContextHandle = (shell_context_handle_t *)shellHandle;
- SHELL_ENTER_CRITICAL();
- va_start(ap, formatString);
- length = (uint32_t)SHELL_Sprintf(shellHandle, formatString, ap);
- status = SHELL_Write(shellHandle, (const char *)shellContextHandle->printBuffer, length);
- va_end(ap);
- SHELL_EXIT_CRITICAL();
- return (status == kStatus_SHELL_Success) ? (int)length : 0;
- }
- void SHELL_ChangePrompt(shell_handle_t shellHandle, char *prompt)
- {
- shell_context_handle_t *shellContextHandle;
- assert(shellHandle);
- assert(prompt);
- shellContextHandle = (shell_context_handle_t *)shellHandle;
- shellContextHandle->prompt = prompt;
- SHELL_PrintPrompt(shellContextHandle);
- }
- void SHELL_PrintPrompt(shell_handle_t shellHandle)
- {
- shell_context_handle_t *shellContextHandle;
- assert(shellHandle);
- shellContextHandle = (shell_context_handle_t *)shellHandle;
- (void)SHELL_Write(shellContextHandle, "\r\n", 2U);
- (void)SHELL_Write(shellContextHandle, shellContextHandle->prompt, strlen(shellContextHandle->prompt));
- }
|