├── readme.md ├── NOTICE ├── Terminal ├── Cfg │ └── Template │ │ └── terminal_cfg.h ├── OS │ ├── uCOS-III │ │ └── terminal_os.c │ └── uCOS-II │ │ └── terminal_os.c ├── Serial │ └── Template │ │ └── terminal_serial.c ├── Source │ ├── terminal.h │ └── terminal.c └── Mode │ └── VT100 │ └── terminal_mode.c ├── Cfg └── Template │ └── shell_cfg.h ├── Cmd └── General │ ├── sh_shell.h │ └── sh_shell.c ├── LICENSE └── Source ├── shell.h └── shell.c /readme.md: -------------------------------------------------------------------------------- 1 | # uC/Shell 2 | 3 | μC/Shell is a stand-alone module allowing a string containing a command and its argument to be parsed and executed. μC/Shell can be used with μC/OS-II, μC/OS-III, μC/TELNETs, μC/FTPs, μC/TFTPs, μC/FS, and more. μC/Shell provides a shell interface for Micrium components, but can be used within many applications as it allows for the additional of any number of commands. Modules in need of a shell facility (such as μC/TELNETs) interact with it by means of an application callback function. 4 | 5 | ## For the complete documentation, visit https://doc.micrium.com/display/ucos/ -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | ATTENTION ALL USERS OF THIS REPOSITORY: 2 | 3 | The original work found in this repository is provided by Silicon Labs under the 4 | Apache License, Version 2.0. 5 | 6 | Any third party may contribute derivative works to the original work in which 7 | modifications are clearly identified as being licensed under: 8 | 9 | (1) the Apache License, Version 2.0 or a compatible open source license; or 10 | (2) under a proprietary license with a copy of such license deposited. 11 | 12 | All posted derivative works must clearly identify which license choice has been 13 | elected. 14 | 15 | No such posted derivative works will be considered to be a “Contribution” under 16 | the Apache License, Version 2.0. 17 | 18 | SILICON LABS MAKES NO WARRANTY WITH RESPECT TO ALL POSTED THIRD PARTY CONTENT 19 | AND DISCLAIMS ALL OTHER WARRANTIES OR LIABILITIES, INCLUDING ALL WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, OWNERSHIP, 21 | NON-INFRINGEMENT, AND NON-MISAPPROPRIATION. 22 | 23 | In the event a derivative work is desired to be submitted to Silicon Labs as a 24 | “Contribution” under the Apache License, Version 2.0, a “Contributor” must give 25 | written email notice to micrium@weston-embedded.com. Unless an email response in 26 | the affirmative to accept the derivative work as a “Contribution”, such email 27 | submission should be considered to have not been incorporated into the original 28 | work. 29 | -------------------------------------------------------------------------------- /Terminal/Cfg/Template/terminal_cfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * TERMINAL 21 | * 22 | * CONFIGURATION TEMPLATE FILE 23 | * 24 | * Filename : terminal_cfg.h 25 | * Version : V1.04.00 26 | ********************************************************************************************************* 27 | */ 28 | 29 | /* 30 | ********************************************************************************************************* 31 | * TASKS PRIORITIES 32 | ********************************************************************************************************* 33 | */ 34 | 35 | #define TERMINAL_OS_CFG_TASK_PRIO 16u 36 | 37 | 38 | /* 39 | ********************************************************************************************************* 40 | * STACK SIZES 41 | * Size of the task stacks (# of OS_STK entries) 42 | ********************************************************************************************************* 43 | */ 44 | 45 | #define TERMINAL_OS_CFG_TASK_STK_SIZE 1024u 46 | 47 | 48 | /* 49 | ********************************************************************************************************* 50 | * TERMINAL 51 | * 52 | * Note(s) : (1) Defines the maximum length of a command entered on the terminal, in characters. 53 | * 54 | * (2) Defines the maximum path length of the Current Working Directory (CWD). 55 | * 56 | * (3) Enables/disables command history. 57 | * 58 | * (4) Defines the number of items to hold in the command history. 59 | * 60 | * (5) Defines the length of a item in the command history. If a command is entered into the 61 | * terminal that exceeds this length, then only the first characters, up to this number of 62 | * characters, will be copied into the command history. 63 | ********************************************************************************************************* 64 | */ 65 | 66 | #define TERMINAL_CFG_MAX_CMD_LEN 260u /* Cfg max cmd len (see Note #1). */ 67 | #define TERMINAL_CFG_MAX_PATH_LEN 260u /* Cfg max path len (see Note #2). */ 68 | 69 | #define TERMINAL_CFG_HISTORY_EN DEF_ENABLED /* En/dis history (see Note #3). */ 70 | #define TERMINAL_CFG_HISTORY_ITEMS_NBR 16u /* Cfg nbr history items (see Note #4). */ 71 | #define TERMINAL_CFG_HISTORY_ITEM_LEN 64u /* Cfg history item len (see Note #5). */ 72 | -------------------------------------------------------------------------------- /Cfg/Template/shell_cfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * SHELL UTILITY CONFIGURATION FILE 21 | * 22 | * TEMPLATE 23 | * 24 | * Filename : shell_cfg.h 25 | * Version : V1.04.00 26 | ********************************************************************************************************* 27 | */ 28 | 29 | 30 | /* 31 | ********************************************************************************************************* 32 | * MODULE 33 | ********************************************************************************************************* 34 | */ 35 | 36 | #ifndef SHELL_CFG_H 37 | #define SHELL_CFG_H 38 | 39 | 40 | /* 41 | ********************************************************************************************************* 42 | * SHELL 43 | * 44 | * Note(s) : (1) Defines the size of the table used to hold the various modules' command tables. Command 45 | * tables are added using the Shell_CmdTblAdd() function. Once the table is full, it is not 46 | * possible to add any more unless Shell_CmdTblRem() is first called. 47 | * 48 | * (2) Defines the maximum number or argument(s) a command may pass on the string holding the 49 | * complete command. The minimum value is 1. 50 | * 51 | * (3) Defines the maximum length for module command name, including the NULL character. 52 | ********************************************************************************************************* 53 | */ 54 | 55 | #define SHELL_CFG_CMD_TBL_SIZE 3 /* Cfg Shell cmd tbl size (see Note #1). */ 56 | #define SHELL_CFG_CMD_ARG_NBR_MAX 5 /* Cfg cmd max nbr of arg (see Note #2). */ 57 | 58 | #define SHELL_CFG_MODULE_CMD_NAME_LEN_MAX 6 /* Cfg module cmd name len (See Note #3). */ 59 | 60 | 61 | /* 62 | ********************************************************************************************************* 63 | * TRACING 64 | ********************************************************************************************************* 65 | */ 66 | 67 | #ifndef TRACE_LEVEL_OFF 68 | #define TRACE_LEVEL_OFF 0u 69 | #endif 70 | 71 | #ifndef TRACE_LEVEL_INFO 72 | #define TRACE_LEVEL_INFO 1u 73 | #endif 74 | 75 | #ifndef TRACE_LEVEL_DBG 76 | #define TRACE_LEVEL_DBG 2u 77 | #endif 78 | 79 | #define SHELL_TRACE_LEVEL TRACE_LEVEL_OFF 80 | #define SHELL_TRACE printf 81 | 82 | 83 | /* 84 | ********************************************************************************************************* 85 | * MODULE END 86 | ********************************************************************************************************* 87 | */ 88 | 89 | #endif -------------------------------------------------------------------------------- /Terminal/OS/uCOS-III/terminal_os.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * TERMINAL 21 | * 22 | * uC/OS-II RTOS PORT 23 | * 24 | * Filename : terminal_os.c 25 | * Version : V1.04.00 26 | ********************************************************************************************************* 27 | */ 28 | 29 | 30 | /* 31 | ********************************************************************************************************* 32 | * INCLUDE FILES 33 | ********************************************************************************************************* 34 | */ 35 | 36 | #include 37 | #include 38 | 39 | 40 | /* 41 | ********************************************************************************************************* 42 | * LOCAL DEFINES 43 | ********************************************************************************************************* 44 | */ 45 | 46 | 47 | /* 48 | ********************************************************************************************************* 49 | * LOCAL GLOBAL VARIABLES 50 | ********************************************************************************************************* 51 | */ 52 | 53 | static CPU_STK Terminal_OS_TaskStk[TERMINAL_OS_CFG_TASK_STK_SIZE]; 54 | static OS_TCB Terminal_OS_TaskTCB; 55 | 56 | 57 | /* 58 | ********************************************************************************************************* 59 | * LOCAL FUNCTION PROTOTYPES 60 | ********************************************************************************************************* 61 | */ 62 | 63 | static void Terminal_OS_Task(void *p_arg); 64 | 65 | 66 | /* 67 | ********************************************************************************************************* 68 | * Terminal_OS_Task() 69 | * 70 | * Description : RTOS interface for terminal main loop. 71 | * 72 | * Argument(s) : p_arg Argument to pass to the task. 73 | * 74 | * Return(s) : none. 75 | * 76 | * Caller(s) : RTOS. 77 | * 78 | * Note(s) : none. 79 | ********************************************************************************************************* 80 | */ 81 | 82 | static void Terminal_OS_Task (void *p_arg) 83 | { 84 | Terminal_Task(p_arg); 85 | } 86 | 87 | 88 | /* 89 | ********************************************************************************************************* 90 | * Terminal_OS_Init() 91 | * 92 | * Description : Initialize the terminal task. 93 | * 94 | * Argument(s) : p_arg Argument to pass to the task. 95 | * 96 | * Return(s) : DEF_FAIL Initialize task failed. 97 | * DEF_OK Initialize task successful. 98 | * 99 | * Caller(s) : Terminal_Init() 100 | * 101 | * Note(s) : The RTOS needs to create Terminal_OS_Task(). 102 | ********************************************************************************************************* 103 | */ 104 | 105 | CPU_BOOLEAN Terminal_OS_Init (void *p_arg) 106 | { 107 | OS_ERR os_err; 108 | 109 | 110 | OSTaskCreate((OS_TCB *)&Terminal_OS_TaskTCB, 111 | (CPU_CHAR *)"Terminal", 112 | (OS_TASK_PTR )Terminal_OS_Task, 113 | (void *)0, 114 | (OS_PRIO )TERMINAL_OS_CFG_TASK_PRIO, 115 | (CPU_STK *)&Terminal_OS_TaskStk[0], 116 | (CPU_STK_SIZE)TERMINAL_OS_CFG_TASK_STK_SIZE / 10u, 117 | (CPU_STK_SIZE)TERMINAL_OS_CFG_TASK_STK_SIZE, 118 | (OS_MSG_QTY )0, 119 | (OS_TICK )0, 120 | (void *)0, 121 | (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), 122 | (OS_ERR *)&os_err); 123 | 124 | if (os_err != OS_ERR_NONE) { 125 | return (DEF_FAIL); 126 | } 127 | 128 | return (DEF_OK); 129 | } 130 | -------------------------------------------------------------------------------- /Terminal/Serial/Template/terminal_serial.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * TERMINAL 21 | * 22 | * TEMPLATE COMMUNICATIONS PORT 23 | * 24 | * Filename : terminal_serial.c 25 | * Version : V1.04.00 26 | ********************************************************************************************************* 27 | */ 28 | 29 | 30 | /* 31 | ********************************************************************************************************* 32 | * INCLUDE FILES 33 | ********************************************************************************************************* 34 | */ 35 | 36 | #include 37 | 38 | 39 | /* 40 | ********************************************************************************************************* 41 | * LOCAL DEFINES 42 | ********************************************************************************************************* 43 | */ 44 | 45 | 46 | /* 47 | ********************************************************************************************************* 48 | * LOCAL GLOBAL VARIABLES 49 | ********************************************************************************************************* 50 | */ 51 | 52 | 53 | /* 54 | ********************************************************************************************************* 55 | * LOCAL FUNCTION PROTOTYPES 56 | ********************************************************************************************************* 57 | */ 58 | 59 | 60 | /* 61 | ********************************************************************************************************* 62 | * LOCAL CONFIGURATION ERRORS 63 | ********************************************************************************************************* 64 | */ 65 | 66 | 67 | /* 68 | ********************************************************************************************************* 69 | * TerminalSerial_Init() 70 | * 71 | * Description : Initialize serial communications. 72 | * 73 | * Argument(s) : none. 74 | * 75 | * Return(s) : DEF_OK, if interface was opened. 76 | * DEF_FAIL, otherwise. 77 | * 78 | * Caller(s) : Terminal_Init(). 79 | * 80 | * Note(s) : none. 81 | ********************************************************************************************************* 82 | */ 83 | 84 | CPU_BOOLEAN TerminalSerial_Init (void) 85 | { 86 | return (DEF_FAIL); 87 | } 88 | 89 | 90 | /* 91 | ********************************************************************************************************* 92 | * TerminalSerial_Exit() 93 | * 94 | * Description : Uninitialize serial communications. 95 | * 96 | * Argument(s) : none. 97 | * 98 | * Return(s) : none. 99 | * 100 | * Caller(s) : Terminal_Init(). 101 | * 102 | * Note(s) : none. 103 | ********************************************************************************************************* 104 | */ 105 | 106 | void TerminalSerial_Exit (void) 107 | { 108 | 109 | } 110 | 111 | 112 | /* 113 | ********************************************************************************************************* 114 | * TerminalSerial_Wr() 115 | * 116 | * Description : Serial output. 117 | * 118 | * Argument(s) : pbuf Pointer to the buffer to transmit. 119 | * 120 | * buf_len Number of bytes in the buffer. 121 | * 122 | * Return(s) : none. 123 | * 124 | * Caller(s) : Terminal_Out(). 125 | * 126 | * Note(s) : none. 127 | ********************************************************************************************************* 128 | */ 129 | 130 | CPU_INT16S TerminalSerial_Wr (void *pbuf, 131 | CPU_SIZE_T buf_len) 132 | { 133 | return (-1); 134 | } 135 | 136 | 137 | /* 138 | ********************************************************************************************************* 139 | * TerminalSerial_RdByte() 140 | * 141 | * Description : Serial byte input. 142 | * 143 | * Argument(s) : none. 144 | * 145 | * Return(s) : Byte read from port. 146 | * 147 | * Caller(s) : various. 148 | * 149 | * Note(s) : none. 150 | ********************************************************************************************************* 151 | */ 152 | 153 | CPU_INT08U TerminalSerial_RdByte (void) 154 | { 155 | return (0u); 156 | } 157 | 158 | 159 | /* 160 | ********************************************************************************************************* 161 | * TerminalSerial_WrByte() 162 | * 163 | * Description : Serial byte output. 164 | * 165 | * Argument(s) : c Byte to write. 166 | * 167 | * Return(s) : none. 168 | * 169 | * Caller(s) : various. 170 | * 171 | * Note(s) : none. 172 | ********************************************************************************************************* 173 | */ 174 | 175 | void TerminalSerial_WrByte (CPU_INT08U c) 176 | { 177 | 178 | } 179 | -------------------------------------------------------------------------------- /Cmd/General/sh_shell.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | 18 | /* 19 | ********************************************************************************************************* 20 | * 21 | * GENERAL SHELL COMMANDS 22 | * 23 | * Filename : sh_shell.h 24 | * Version : V1.04.00 25 | ********************************************************************************************************* 26 | */ 27 | 28 | /* 29 | ********************************************************************************************************* 30 | * MODULE 31 | * 32 | * Note(s) : (1) This header file is protected from multiple pre-processor inclusion through use of the 33 | * SH_SHELL present pre-processor macro definition. 34 | ********************************************************************************************************* 35 | */ 36 | 37 | #ifndef SH_SHELL_PRESENT /* See Note #1. */ 38 | #define SH_SHELL_PRESENT 39 | 40 | 41 | /* 42 | ********************************************************************************************************* 43 | * GENERAL SHELL COMMANDS VERSION NUMBER 44 | * 45 | * Note(s) : (1) (a) The General Shell Commands software version is denoted as follows : 46 | * 47 | * Vx.yy 48 | * 49 | * where 50 | * V denotes 'Version' label 51 | * x denotes major software version revision number 52 | * yy denotes minor software version revision number 53 | * 54 | * (b) The General Shell Commands software version label #define is formatted as follows : 55 | * 56 | * ver = x.yy * 100 57 | * 58 | * where 59 | * ver denotes software version number scaled as 60 | * an integer value 61 | * x.yy denotes software version number 62 | ********************************************************************************************************* 63 | */ 64 | 65 | #define SH_SHELL_VERSION 100u /* See Note #1. */ 66 | 67 | 68 | /* 69 | ********************************************************************************************************* 70 | * EXTERNS 71 | ********************************************************************************************************* 72 | */ 73 | 74 | #ifdef SH_SHELL_MODULE 75 | #define SH_SHELL_EXT 76 | #else 77 | #define SH_SHELL_EXT extern 78 | #endif 79 | 80 | /* 81 | ********************************************************************************************************* 82 | * INCLUDE FILES 83 | ********************************************************************************************************* 84 | */ 85 | 86 | #include 87 | #include 88 | #include 89 | #include 90 | #include 91 | #include 92 | 93 | 94 | /* 95 | ********************************************************************************************************* 96 | * DEFINES 97 | ********************************************************************************************************* 98 | */ 99 | 100 | 101 | /* 102 | ********************************************************************************************************* 103 | * DATA TYPES 104 | ********************************************************************************************************* 105 | */ 106 | 107 | 108 | /* 109 | ********************************************************************************************************* 110 | * GLOBAL VARIABLES 111 | ********************************************************************************************************* 112 | */ 113 | 114 | 115 | /* 116 | ********************************************************************************************************* 117 | * MACRO'S 118 | ********************************************************************************************************* 119 | */ 120 | 121 | 122 | /* 123 | ********************************************************************************************************* 124 | * FUNCTION PROTOTYPES 125 | ********************************************************************************************************* 126 | */ 127 | 128 | CPU_BOOLEAN ShShell_Init(void); 129 | 130 | 131 | /* 132 | ********************************************************************************************************* 133 | * CONFIGURATION ERRORS 134 | ********************************************************************************************************* 135 | */ 136 | 137 | 138 | /* 139 | ********************************************************************************************************* 140 | * MODULE END 141 | * 142 | * Note(s) : See 'MODULE Note #1'. 143 | ********************************************************************************************************* 144 | */ 145 | 146 | #endif /* End of SH_SHELL module include (see Note #1). */ 147 | -------------------------------------------------------------------------------- /Terminal/OS/uCOS-II/terminal_os.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * TERMINAL 21 | * 22 | * uC/OS-II RTOS PORT 23 | * 24 | * Filename : terminal_os.c 25 | * Version : V1.04.00 26 | ********************************************************************************************************* 27 | */ 28 | 29 | 30 | /* 31 | ********************************************************************************************************* 32 | * INCLUDE FILES 33 | ********************************************************************************************************* 34 | */ 35 | 36 | #include 37 | #include 38 | 39 | 40 | /* 41 | ********************************************************************************************************* 42 | * LOCAL DEFINES 43 | ********************************************************************************************************* 44 | */ 45 | 46 | 47 | /* 48 | ********************************************************************************************************* 49 | * LOCAL GLOBAL VARIABLES 50 | ********************************************************************************************************* 51 | */ 52 | 53 | static OS_STK Terminal_OS_TaskStk[TERMINAL_OS_CFG_TASK_STK_SIZE]; 54 | 55 | 56 | /* 57 | ********************************************************************************************************* 58 | * LOCAL FUNCTION PROTOTYPES 59 | ********************************************************************************************************* 60 | */ 61 | 62 | static void Terminal_OS_Task(void *p_arg); 63 | 64 | 65 | /* 66 | ********************************************************************************************************* 67 | * Terminal_OS_Task() 68 | * 69 | * Description : RTOS interface for terminal main loop. 70 | * 71 | * Argument(s) : p_arg Argument to pass to the task. 72 | * 73 | * Return(s) : none. 74 | * 75 | * Caller(s) : RTOS. 76 | * 77 | * Note(s) : none. 78 | ********************************************************************************************************* 79 | */ 80 | 81 | static void Terminal_OS_Task (void *p_arg) 82 | { 83 | Terminal_Task(p_arg); 84 | } 85 | 86 | 87 | /* 88 | ********************************************************************************************************* 89 | * Terminal_OS_Init() 90 | * 91 | * Description : Initialize the terminal task. 92 | * 93 | * Argument(s) : p_arg Argument to pass to the task. 94 | * 95 | * Return(s) : DEF_FAIL Initialize task failed. 96 | * DEF_OK Initialize task successful. 97 | * 98 | * Caller(s) : Terminal_Init() 99 | * 100 | * Note(s) : The RTOS needs to create Terminal_OS_Task(). 101 | ********************************************************************************************************* 102 | */ 103 | 104 | CPU_BOOLEAN Terminal_OS_Init (void *p_arg) 105 | { 106 | CPU_INT08U err; 107 | 108 | 109 | #if (OS_TASK_CREATE_EXT_EN > 0) 110 | #if (OS_STK_GROWTH == 1) 111 | err = OSTaskCreateExt( Terminal_OS_Task, 112 | p_arg, 113 | /* Set Top-Of-Stack. */ 114 | &Terminal_OS_TaskStk[TERMINAL_OS_CFG_TASK_STK_SIZE - 1], 115 | TERMINAL_OS_CFG_TASK_PRIO, 116 | TERMINAL_OS_CFG_TASK_PRIO, 117 | &Terminal_OS_TaskStk[0], /* Set Bottom-Of-Stack. */ 118 | TERMINAL_OS_CFG_TASK_STK_SIZE, 119 | (void *)0, /* No TCB extension. */ 120 | /* Enable stack checking + clear stack. */ 121 | OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 122 | #else 123 | err = OSTaskCreateExt( Terminal_OS_Task, 124 | p_arg, 125 | &Terminal_OS_TaskStk[0], /* Set Top-Of-Stack. */ 126 | TERMINAL_OS_CFG_TASK_PRIO, 127 | TERMINAL_OS_CFG_TASK_PRIO, 128 | /* Set Bottom-Of-Stack. */ 129 | &Terminal_OS_TaskStk[TERMINAL_OS_CFG_TASK_STK_SIZE - 1], 130 | TERMINAL_OS_CFG_TASK_STK_SIZE, 131 | (void *)0, /* No TCB extension. */ 132 | /* Enable stack checking + clear stack. */ 133 | OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); 134 | #endif 135 | #else 136 | #if (OS_STK_GROWTH == 1) 137 | err = OSTaskCreate( Terminal_OS_Task, 138 | p_arg, 139 | &Terminal_OS_TaskStk[TERMINAL_OS_CFG_TASK_STK_SIZE - 1], 140 | TERMINAL_OS_CFG_TASK_PRIO); 141 | #else 142 | err = OSTaskCreate( Terminal_OS_Task, 143 | p_arg, 144 | &Terminal_OS_TaskStk[0], 145 | TERMINAL_OS_CFG_TASK_PRIO); 146 | #endif 147 | #endif 148 | 149 | if (err != OS_ERR_NONE) { 150 | return (DEF_FAIL); 151 | } 152 | 153 | #if (OS_TASK_NAME_EN > 0) 154 | OSTaskNameSet(TERMINAL_OS_CFG_TASK_PRIO, (INT8U *)"Terminal", &err); 155 | #endif 156 | 157 | return (DEF_OK); 158 | } 159 | -------------------------------------------------------------------------------- /Cmd/General/sh_shell.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | 18 | /* 19 | ********************************************************************************************************* 20 | * 21 | * GENERAL SHELL COMMANDS 22 | * 23 | * Filename : sh_shell.c 24 | * Version : V1.04.00 25 | ********************************************************************************************************* 26 | */ 27 | 28 | /* 29 | ********************************************************************************************************* 30 | * INCLUDE FILES 31 | ********************************************************************************************************* 32 | */ 33 | 34 | #define SH_SHELL_MODULE 35 | #include 36 | 37 | 38 | /* 39 | ********************************************************************************************************* 40 | * LOCAL DEFINES 41 | ********************************************************************************************************* 42 | */ 43 | 44 | #define SH_SHELL_NEW_LINE (CPU_CHAR *)"\r\n" 45 | #define SH_SHELL_BLANK_LINE (CPU_CHAR *)"\r\n\r\n" 46 | #define SH_SHELL_STR_HELP (CPU_CHAR *)"-h" 47 | 48 | /* 49 | ********************************************************************************************************* 50 | * ARGUMENT ERROR MESSAGES 51 | ********************************************************************************************************* 52 | */ 53 | 54 | #define SH_SHELL_ARG_ERR_HELP (CPU_CHAR *)"Sh_help: usage: Sh_help\r\n Sh_help [command]" 55 | 56 | /* 57 | ********************************************************************************************************* 58 | * COMMAND EXPLANATION MESSAGES 59 | ********************************************************************************************************* 60 | */ 61 | 62 | #define SH_SHELL_CMD_EXP_HELP (CPU_CHAR *)" Get list of commands, or information about a command." 63 | 64 | 65 | /* 66 | ********************************************************************************************************* 67 | * LOCAL CONSTANTS 68 | ********************************************************************************************************* 69 | */ 70 | 71 | 72 | /* 73 | ********************************************************************************************************* 74 | * LOCAL DATA TYPES 75 | ********************************************************************************************************* 76 | */ 77 | 78 | 79 | /* 80 | ********************************************************************************************************* 81 | * LOCAL GLOBAL VARIABLES 82 | ********************************************************************************************************* 83 | */ 84 | 85 | 86 | /* 87 | ********************************************************************************************************* 88 | * LOCAL FUNCTION PROTOTYPES 89 | ********************************************************************************************************* 90 | */ 91 | 92 | 93 | static CPU_INT16S ShShell_help(CPU_INT16U argc, 94 | CPU_CHAR *argv[], 95 | SHELL_OUT_FNCT out_fnct, 96 | SHELL_CMD_PARAM *pcmd_param); 97 | 98 | static SHELL_CMD ShShell_CmdTbl [] = 99 | { 100 | {"Sh_help", ShShell_help}, 101 | {0, 0 } 102 | }; 103 | 104 | 105 | /* 106 | ********************************************************************************************************* 107 | * LOCAL CONFIGURATION ERRORS 108 | ********************************************************************************************************* 109 | */ 110 | 111 | 112 | /* 113 | ********************************************************************************************************* 114 | * ShShell_Init() 115 | * 116 | * Description : Initialize Shell for general shell commands. 117 | * 118 | * Argument(s) : none. 119 | * 120 | * Return(s) : DEF_OK, if general shell commands were added. 121 | * DEF_FAIL, otherwise. 122 | * 123 | * Caller(s) : Application. 124 | * 125 | * Note(s) : none. 126 | ********************************************************************************************************* 127 | */ 128 | 129 | CPU_BOOLEAN ShShell_Init (void) 130 | { 131 | SHELL_ERR err; 132 | CPU_BOOLEAN ok; 133 | 134 | 135 | Shell_CmdTblAdd((CPU_CHAR *)"Sh", ShShell_CmdTbl, &err); 136 | 137 | ok = (err == SHELL_ERR_NONE) ? DEF_OK : DEF_FAIL; 138 | return (ok); 139 | } 140 | 141 | 142 | /* 143 | ********************************************************************************************************* 144 | ********************************************************************************************************* 145 | * COMMAND FUNCTIONS 146 | ********************************************************************************************************* 147 | ********************************************************************************************************* 148 | */ 149 | 150 | /* 151 | ********************************************************************************************************* 152 | * ShShell_help() 153 | * 154 | * Description : List all commands or invoke '--help' for another command. 155 | * 156 | * Argument(s) : argc The number of arguments. 157 | * 158 | * argv Array of arguments. 159 | * 160 | * out_fnct The output function. 161 | * 162 | * pcmd_param Pointer to the command parameters. 163 | * 164 | * Return(s) : SHELL_EXEC_ERR, if an error is encountered. 165 | * SHELL_ERR_NONE, otherwise. 166 | * 167 | * Caller(s) : Shell, in response to command execution. 168 | * 169 | * Note(s) : none. 170 | ********************************************************************************************************* 171 | */ 172 | 173 | static CPU_INT16S ShShell_help (CPU_INT16U argc, 174 | CPU_CHAR *argv[], 175 | SHELL_OUT_FNCT out_fnct, 176 | SHELL_CMD_PARAM *pcmd_param) 177 | { 178 | CPU_CHAR cmd_str[SHELL_CFG_MODULE_CMD_NAME_LEN_MAX + 4]; 179 | SHELL_ERR err; 180 | SHELL_CMD *pcmd; 181 | SHELL_MODULE_CMD *pmodule_cmd; 182 | 183 | 184 | if (argc == 2) { 185 | if (Str_Cmp(argv[1], SH_SHELL_STR_HELP) == 0) { 186 | (void)out_fnct(SH_SHELL_ARG_ERR_HELP, (CPU_INT16U)Str_Len(SH_SHELL_ARG_ERR_HELP), pcmd_param->pout_opt); 187 | (void)out_fnct(SH_SHELL_NEW_LINE, 2, pcmd_param->pout_opt); 188 | (void)out_fnct(SH_SHELL_CMD_EXP_HELP, (CPU_INT16U)Str_Len(SH_SHELL_CMD_EXP_HELP), pcmd_param->pout_opt); 189 | (void)out_fnct(SH_SHELL_NEW_LINE, 2, pcmd_param->pout_opt); 190 | return (SHELL_ERR_NONE); 191 | } 192 | } 193 | 194 | if ((argc != 1) && (argc != 2)) { 195 | (void)out_fnct(SH_SHELL_ARG_ERR_HELP, (CPU_INT16U)Str_Len(SH_SHELL_ARG_ERR_HELP), pcmd_param->pout_opt); 196 | (void)out_fnct(SH_SHELL_NEW_LINE, 2, pcmd_param->pout_opt); 197 | return (SHELL_EXEC_ERR); 198 | } 199 | 200 | switch (argc) { 201 | case 1: 202 | pmodule_cmd = Shell_ModuleCmdUsedPoolPtr; 203 | while (pmodule_cmd != (SHELL_MODULE_CMD *)0) { 204 | pcmd = pmodule_cmd->CmdTblPtr; 205 | if (pcmd != (SHELL_CMD *)0) { 206 | while (pcmd->Fnct != (SHELL_CMD_FNCT)0) { 207 | (void)out_fnct((CPU_CHAR *)pcmd->Name, 208 | (CPU_INT16U)Str_Len(pcmd->Name), 209 | pcmd_param->pout_opt); 210 | (void)out_fnct(SH_SHELL_NEW_LINE, 2, pcmd_param->pout_opt); 211 | pcmd++; 212 | } 213 | } 214 | pmodule_cmd = pmodule_cmd->NextModuleCmdPtr; 215 | } 216 | break; 217 | 218 | case 2: 219 | Str_Copy(cmd_str, argv[1]); 220 | Str_Cat(cmd_str, (CPU_CHAR *)" "); 221 | Str_Cat(cmd_str, SH_SHELL_STR_HELP); 222 | 223 | Shell_Exec(cmd_str, out_fnct, pcmd_param, &err); 224 | 225 | switch (err) { 226 | case SHELL_ERR_CMD_NOT_FOUND: 227 | case SHELL_ERR_CMD_SEARCH: 228 | case SHELL_ERR_ARG_TBL_FULL: 229 | (void)out_fnct((CPU_CHAR *)"Command not recognized: ", 25, pcmd_param->pout_opt); 230 | (void)out_fnct(argv[1], (CPU_INT16U)Str_Len(argv[1]), pcmd_param->pout_opt); 231 | (void)out_fnct(SH_SHELL_NEW_LINE, 2, pcmd_param->pout_opt); 232 | break; 233 | 234 | case SHELL_ERR_NONE: 235 | case SHELL_ERR_NULL_PTR: 236 | case SHELL_ERR_CMD_EXEC: 237 | default: 238 | break; 239 | } 240 | break; 241 | 242 | default: 243 | break; 244 | } 245 | 246 | return (SHELL_ERR_NONE); 247 | } 248 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /Terminal/Source/terminal.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * TERMINAL 21 | * 22 | * Filename : terminal.h 23 | * Version : V1.04.00 24 | ********************************************************************************************************* 25 | */ 26 | 27 | 28 | /* 29 | ********************************************************************************************************* 30 | * MODULE 31 | * 32 | * Note(s) : (1) This header file is protected from multiple pre-processor inclusion through use of the 33 | * TERMINAL present pre-processor macro definition. 34 | ********************************************************************************************************* 35 | */ 36 | 37 | #ifndef TERMINAL_PRESENT /* See Note #1. */ 38 | #define TERMINAL_PRESENT 39 | 40 | 41 | /* 42 | ********************************************************************************************************* 43 | * TERMINAL VERSION NUMBER 44 | * 45 | * Note(s) : (1) (a) The Terminal software version is denoted as follows : 46 | * 47 | * Vx.yy 48 | * 49 | * where 50 | * V denotes 'Version' label 51 | * x denotes major software version revision number 52 | * yy denotes minor software version revision number 53 | * 54 | * (b) The Terminal software version label #define is formatted as follows : 55 | * 56 | * ver = x.yy * 100 57 | * 58 | * where 59 | * ver denotes software version number scaled as 60 | * an integer value 61 | * x.yy denotes software version number 62 | ********************************************************************************************************* 63 | */ 64 | 65 | #define TERMINAL_VERSION 100u /* See Note #1. */ 66 | 67 | 68 | /* 69 | ********************************************************************************************************* 70 | * EXTERNS 71 | ********************************************************************************************************* 72 | */ 73 | 74 | #ifdef TERMINAL_MODULE 75 | #define TERMINAL_EXT 76 | #else 77 | #define TERMINAL_EXT extern 78 | #endif 79 | 80 | 81 | /* 82 | ********************************************************************************************************* 83 | * INCLUDE FILES 84 | ********************************************************************************************************* 85 | */ 86 | 87 | #include 88 | #include 89 | 90 | #include 91 | #include 92 | #include 93 | #include 94 | 95 | #include 96 | #include 97 | 98 | 99 | /* 100 | ********************************************************************************************************* 101 | * DEFINES 102 | ********************************************************************************************************* 103 | */ 104 | 105 | #define TERMINAL_ESC_TYPE_NONE 0u 106 | #define TERMINAL_ESC_TYPE_UP 1u 107 | #define TERMINAL_ESC_TYPE_DOWN 2u 108 | #define TERMINAL_ESC_TYPE_INS 3u 109 | 110 | 111 | /* 112 | ********************************************************************************************************* 113 | * DATA TYPES 114 | ********************************************************************************************************* 115 | */ 116 | 117 | 118 | /* 119 | ********************************************************************************************************* 120 | * GLOBAL VARIABLES 121 | ********************************************************************************************************* 122 | */ 123 | 124 | 125 | /* 126 | ********************************************************************************************************* 127 | * MACRO'S 128 | ********************************************************************************************************* 129 | */ 130 | 131 | 132 | /* 133 | ********************************************************************************************************* 134 | * FUNCTION PROTOTYPES 135 | ********************************************************************************************************* 136 | */ 137 | 138 | CPU_BOOLEAN Terminal_Init (void); 139 | 140 | void Terminal_Task (void *p_arg); 141 | 142 | void Terminal_WrStr (CPU_CHAR *pbuf, 143 | CPU_SIZE_T buf_len); 144 | 145 | void Terminal_WrChar (CPU_CHAR c); 146 | 147 | /* 148 | ********************************************************************************************************* 149 | * FUNCTION PROTOTYPES 150 | * DEFINED in OS's 'terminal_os.c' 151 | ********************************************************************************************************* 152 | */ 153 | 154 | CPU_BOOLEAN Terminal_OS_Init (void *p_arg); 155 | 156 | /* 157 | ********************************************************************************************************* 158 | * FUNCTION PROTOTYPES 159 | * DEFINED in SERIAL's 'terminal_serial.c' 160 | ********************************************************************************************************* 161 | */ 162 | 163 | CPU_BOOLEAN TerminalSerial_Init (void); 164 | 165 | void TerminalSerial_Exit (void); 166 | 167 | CPU_INT08U TerminalSerial_RdByte(void); 168 | 169 | CPU_INT16S TerminalSerial_Wr (void *pbuf, 170 | CPU_SIZE_T buf_len); 171 | 172 | void TerminalSerial_WrByte(CPU_INT08U c); 173 | 174 | /* 175 | ********************************************************************************************************* 176 | * FUNCTION PROTOTYPES 177 | * DEFINED in MODE's 'terminal_mode.c' 178 | ********************************************************************************************************* 179 | */ 180 | 181 | CPU_INT08U TerminalMode_RdLine (CPU_CHAR *pstr, 182 | CPU_SIZE_T len_max, 183 | CPU_SIZE_T *pcursor_pos, 184 | CPU_BOOLEAN ins); 185 | 186 | void TerminalMode_Clr (CPU_SIZE_T nbr_char, 187 | CPU_SIZE_T cursor_pos); 188 | 189 | void TerminalMode_NewLine (void); 190 | 191 | void TerminalMode_Prompt (void); 192 | 193 | 194 | /* 195 | ********************************************************************************************************* 196 | * CONFIGURATION ERRORS 197 | ********************************************************************************************************* 198 | */ 199 | 200 | /* Task priority. */ 201 | #ifndef TERMINAL_OS_CFG_TASK_PRIO 202 | #error "TERMINAL_OS_CFG_TASK_PRIO not #define'd in 'terminal_cfg.h'" 203 | #endif 204 | 205 | 206 | 207 | /* Task stack size. */ 208 | #ifndef TERMINAL_OS_CFG_TASK_STK_SIZE 209 | #error "TERMINAL_OS_CFG_TASK_STK_SIZE not #define'd in 'terminal_cfg.h'" 210 | #endif 211 | 212 | 213 | 214 | /* Maximum working directory path length. */ 215 | #ifndef TERMINAL_CFG_MAX_PATH_LEN 216 | #error "TERMINAL_CFG_MAX_PATH_LEN not #define'd in 'terminal_cfg.h'" 217 | #error " [MUST be >= 1] " 218 | #error " [ && <= 65535] " 219 | 220 | #elif ((TERMINAL_CFG_MAX_PATH_LEN < 1) || \ 221 | (TERMINAL_CFG_MAX_PATH_LEN > DEF_INT_16U_MAX_VAL)) 222 | #error "TERMINAL_CFG_MAX_PATH_LEN illegally #define'd in 'terminal_cfg.h'" 223 | #error " [MUST be >= 1] " 224 | #error " [ && <= 65535] " 225 | #endif 226 | 227 | 228 | 229 | /* Maximum input line length length. */ 230 | #ifndef TERMINAL_CFG_MAX_CMD_LEN 231 | #error "TERMINAL_CFG_MAX_CMD_LEN not #define'd in 'terminal_cfg.h'" 232 | #error " [MUST be >= 1] " 233 | #error " [ && <= 65535] " 234 | 235 | 236 | #elif ((TERMINAL_CFG_MAX_CMD_LEN < 1) || \ 237 | (TERMINAL_CFG_MAX_CMD_LEN > DEF_INT_16U_MAX_VAL)) 238 | #error "TERMINAL_CFG_MAX_CMD_LEN illegally #define'd in 'terminal_cfg.h'" 239 | #error " [MUST be >= 1] " 240 | #error " [ && <= 65535] " 241 | #endif 242 | 243 | 244 | 245 | 246 | /* History enable. */ 247 | #ifndef TERMINAL_CFG_HISTORY_EN 248 | #error "TERMINAL_CFG_HISTORY_EN not #define'd in 'terminal_cfg.h'" 249 | #error " [MUST be DEF_ENABLED ] " 250 | #error " [ && || DEF_DISABLED] " 251 | 252 | 253 | 254 | #elif ((TERMINAL_CFG_HISTORY_EN != DEF_ENABLED) && \ 255 | (TERMINAL_CFG_HISTORY_EN != DEF_DISABLED)) 256 | #error "TERMINAL_CFG_HISTORY_EN illegally #define'd in 'terminal_cfg.h'" 257 | #error " [MUST be DEF_ENABLED ] " 258 | #error " [ && || DEF_DISABLED] " 259 | 260 | 261 | 262 | #elif (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 263 | /* Number of items to keep in history. */ 264 | #ifndef TERMINAL_CFG_HISTORY_ITEMS_NBR 265 | #error "TERMINAL_CFG_HISTORY_ITEMS_NBR not #define'd in 'terminal_cfg.h'" 266 | #error " [MUST be >= 4] " 267 | #error " [ && <= 65535] " 268 | 269 | #elif ((TERMINAL_CFG_HISTORY_ITEMS_NBR < 4) || \ 270 | (TERMINAL_CFG_HISTORY_ITEMS_NBR > DEF_INT_16U_MAX_VAL)) 271 | #error "TERMINAL_CFG_HISTORY_ITEMS_NBR illegally #define'd in 'terminal_cfg.h'" 272 | #error " [MUST be >= 4] " 273 | #error " [ && <= 65535] " 274 | #endif 275 | 276 | 277 | 278 | /* Maximum length of items in history. */ 279 | #ifndef TERMINAL_CFG_HISTORY_ITEM_LEN 280 | #error "TERMINAL_CFG_HISTORY_ITEM_LEN not #define'd in 'terminal_cfg.h'" 281 | #error " [MUST be >= 1] " 282 | #error " [ && <= TERMINAL_CFG_MAX_CMD_LEN] " 283 | 284 | #elif ((TERMINAL_CFG_HISTORY_ITEM_LEN < 1) || \ 285 | (TERMINAL_CFG_HISTORY_ITEM_LEN > TERMINAL_CFG_MAX_CMD_LEN)) 286 | #error "TERMINAL_CFG_HISTORY_ITEM_LEN illegally #define'd in 'terminal_cfg.h'" 287 | #error " [MUST be >= 1] " 288 | #error " [ && <= TERMINAL_CFG_MAX_CMD_LEN] " 289 | #endif 290 | 291 | #endif 292 | 293 | 294 | /* 295 | ********************************************************************************************************* 296 | * MODULE END 297 | * 298 | * Note(s) : See 'MODULE Note #1'. 299 | ********************************************************************************************************* 300 | */ 301 | 302 | #endif /* End of TERMINAL module include (see Note #1). */ 303 | -------------------------------------------------------------------------------- /Source/shell.h: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * SHELL UTILITY 21 | * 22 | * Filename : shell.h 23 | * Version : V1.04.00 24 | ********************************************************************************************************* 25 | */ 26 | 27 | 28 | /* 29 | ********************************************************************************************************* 30 | * MODULE 31 | * 32 | * Note(s) : (1) This header file is protected from multiple pre-processor inclusion through use of the 33 | * SHELL present pre-processor macro definition. 34 | ********************************************************************************************************* 35 | */ 36 | 37 | #ifndef SHELL_PRESENT /* See Note #1. */ 38 | #define SHELL_PRESENT 39 | 40 | 41 | /* 42 | ********************************************************************************************************* 43 | * SHELL VERSION NUMBER 44 | * 45 | * Note(s) : (1) (a) The Shell module software version is denoted as follows : 46 | * 47 | * Vx.yy.zz 48 | * 49 | * where 50 | * V denotes 'Version' label 51 | * x denotes major software version revision number 52 | * yy denotes minor software version revision number 53 | * zz denotes sub-minor software version revision number 54 | * 55 | * (b) The Shell software version label #define is formatted as follows : 56 | * 57 | * ver = x.yyzz * 100 * 100 58 | * 59 | * where 60 | * ver denotes software version number scaled as an integer value 61 | * x.yyzz denotes software version number, where the unscaled integer 62 | * portion denotes the major version number & the unscaled 63 | * fractional portion denotes the (concatenated) minor 64 | * version numbers 65 | ********************************************************************************************************* 66 | */ 67 | 68 | #define SHELL_VERSION 10400u /* See Note #1. */ 69 | 70 | 71 | /* 72 | ********************************************************************************************************* 73 | * EXTERNS 74 | ********************************************************************************************************* 75 | */ 76 | 77 | #ifdef SHELL_MODULE 78 | #define SHELL_EXT 79 | #else 80 | #define SHELL_EXT extern 81 | #endif 82 | 83 | 84 | /* 85 | ********************************************************************************************************* 86 | * INCLUDE FILES 87 | * 88 | * Note(s) : (1) The Shell module files are located in the following directories : 89 | * 90 | * (a) \\shell_cfg.h 91 | * 92 | * (b) \\Source\shell.h 93 | * \shell.c 94 | * 95 | * where 96 | * directory path for Your Product's Application 97 | * directory path for Shell module 98 | * 99 | * (2) CPU-configuration software files are located in the following directories : 100 | * 101 | * (a) \\cpu_*.* 102 | * (b) \\\\cpu*.* 103 | * 104 | * where 105 | * directory path for common CPU-compiler software 106 | * directory name for specific processor (CPU) 107 | * directory name for specific compiler 108 | * 109 | * (3) NO compiler-supplied standard library functions SHOULD be used. 110 | * 111 | * (a) Standard library functions are implemented in the custom library module(s) : 112 | * 113 | * \\lib_*.* 114 | * 115 | * where 116 | * directory path for custom library software 117 | * 118 | * (4) Compiler MUST be configured to include as additional include path directories : 119 | * 120 | * (a) '\\' directory See Note #1a 121 | * 122 | * (b) '\\' directory See Note #1b 123 | * 124 | * (c) (1) '\\' directory See Note #2a 125 | * (2) '\\\\' directory See Note #2b 126 | * 127 | * (d) '\\' directory See Note #3a 128 | ********************************************************************************************************* 129 | */ 130 | 131 | #include /* CPU Configuration (see Note #2b) */ 132 | #include /* CPU Core Library (see Note #2a) */ 133 | 134 | #include /* Standard Defines (see Note #3a) */ 135 | #include /* Standard String Library (see Note #3a) */ 136 | 137 | #include /* Application Configuration File (see Note #1a) */ 138 | 139 | 140 | /* 141 | ********************************************************************************************************* 142 | * DEFINES 143 | ********************************************************************************************************* 144 | */ 145 | 146 | #define SHELL_ASCII_SPACE ' ' /* ASCII value for space */ 147 | #define SHELL_ASCII_QUOTE '\"' /* ASCII value for quote */ 148 | #define SHELL_ASCII_ARG_END '\0' 149 | #define SHELL_ASCII_CDM_NAME_DELIMITER '_' 150 | 151 | 152 | /* 153 | ********************************************************************************************************* 154 | * SHELL ERROR CODES DEFINES 155 | * 156 | * Note(s) : (1) Command function MUST return SHELL_EXEC_ERR when an error occurred at execution time. 157 | * Any other return value is command specific. 158 | * 159 | * (2) Output function MUST return : 160 | * 161 | * (a) The number of positive data octets transmitted, if NO errors 162 | * 163 | * (b) SHELL_OUT_RTN_CODE_CONN_CLOSED, if implemented connection closed 164 | * 165 | * (c) SHELL_OUT_ERR, otherwise 166 | ********************************************************************************************************* 167 | */ 168 | 169 | #define SHELL_EXEC_ERR -1 /* See Note #1. */ 170 | 171 | #define SHELL_OUT_RTN_CODE_CONN_CLOSED 0 /* See Note #2. */ 172 | #define SHELL_OUT_ERR -1 173 | 174 | #define SHELL_ERR_NONE 0 175 | #define SHELL_ERR_NULL_PTR 1 176 | #define SHELL_ERR_MODULE_CMD_EMPTY 2 177 | #define SHELL_ERR_MODULE_CMD_NAME_TOO_LONG 3 178 | #define SHELL_ERR_MODULE_CMD_NAME_NONE 4 179 | #define SHELL_ERR_MODULE_CMD_NAME_COPY 5 180 | #define SHELL_ERR_MODULE_CMD_NONE_AVAIL 6 181 | #define SHELL_ERR_MODULE_CMD_ALREADY_IN 7 182 | #define SHELL_ERR_MODULE_CMD_NOT_FOUND 8 183 | #define SHELL_ERR_CMD_EXEC 9 184 | #define SHELL_ERR_CMD_NOT_FOUND 10 185 | #define SHELL_ERR_ARG_TBL_FULL 11 186 | #define SHELL_ERR_CMD_SEARCH 12 187 | 188 | 189 | /* 190 | ********************************************************************************************************* 191 | * ERROR CODES DATA TYPE 192 | ********************************************************************************************************* 193 | */ 194 | 195 | typedef CPU_INT16U SHELL_ERR; 196 | 197 | 198 | /* 199 | ********************************************************************************************************* 200 | * SHELL COMMAND PARAMETER 201 | * 202 | * Note(s) : (1) This structure is used to pass additional parameters to the command. Future implementation 203 | * of this module could add fields to that structure. 204 | * 205 | * (2) This variable is used to let the shell commands to control the session status. For 206 | * instance, a command interacting with uC/TELNETs could used this variable to terminate 207 | * the current session. 208 | ********************************************************************************************************* 209 | */ 210 | 211 | typedef struct shell_cmd_param { 212 | void *pcur_working_dir; /* Cur working dir ptr. */ 213 | void *pout_opt; /* Output opt ptr. */ 214 | CPU_BOOLEAN *psession_active; /* Session status flag (see Note #2). */ 215 | } SHELL_CMD_PARAM; 216 | 217 | 218 | /* 219 | ********************************************************************************************************* 220 | * SHELL COMMAND FUNCTION POINTER DATA TYPE 221 | * 222 | * Note(s) : (1) (a) 'SHELL_OUT_FNCT' data type defined to replace the commonly-used function pointer 223 | * to the output facility. 224 | * 225 | * (b) CPU_INT16U ret_val; 226 | * SHELL_CMD_FNCT FnctName; 227 | * CPU_CHAR *pbuf; 228 | * CPU_INT16U buf_len; 229 | * void *popt; 230 | * 231 | * ret_val = FnctName(pbuf, buf_len, popt); 232 | * 233 | * (c) Shell output function MUST return : 234 | * 235 | * (1) The number of positive data octets transmitted, if NO error 236 | * 237 | * (2) SHELL_OUT_RTN_CODE_CONN_CLOSED, if link connection closed 238 | * 239 | * (3) SHELL_OUT_ERR, otherwise 240 | * 241 | * (2) (a) 'SHELL_CMD_FNCT' data type defined to replace the commonly-used function pointer 242 | * to a shell command. The last parameter is a pointer to an 'out' function having 243 | * the prototype specified in #1. 244 | * 245 | * (b) Example function pointer usage : 246 | * 247 | * CPU_INT16U ret_val 248 | * SHELL_CMD_FNCT FnctName; 249 | * CPU_INT16U argc; 250 | * CPU_CHAR *argv[]; 251 | * SHELL_OUT_FNCT pout_fnct; 252 | * SHELL_CMD_PARAM *pcmd_param 253 | * 254 | * ret_val = FnctName(argc, argv, pout_fnct, pcmd_param); 255 | * 256 | * (c) Shell commands MUST return SHELL_EXEC_ERR when an error occured at execution 257 | * time. Any other return value is command specific. 258 | ********************************************************************************************************* 259 | */ 260 | 261 | /* See Note #1. */ 262 | typedef CPU_INT16S (*SHELL_OUT_FNCT)(CPU_CHAR *p_buf, 263 | CPU_INT16U buf_len, 264 | void *p_opt); 265 | 266 | /* See Note #2. */ 267 | typedef CPU_INT16S (*SHELL_CMD_FNCT)(CPU_INT16U argc, 268 | CPU_CHAR *argv[], 269 | SHELL_OUT_FNCT out_fnct, 270 | SHELL_CMD_PARAM *p_cmd_param); 271 | 272 | 273 | /* 274 | ********************************************************************************************************* 275 | * SHELL COMMAND DATA TYPE 276 | * 277 | * Note(s) : This structure is used to store a command (function pointer) along with a character string 278 | * representing its name. 279 | ********************************************************************************************************* 280 | */ 281 | 282 | typedef struct shell_cmd { 283 | const CPU_CHAR *Name; /* Ptr to cmd name. */ 284 | SHELL_CMD_FNCT Fnct; /* Ptr to cmd fnct. */ 285 | } SHELL_CMD; 286 | 287 | 288 | /* 289 | ********************************************************************************************************* 290 | * SHELL MODULE COMMAND DATA TYPE 291 | * 292 | * Note(s) : 'Name' is a NULL terminated character string representing the name of the module command. 293 | * See Shell_CmdTblAdd(), Note #2, for more details. 294 | ********************************************************************************************************* 295 | */ 296 | 297 | typedef struct shell_module_cmd SHELL_MODULE_CMD; 298 | 299 | struct shell_module_cmd { 300 | CPU_CHAR Name[SHELL_CFG_MODULE_CMD_NAME_LEN_MAX]; /* Name (prefix) of module cmd (see Note #1). */ 301 | SHELL_MODULE_CMD *PrevModuleCmdPtr; /* Ptr to PREV module cmd. */ 302 | SHELL_MODULE_CMD *NextModuleCmdPtr; /* Ptr to NEXT module cmd. */ 303 | SHELL_CMD *CmdTblPtr; /* Ptr to cmd tbl. */ 304 | } ; 305 | 306 | 307 | /* 308 | ********************************************************************************************************* 309 | * GLOBAL VARIABLES 310 | ********************************************************************************************************* 311 | */ 312 | 313 | SHELL_EXT SHELL_MODULE_CMD Shell_ModuleCmdTbl[SHELL_CFG_CMD_TBL_SIZE]; 314 | 315 | SHELL_EXT SHELL_MODULE_CMD *Shell_ModuleCmdUsedPoolPtr; /* Ptr to pool of used module cmd. */ 316 | SHELL_EXT SHELL_MODULE_CMD *Shell_ModuleCmdFreePoolPtr; /* Ptr to pool of free module cmd. */ 317 | 318 | 319 | /* 320 | ********************************************************************************************************* 321 | * MACRO'S 322 | ********************************************************************************************************* 323 | */ 324 | 325 | 326 | /* 327 | ********************************************************************************************************* 328 | * FUNCTION PROTOTYPES 329 | ********************************************************************************************************* 330 | */ 331 | 332 | CPU_BOOLEAN Shell_Init (void); 333 | 334 | CPU_INT16S Shell_Exec (CPU_CHAR *in, 335 | SHELL_OUT_FNCT out_fnct, 336 | SHELL_CMD_PARAM *pcmd_param, 337 | SHELL_ERR *perr); 338 | 339 | void Shell_CmdTblAdd(CPU_CHAR *cmd_tbl_name, 340 | SHELL_CMD cmd_tbl[], 341 | SHELL_ERR *perr); 342 | 343 | void Shell_CmdTblRem(CPU_CHAR *cmd_tbl_name, 344 | SHELL_ERR *perr); 345 | 346 | 347 | /* 348 | ********************************************************************************************************* 349 | * TRACING 350 | ********************************************************************************************************* 351 | */ 352 | 353 | /* Trace level, default to TRACE_LEVEL_OFF */ 354 | #ifndef TRACE_LEVEL_OFF 355 | #define TRACE_LEVEL_OFF 0 356 | #endif 357 | 358 | #ifndef TRACE_LEVEL_INFO 359 | #define TRACE_LEVEL_INFO 1 360 | #endif 361 | 362 | #ifndef TRACE_LEVEL_DEBUG 363 | #define TRACE_LEVEL_DEBUG 2 364 | #endif 365 | 366 | #ifndef SHELL_TRACE_LEVEL 367 | #define SHELL_TRACE_LEVEL TRACE_LEVEL_OFF 368 | #endif 369 | 370 | #ifndef SHELL_TRACE 371 | #define SHELL_TRACE printf 372 | #endif 373 | 374 | #define SHELL_TRACE_INFO(x) ((SHELL_TRACE_LEVEL >= TRACE_LEVEL_INFO) ? (void)(SHELL_TRACE x) : (void)0) 375 | #define SHELL_TRACE_DEBUG(x) ((SHELL_TRACE_LEVEL >= TRACE_LEVEL_DEBUG) ? (void)(SHELL_TRACE x) : (void)0) 376 | 377 | 378 | /* 379 | ********************************************************************************************************* 380 | * CONFIGURATION ERRORS 381 | ********************************************************************************************************* 382 | */ 383 | 384 | #ifndef SHELL_CFG_CMD_TBL_SIZE 385 | #error "SHELL_CFG_CMD_TBL_SIZE not #define'd in 'shell_cfg.h'" 386 | 387 | #elif ((SHELL_CFG_CMD_TBL_SIZE < 1) || \ 388 | (SHELL_CFG_CMD_TBL_SIZE > DEF_INT_16U_MAX_VAL)) 389 | #error "SHELL_CFG_CMD_TBL_SIZE illegally #define'd in 'shell_cfg.h'" 390 | #error " [MUST be >= 1] " 391 | #error " [ && <= 65535] " 392 | #endif 393 | 394 | #ifndef SHELL_CFG_CMD_ARG_NBR_MAX 395 | #error "SHELL_CFG_CMD_ARG_NBR_MAX not #define'd in 'shell_cfg.h'" 396 | 397 | #elif ((SHELL_CFG_CMD_ARG_NBR_MAX < 1) || \ 398 | (SHELL_CFG_CMD_ARG_NBR_MAX > DEF_INT_16U_MAX_VAL)) 399 | #error "SHELL_CFG_CMD_ARG_NBR_MAX illegally #define'd in 'shell_cfg.h'" 400 | #error " [MUST be >= 1] " 401 | #error " [ && <= 65535] " 402 | #endif 403 | 404 | #ifndef SHELL_CFG_MODULE_CMD_NAME_LEN_MAX 405 | #error "SHELL_CFG_MODULE_CMD_NAME_LEN_MAX not #define'd in 'shell_cfg.h'" 406 | 407 | #elif ((SHELL_CFG_MODULE_CMD_NAME_LEN_MAX < 1) || \ 408 | (SHELL_CFG_MODULE_CMD_NAME_LEN_MAX > DEF_INT_16U_MAX_VAL)) 409 | #error "SHELL_CFG_MODULE_CMD_NAME_LEN_MAX illegally #define'd in 'shell_cfg.h'" 410 | #error " [MUST be >= 1] " 411 | #error " [ && <= 65535] " 412 | #endif 413 | 414 | 415 | /* 416 | ********************************************************************************************************* 417 | * MODULE END 418 | ********************************************************************************************************* 419 | */ 420 | 421 | #endif /* End of SHELL module include. */ 422 | 423 | -------------------------------------------------------------------------------- /Terminal/Mode/VT100/terminal_mode.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * TERMINAL 21 | * 22 | * VT100 MODE PORT 23 | * 24 | * Filename : terminal_mode.c 25 | * Version : V1.04.00 26 | ********************************************************************************************************* 27 | * Note(s) : (1) ECMA-48 'Control Functions for Coded Character Sets' (5th edition), standardizes 28 | * a set of terminal emulation commands. The ISO/IEC and ANSI issued corresponding 29 | * standards, ISO/IEC 6429 and ANSI X3.64, respectively. The DEC VT100 video terminal 30 | * implemented a command set which conformed to ANSI X3.64, so this type of terminal 31 | * emulation is often known as VT100. 32 | * 33 | * (2) To use this terminal mode, the terminal program employed (Hyperterminal, puTTY, 34 | * etc.) should be setup in VT100 mode and character echo should be disabled. 35 | * Depending on the command set used, it may be necessary to generate a CR ('\r') on 36 | * each LF ('\n'). 37 | * 38 | * (3) Only the several ECMA-48 commands relevant to terminal operation are supported. 39 | * These are : 40 | * 41 | * (a) Cursor Up. 42 | * (b) Cursor Down. 43 | * (c) Cursor Left. 44 | * (d) Cursor Right. 45 | * 46 | * In addition, several editing keys are supported : 47 | * 48 | * (a) Insert. 49 | * (b) Delete. 50 | * (c) End. 51 | * (d) Home. 52 | ** 53 | * (4) Only 7-bit mode is supported. 54 | ********************************************************************************************************* 55 | */ 56 | 57 | 58 | /* 59 | ********************************************************************************************************* 60 | * INCLUDE FILES 61 | ********************************************************************************************************* 62 | */ 63 | 64 | #include 65 | 66 | /* 67 | ********************************************************************************************************* 68 | * LOCAL DEFINES 69 | ********************************************************************************************************* 70 | */ 71 | 72 | #define TERMINAL_VT100_ESC_CHAR 0x1Bu 73 | 74 | /* 75 | ********************************************************************************************************* 76 | * C0 COMMAND SET 77 | ********************************************************************************************************* 78 | */ 79 | 80 | #define TERMINAL_VT100_C0_BS 0x08u /* Backspace. */ 81 | #define TERMINAL_VT100_C0_LF 0x0Au /* Line feed. */ 82 | #define TERMINAL_VT100_C0_CR 0x0Du /* Carriage return. */ 83 | 84 | #define TERMINAL_VT100_C0_ESC 0x1Bu /* Escape. */ 85 | 86 | /* 87 | ********************************************************************************************************* 88 | * C1 COMMAND SET 89 | ********************************************************************************************************* 90 | */ 91 | 92 | #define TERMINAL_VT100_C1_CSI 0x5Bu /* Control sequence introducer. */ 93 | 94 | /* 95 | ********************************************************************************************************* 96 | * CONTROL SEQUENCE BYTE VALUE LIMITS 97 | ********************************************************************************************************* 98 | */ 99 | 100 | #define TERMINAL_VT100_PB_MIN 0x30 101 | #define TERMINAL_VT100_PB_MAX 0x3F 102 | #define TERMINAL_VT100_IB_MIN 0x20 103 | #define TERMINAL_VT100_IB_MAX 0x2F 104 | #define TERMINAL_VT100_FB_MIN 0x40 105 | #define TERMINAL_VT100_FB_MAX 0x7E 106 | 107 | /* 108 | ********************************************************************************************************* 109 | * NO PARAMETER CONTROL SEQUENCE FINAL BYTE 110 | ********************************************************************************************************* 111 | */ 112 | 113 | #define TERMINAL_VT100_NP_CUU 0x41u /* Cursor up. */ 114 | #define TERMINAL_VT100_NP_CUD 0x42u /* Cursor down. */ 115 | #define TERMINAL_VT100_NP_CUF 0x43u /* Cursor right. */ 116 | #define TERMINAL_VT100_NP_CUB 0x44u /* Cursor left. */ 117 | 118 | /* 119 | ********************************************************************************************************* 120 | * CONTROL & FUNCTION KEY VALUES 121 | ********************************************************************************************************* 122 | */ 123 | 124 | #define TERMINAL_VT100_KEY_HOME 0x31u 125 | #define TERMINAL_VT100_KEY_INSERT 0x32u 126 | #define TERMINAL_VT100_KEY_DELETE 0x33u 127 | #define TERMINAL_VT100_KEY_END 0x34u 128 | #define TERMINAL_VT100_KEY_PAGEDOWN 0x35u 129 | #define TERMINAL_VT100_KEY_PAGEUP 0x36u 130 | 131 | #define TERMINAL_VT100_P1_KEY 0x7Eu 132 | 133 | 134 | /* 135 | ********************************************************************************************************* 136 | * LOCAL CONSTANTS 137 | ********************************************************************************************************* 138 | */ 139 | 140 | static CPU_INT08U Terminal_VT100_EscStrLeft[] = {TERMINAL_VT100_ESC_CHAR, 141 | TERMINAL_VT100_C1_CSI, 142 | TERMINAL_VT100_NP_CUB}; 143 | 144 | static CPU_INT08U Terminal_VT100_EscStrRight[] = {TERMINAL_VT100_ESC_CHAR, 145 | TERMINAL_VT100_C1_CSI, 146 | TERMINAL_VT100_NP_CUF}; 147 | 148 | 149 | /* 150 | ********************************************************************************************************* 151 | * LOCAL GLOBAL VARIABLES 152 | ********************************************************************************************************* 153 | */ 154 | 155 | 156 | /* 157 | ********************************************************************************************************* 158 | * LOCAL MACRO'S 159 | ********************************************************************************************************* 160 | */ 161 | 162 | #define TERMINAL_VT100_IS_PARAMETER_BYTE(b) ((((b) >= TERMINAL_VT100_PB_MIN) && ((b) <= TERMINAL_VT100_PB_MAX)) ? DEF_YES : DEF_NO) 163 | 164 | #define TERMINAL_VT100_IS_INTERMEDIATE_BYTE(b) ((((b) >= TERMINAL_VT100_IB_MIN) && ((b) <= TERMINAL_VT100_IB_MAX)) ? DEF_YES : DEF_NO) 165 | 166 | #define TERMINAL_VT100_IS_FINAL_BYTE(b) ((((b) >= TERMINAL_VT100_FB_MIN) && ((b) <= TERMINAL_VT100_FB_MAX)) ? DEF_YES : DEF_NO) 167 | 168 | 169 | /* 170 | ********************************************************************************************************* 171 | * LOCAL FUNCTION PROTOTYPES 172 | ********************************************************************************************************* 173 | */ 174 | 175 | 176 | /* 177 | ********************************************************************************************************* 178 | * LOCAL CONFIGURATION ERRORS 179 | ********************************************************************************************************* 180 | */ 181 | 182 | 183 | /* 184 | ********************************************************************************************************* 185 | * TerminalMode_RdLine() 186 | * 187 | * Description : Read a line from the serial interface. 188 | * 189 | * Argument(s) : pstr Pointer to a buffer at which the string can be stored. 190 | * 191 | * len_max Size of the string that will be read. 192 | * 193 | * pcursor_pos Pointer to variable that specifies the current cursor position 194 | * AND 195 | * Pointer to variable that will receive the final cursor position. 196 | * 197 | * ins Indicates insertion mode : 198 | * 199 | * DEF_YES, insert on. 200 | * DEF_NO, insert off. 201 | * 202 | * Return(s) : Type of escape sequence encountered : 203 | * 204 | * TERMINAL_ESC_TYPE_NONE No escape sequence. 205 | * TERMINAL_ESC_TYPE_UP 'Up' arrow key sequence (move to previous history element). 206 | * TERMINAL_ESC_TYPE_DOWN 'Down' arrow key sequence (move to next history element). 207 | * TERMINAL_ESC_TYPE_INS Insert mode toggled. 208 | * 209 | * Caller(s) : Terminal_Task(). 210 | * 211 | * Note(s) : none. 212 | ********************************************************************************************************* 213 | */ 214 | 215 | CPU_INT08U TerminalMode_RdLine (CPU_CHAR *pstr, 216 | CPU_SIZE_T len_max, 217 | CPU_SIZE_T *pcursor_pos, 218 | CPU_BOOLEAN ins) 219 | { 220 | CPU_CHAR cmd[10]; 221 | CPU_CHAR cmd_end; 222 | CPU_SIZE_T cmd_ix; 223 | CPU_CHAR cursor_char; 224 | CPU_SIZE_T cursor_pos; 225 | CPU_CHAR in_char; 226 | CPU_INT08U rtn_val; 227 | CPU_SIZE_T str_len; 228 | CPU_SIZE_T str_ix; 229 | 230 | 231 | rtn_val = TERMINAL_ESC_TYPE_NONE; 232 | cursor_pos = *pcursor_pos; 233 | 234 | while (DEF_TRUE) { 235 | in_char = TerminalSerial_RdByte(); 236 | 237 | switch (in_char) { 238 | case TERMINAL_VT100_C0_CR: /* ------------------- NEW LINE CHAR ------------------ */ 239 | case TERMINAL_VT100_C0_LF: 240 | str_len = Str_Len(pstr); 241 | pstr[str_len] = ASCII_CHAR_NULL; 242 | *pcursor_pos = str_len; 243 | rtn_val = TERMINAL_ESC_TYPE_NONE; 244 | return (rtn_val); 245 | 246 | 247 | 248 | case TERMINAL_VT100_C0_BS: /* ------------------ BACKSPACE CHAR ------------------ */ 249 | if (cursor_pos > 0u) { 250 | if (ins == DEF_FALSE) { /* Clr prev char. */ 251 | Terminal_WrStr((CPU_CHAR *)"\b \b", 3u); 252 | if (pstr[cursor_pos] == ASCII_CHAR_NULL) { 253 | pstr[cursor_pos - 1u] = ASCII_CHAR_NULL; 254 | } else { 255 | pstr[cursor_pos - 1u] = ASCII_CHAR_SPACE; 256 | } 257 | cursor_pos--; 258 | } else { /* Del prev char. */ 259 | str_len = Str_Len(pstr); 260 | Terminal_WrChar(TERMINAL_VT100_C0_BS); 261 | if (str_len > cursor_pos) { 262 | Terminal_WrStr(&pstr[cursor_pos], str_len - cursor_pos); 263 | } 264 | Terminal_WrChar(ASCII_CHAR_SPACE); 265 | for (str_ix = cursor_pos; str_ix <= str_len; str_ix++) { 266 | Terminal_WrChar(TERMINAL_VT100_C0_BS); 267 | pstr[str_ix - 1u] = pstr[str_ix]; 268 | } 269 | cursor_pos--; 270 | } 271 | } 272 | break; 273 | 274 | 275 | 276 | case TERMINAL_VT100_C0_ESC: /* -------------------- ESCAPE CHAR ------------------- */ 277 | in_char = TerminalSerial_RdByte(); /* Rd esc'd char. */ 278 | if (in_char == TERMINAL_VT100_C1_CSI) { /* Cmd seq intro. */ 279 | cmd_ix = 0u; 280 | /* Rd param byte's. */ 281 | in_char = TerminalSerial_RdByte(); 282 | while ((TERMINAL_VT100_IS_PARAMETER_BYTE(in_char) == DEF_YES) && (cmd_ix < sizeof(cmd))) { 283 | cmd[cmd_ix] = in_char; 284 | cmd_ix++; 285 | in_char = TerminalSerial_RdByte(); 286 | } 287 | /* Rd intermediate byte's. */ 288 | while ((TERMINAL_VT100_IS_INTERMEDIATE_BYTE(in_char) == DEF_YES) && (cmd_ix < sizeof(cmd))) { 289 | cmd[cmd_ix] = in_char; 290 | cmd_ix++; 291 | in_char = TerminalSerial_RdByte(); 292 | } 293 | 294 | cmd_end = in_char; /* Cmd end byte. */ 295 | 296 | 297 | 298 | switch (cmd_end) { 299 | case TERMINAL_VT100_NP_CUU: /* --------------------- CURSOR UP -------------------- */ 300 | *pcursor_pos = cursor_pos; 301 | rtn_val = TERMINAL_ESC_TYPE_UP; 302 | return (rtn_val); /* Terminal history will handle cmd. */ 303 | 304 | 305 | 306 | case TERMINAL_VT100_NP_CUD: /* -------------------- CURSOR DOWN ------------------- */ 307 | *pcursor_pos = cursor_pos; 308 | rtn_val = TERMINAL_ESC_TYPE_DOWN; 309 | return (rtn_val); /* Terminal history will handle cmd. */ 310 | 311 | 312 | 313 | case TERMINAL_VT100_NP_CUF: /* ------------------- CURSOR RIGHT ------------------- */ 314 | if (cursor_pos < Str_Len(pstr)) { /* Move cursor right one pos. */ 315 | cursor_pos++; 316 | Terminal_WrStr((CPU_CHAR *)Terminal_VT100_EscStrRight, 3u); 317 | } 318 | break; 319 | 320 | 321 | 322 | case TERMINAL_VT100_NP_CUB: /* ------------------- CURSOR LEFT -------------------- */ 323 | if (cursor_pos > 0u) { /* Move cursor left one pos. */ 324 | cursor_pos--; 325 | Terminal_WrStr((CPU_CHAR *)Terminal_VT100_EscStrLeft, 3u); 326 | } 327 | break; 328 | 329 | case TERMINAL_VT100_P1_KEY: 330 | if (cmd_ix == 1u) { 331 | switch (cmd[0]) { 332 | case TERMINAL_VT100_KEY_INSERT: /* ------------------ INSERT ------------------ */ 333 | *pcursor_pos = cursor_pos; 334 | rtn_val = TERMINAL_ESC_TYPE_INS; 335 | return (rtn_val); /* Terminal will handle cmd. */ 336 | 337 | 338 | 339 | case TERMINAL_VT100_KEY_HOME: /* ------------------- HOME ------------------- */ 340 | while (cursor_pos > 0u) { /* Move cursor to first char on line. */ 341 | Terminal_WrStr((CPU_CHAR *)Terminal_VT100_EscStrLeft, 3u); 342 | cursor_pos--; 343 | } 344 | break; 345 | 346 | 347 | 348 | case TERMINAL_VT100_KEY_DELETE: /* ------------------ DELETE ------------------ */ 349 | str_len = Str_Len(pstr); /* Delete char at cursor. */ 350 | if (str_len > cursor_pos) { 351 | Terminal_WrStr(&pstr[cursor_pos + 1u], str_len - cursor_pos); 352 | Terminal_WrStr((CPU_CHAR *)" \b", 2u); 353 | for (str_ix = cursor_pos + 1; str_ix < str_len; str_ix++) { 354 | pstr[str_ix - 1u] = pstr[str_ix]; 355 | Terminal_WrStr((CPU_CHAR *)Terminal_VT100_EscStrLeft, 3u); 356 | } 357 | pstr[str_len - 1u] = (CPU_CHAR)0; 358 | if (str_len == cursor_pos) { 359 | cursor_pos--; 360 | } 361 | } 362 | break; 363 | 364 | 365 | 366 | case TERMINAL_VT100_KEY_END: /* -------------------- END ------------------- */ 367 | str_len = Str_Len(pstr); /* Move cursor to last char on line. */ 368 | while (cursor_pos < str_len) { 369 | Terminal_WrStr((CPU_CHAR *)Terminal_VT100_EscStrRight, 3u); 370 | cursor_pos++; 371 | } 372 | break; 373 | 374 | default: 375 | break; 376 | } 377 | } 378 | break; 379 | 380 | default: 381 | break; 382 | } 383 | } 384 | break; 385 | 386 | 387 | default: /* -------------------- OTHER CHAR -------------------- */ 388 | if (ASCII_IsPrint(in_char) == DEF_YES){ /* Print printable char. */ 389 | /* Ovwr char at cursor's pos. */ 390 | if (cursor_pos < len_max) { 391 | if (ins == DEF_NO) { 392 | Terminal_WrChar(in_char); 393 | cursor_char = pstr[cursor_pos]; 394 | pstr[cursor_pos] = in_char; 395 | if (cursor_char == ASCII_CHAR_NULL) { /* If char at cursor was NULL, wr new NULL. */ 396 | pstr[cursor_pos + 1u] = ASCII_CHAR_NULL; 397 | } 398 | cursor_pos++; 399 | 400 | } else { /* Ins char at cursor's pos. */ 401 | str_len = Str_Len(pstr); /* Shift str right. */ 402 | if (str_len == len_max) { /* Handle buf ovf. */ 403 | str_len = len_max - 1u; 404 | } 405 | for (str_ix = str_len; str_ix > cursor_pos; str_ix--) { 406 | pstr[str_ix] = pstr[str_ix - 1u]; 407 | } 408 | pstr[cursor_pos] = in_char; /* Ins new char. */ 409 | pstr[str_len + 1u] = ASCII_CHAR_NULL; 410 | 411 | if (str_len > cursor_pos) { /* Wr str to terminal. */ 412 | Terminal_WrStr(&pstr[cursor_pos], str_len - cursor_pos); 413 | } 414 | /* Place cursor at old pos. */ 415 | for (str_ix = cursor_pos; str_ix < str_len; str_ix++) { 416 | Terminal_WrChar(ASCII_CHAR_BACKSPACE); 417 | } 418 | cursor_pos++; 419 | } 420 | } 421 | } 422 | break; 423 | } 424 | } 425 | } 426 | 427 | 428 | /* 429 | ********************************************************************************************************* 430 | * TerminalMode_Clr() 431 | * 432 | * Description : Clear the terminal line. 433 | * 434 | * Argument(s) : nbr_char Number of characters on line. 435 | * 436 | * cursor_pos Current cursor position. 437 | * 438 | * Return(s) : none. 439 | * 440 | * Caller(s) : Terminal_Task(). 441 | * 442 | * Note(s) : none. 443 | ********************************************************************************************************* 444 | */ 445 | 446 | void TerminalMode_Clr (CPU_SIZE_T nbr_char, 447 | CPU_SIZE_T cursor_pos) 448 | { 449 | CPU_SIZE_T ix; 450 | 451 | 452 | for (ix = cursor_pos; ix < nbr_char; ix++) { 453 | Terminal_WrStr((CPU_CHAR *)" ", 1u); 454 | } 455 | for (ix = 0; ix < nbr_char; ix++) { 456 | Terminal_WrStr((CPU_CHAR *)"\b \b", 3u); 457 | } 458 | } 459 | 460 | 461 | /* 462 | ********************************************************************************************************* 463 | * TerminalMode_NewLine() 464 | * 465 | * Description : Move terminal to new line. 466 | * 467 | * Argument(s) : none. 468 | * 469 | * Return(s) : none. 470 | * 471 | * Caller(s) : Terminal_Task(). 472 | * 473 | * Note(s) : none. 474 | ********************************************************************************************************* 475 | */ 476 | 477 | void TerminalMode_NewLine (void) 478 | { 479 | Terminal_WrStr((CPU_CHAR *)"\r\n", 2u); 480 | } 481 | 482 | 483 | /* 484 | ********************************************************************************************************* 485 | * TerminalMode_Prompt() 486 | * 487 | * Description : Show prompt. 488 | * 489 | * Argument(s) : none. 490 | * 491 | * Return(s) : none. 492 | * 493 | * Caller(s) : Terminal_Task(). 494 | * 495 | * Note(s) : none. 496 | ********************************************************************************************************* 497 | */ 498 | 499 | void TerminalMode_Prompt (void) 500 | { 501 | Terminal_WrStr((CPU_CHAR *)"\r\n> ", 4u); 502 | } 503 | -------------------------------------------------------------------------------- /Terminal/Source/terminal.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * TERMINAL 21 | * 22 | * Filename : terminal.c 23 | * Version : V1.04.00 24 | ********************************************************************************************************* 25 | */ 26 | 27 | 28 | /* 29 | ********************************************************************************************************* 30 | * INCLUDE FILES 31 | ********************************************************************************************************* 32 | */ 33 | 34 | #define TERMINAL_MODULE 35 | #include 36 | 37 | 38 | /* 39 | ********************************************************************************************************* 40 | * LOCAL DEFINES 41 | ********************************************************************************************************* 42 | */ 43 | 44 | 45 | #define TERMINAL_NEW_LINE (CPU_CHAR *)"\r\n" 46 | #define TERMINAL_BLANK_LINE (CPU_CHAR *)"\r\n\r\n" 47 | #define TERMINAL_STR_HELP (CPU_CHAR *)"-h" 48 | 49 | /* 50 | ********************************************************************************************************* 51 | * ARGUMENT ERROR MESSAGES 52 | ********************************************************************************************************* 53 | */ 54 | 55 | #define TERMINAL_ARG_ERR_FC (CPU_CHAR *)"Term_fc: usage: Term_fc" 56 | 57 | /* 58 | ********************************************************************************************************* 59 | * COMMAND EXPLANATION MESSAGES 60 | ********************************************************************************************************* 61 | */ 62 | 63 | #define TERMINAL_CMD_EXP_FC (CPU_CHAR *)" List terminal history items." 64 | 65 | 66 | /* 67 | ********************************************************************************************************* 68 | * LOCAL CONSTANTS 69 | ********************************************************************************************************* 70 | */ 71 | 72 | 73 | /* 74 | ********************************************************************************************************* 75 | * LOCAL GLOBAL VARIABLES 76 | ********************************************************************************************************* 77 | */ 78 | 79 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 80 | static CPU_CHAR Terminal_History[TERMINAL_CFG_HISTORY_ITEMS_NBR][TERMINAL_CFG_HISTORY_ITEM_LEN]; 81 | static CPU_INT16U Terminal_HistoryIxFirst; 82 | static CPU_INT16U Terminal_HistoryIxLast; 83 | static CPU_INT16U Terminal_HistoryIxShown; 84 | static CPU_BOOLEAN Terminal_HistoryShown; 85 | static CPU_BOOLEAN Terminal_HistoryEmpty; 86 | static CPU_INT16U Terminal_HistoryCnt; 87 | #endif 88 | 89 | 90 | /* 91 | ********************************************************************************************************* 92 | * LOCAL FUNCTION PROTOTYPES 93 | ********************************************************************************************************* 94 | */ 95 | 96 | static CPU_INT16S Terminal_OutFnct (CPU_CHAR *pbuf, 97 | CPU_INT16U buf_len, 98 | void *popt); 99 | 100 | static CPU_INT16S Terminal_Help (SHELL_OUT_FNCT out_fnct, 101 | SHELL_CMD_PARAM *pcmd_param); 102 | 103 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 104 | static void Terminal_HistoryInit (void); 105 | 106 | static void Terminal_HistoryNextGet(CPU_CHAR *pstr); 107 | 108 | static void Terminal_HistoryPrevGet(CPU_CHAR *pstr); 109 | 110 | static void Terminal_HistoryPut (CPU_CHAR *pstr); 111 | 112 | static CPU_INT16S Terminal_fc (CPU_INT16U argc, 113 | CPU_CHAR *argv[], 114 | SHELL_OUT_FNCT out_fnct, 115 | SHELL_CMD_PARAM *pcmd_param); 116 | #endif 117 | 118 | /* 119 | ********************************************************************************************************* 120 | * SHELL COMMAND TABLE 121 | ********************************************************************************************************* 122 | */ 123 | 124 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 125 | static SHELL_CMD Terminal_CmdTbl [] = { 126 | {"Term_fc", Terminal_fc}, 127 | {0, 0 } 128 | }; 129 | #endif 130 | 131 | 132 | /* 133 | ********************************************************************************************************* 134 | * LOCAL CONFIGURATION ERRORS 135 | ********************************************************************************************************* 136 | */ 137 | 138 | 139 | /* 140 | ********************************************************************************************************* 141 | * Terminal_Init() 142 | * 143 | * Description : Initialize terminal. 144 | * 145 | * Argument(s) : none. 146 | * 147 | * Return(s) : DEF_OK, if terminal was initialized. 148 | * DEF_FAIL, otherwise. 149 | * 150 | * Caller(s) : Application. 151 | * 152 | * Note(s) : none. 153 | ********************************************************************************************************* 154 | */ 155 | 156 | CPU_BOOLEAN Terminal_Init (void) 157 | { 158 | CPU_BOOLEAN ok; 159 | 160 | 161 | /* ------------------- INIT SERIAL IF ----------------- */ 162 | ok = TerminalSerial_Init(); 163 | if (ok == DEF_OK) { 164 | 165 | 166 | 167 | /* ------------------ INIT OS SERVICES ---------------- */ 168 | ok = Terminal_OS_Init((void *)0); 169 | if (ok != DEF_OK) { /* If OS not init'd ... */ 170 | TerminalSerial_Exit(); /* ... exit serial if. */ 171 | } 172 | } 173 | 174 | return (ok); 175 | } 176 | 177 | 178 | /* 179 | ********************************************************************************************************* 180 | * Terminal_Task() 181 | * 182 | * Description : Terminal task. 183 | * 184 | * Argument(s) : p_arg Argument passed to the task (ignored). 185 | * 186 | * Return(s) : none. 187 | * 188 | * Caller(s) : Terminal OS port. 189 | * 190 | * Note(s) : none. 191 | ********************************************************************************************************* 192 | */ 193 | 194 | void Terminal_Task (void *p_arg) 195 | { 196 | CPU_CHAR cmd[TERMINAL_CFG_MAX_CMD_LEN + 1u]; 197 | CPU_SIZE_T cmd_len; 198 | SHELL_CMD_PARAM cmd_param; 199 | CPU_INT16S cmp_val; 200 | CPU_SIZE_T cursor_pos; 201 | CPU_CHAR cwd_path[TERMINAL_CFG_MAX_PATH_LEN + 1u]; 202 | SHELL_ERR err; 203 | CPU_INT08U esc_type; 204 | CPU_BOOLEAN ins; 205 | 206 | 207 | (void)p_arg; 208 | 209 | /* --------------------- INIT VARS -------------------- */ 210 | Mem_Set((void *)&cwd_path[0], /* Clr cur working dir path. */ 211 | (CPU_INT08U) 0x00u, 212 | (CPU_SIZE_T) TERMINAL_CFG_MAX_PATH_LEN); 213 | 214 | Str_Copy(cwd_path, (CPU_CHAR *)"\\"); 215 | 216 | Mem_Set((void *)&cmd[0], /* Clr cur line. */ 217 | (CPU_INT08U) 0x00u, 218 | (CPU_SIZE_T) TERMINAL_CFG_MAX_CMD_LEN); 219 | 220 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 221 | Terminal_HistoryInit(); 222 | Shell_CmdTblAdd((CPU_CHAR *)"Term", Terminal_CmdTbl, &err); 223 | #endif 224 | 225 | cursor_pos = 0u; 226 | cmd_len = 0u; 227 | ins = DEF_NO; 228 | 229 | cmd_param.pcur_working_dir = (void *)cwd_path; 230 | cmd_param.pout_opt = (void *)0; 231 | 232 | TerminalMode_Prompt(); /* Show first prompt. */ 233 | 234 | 235 | 236 | 237 | while (DEF_TRUE) { 238 | /* -------------------- RD NEW LINE ------------------- */ 239 | esc_type = TerminalMode_RdLine(&cmd[0], 240 | TERMINAL_CFG_MAX_CMD_LEN, 241 | &cursor_pos, 242 | ins); 243 | cmd_len = Str_Len(&cmd[0]); 244 | 245 | 246 | switch (esc_type) { 247 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 248 | case TERMINAL_ESC_TYPE_UP: /* ------------- MOVE TO PREV HISTORY ITEM ------------ */ 249 | TerminalMode_Clr(cmd_len, cursor_pos); /* Clr terminal line. */ 250 | Terminal_HistoryPrevGet(cmd); /* Get prev history item. */ 251 | cmd_len = Str_Len(cmd); 252 | cursor_pos = cmd_len; /* Cursor at end of line. */ 253 | Terminal_WrStr(cmd, cmd_len); /* Wr prev history item to terminal. */ 254 | break; 255 | 256 | 257 | 258 | case TERMINAL_ESC_TYPE_DOWN: /* ------------- MOVE TO NEXT HISTORY ITEM ------------ */ 259 | TerminalMode_Clr(cmd_len, cursor_pos); /* Clr terminal line. */ 260 | Terminal_HistoryNextGet(cmd); /* Get next history item. */ 261 | cmd_len = Str_Len(cmd); 262 | cursor_pos = cmd_len; /* Cursor at end of line. */ 263 | Terminal_WrStr(cmd, cmd_len); /* Wr next history item to terminal. */ 264 | break; 265 | #else 266 | 267 | 268 | 269 | 270 | case TERMINAL_ESC_TYPE_UP: /* ---------------- UNSUPPORTED UP/DOWN --------------- */ 271 | case TERMINAL_ESC_TYPE_DOWN: 272 | TerminalMode_Clr(cmd_len, cursor_pos); /* Clear line. */ 273 | Str_Copy(cmd, (CPU_CHAR *)""); 274 | break; 275 | #endif 276 | 277 | 278 | 279 | case TERMINAL_ESC_TYPE_INS: /* ---------------- TOGGLE INSERT MODE ---------------- */ 280 | if (ins == DEF_YES) { 281 | ins = DEF_NO; 282 | } else { 283 | ins = DEF_YES; 284 | } 285 | break; 286 | 287 | 288 | 289 | case TERMINAL_ESC_TYPE_NONE: /* --------------------- EXEC CMD --------------------- */ 290 | default: 291 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 292 | Terminal_HistoryPut(cmd); /* Put line into history. */ 293 | #endif 294 | 295 | cmp_val = Str_Cmp(cmd, (CPU_CHAR *)""); 296 | if (cmp_val != 0) { 297 | TerminalMode_NewLine(); /* Move to new line. */ 298 | 299 | cmp_val = Str_Cmp(cmd, (CPU_CHAR *)"?"); 300 | if (cmp_val == 0) { 301 | (void)Terminal_Help( Terminal_OutFnct, /* List all cmds ... */ 302 | &cmd_param); 303 | 304 | 305 | } else { 306 | (void)Shell_Exec( cmd, /* ... OR exec cmd. */ 307 | Terminal_OutFnct, 308 | &cmd_param, 309 | &err); 310 | 311 | switch (err) { 312 | case SHELL_ERR_CMD_NOT_FOUND: 313 | case SHELL_ERR_CMD_SEARCH: 314 | case SHELL_ERR_ARG_TBL_FULL: 315 | Terminal_WrStr((CPU_CHAR *)"Command not found\r\n", 19); 316 | break; 317 | 318 | case SHELL_ERR_NONE: 319 | case SHELL_ERR_NULL_PTR: 320 | case SHELL_ERR_CMD_EXEC: 321 | default: 322 | break; 323 | } 324 | } 325 | } 326 | 327 | 328 | 329 | /* ------------------ DISP NEW PROMPT ----------------- */ 330 | TerminalMode_Prompt(); /* Show new prompt. */ 331 | Str_Copy(cmd, (CPU_CHAR *)""); /* Clear cmd. */ 332 | cursor_pos = 0u; /* Cursor pos'd at beginning of line. */ 333 | break; 334 | } 335 | } 336 | } 337 | 338 | 339 | /* 340 | ********************************************************************************************************* 341 | * Terminal_WrStr() 342 | * 343 | * Description : Write string to terminal. 344 | * 345 | * Argument(s) : pbuf Pointer to the buffer to transmit. 346 | * 347 | * buf_len Number of bytes in the buffer. 348 | * 349 | * Return(s) : none. 350 | * 351 | * Caller(s) : various. 352 | * 353 | * Note(s) : none. 354 | ********************************************************************************************************* 355 | */ 356 | 357 | void Terminal_WrStr (CPU_CHAR *pbuf, 358 | CPU_SIZE_T buf_len) 359 | { 360 | TerminalSerial_Wr((void *)pbuf, 361 | (CPU_SIZE_T)buf_len); 362 | } 363 | 364 | 365 | /* 366 | ********************************************************************************************************* 367 | * Terminal_WrChar() 368 | * 369 | * Description : Write character to terminal. 370 | * 371 | * Argument(s) : c Character to transmit. 372 | * 373 | * Return(s) : none. 374 | * 375 | * Caller(s) : various. 376 | * 377 | * Note(s) : none. 378 | ********************************************************************************************************* 379 | */ 380 | 381 | void Terminal_WrChar (CPU_CHAR c) 382 | { 383 | TerminalSerial_WrByte((CPU_INT08U)c); 384 | } 385 | 386 | 387 | /* 388 | ********************************************************************************************************* 389 | ********************************************************************************************************* 390 | * LOCAL FUNCTIONS 391 | ********************************************************************************************************* 392 | ********************************************************************************************************* 393 | */ 394 | 395 | /* 396 | ********************************************************************************************************* 397 | * Terminal_OutFnct() 398 | * 399 | * Description : Out function used by Shell. 400 | * 401 | * Argument(s) : pbuf Pointer to the buffer contianing data to send. 402 | * 403 | * buf_len Length of buffer. 404 | * 405 | * popt Pointer to options (unused). 406 | * 407 | * Return(s) : Number of positive data octets transmitted. 408 | * 409 | * Caller(s) : Shell, as a result of command execution in Terminal_Task(). 410 | * 411 | * Note(s) : none. 412 | ********************************************************************************************************* 413 | */ 414 | 415 | static CPU_INT16S Terminal_OutFnct (CPU_CHAR *pbuf, 416 | CPU_INT16U buf_len, 417 | void *popt) 418 | { 419 | (void)popt; 420 | 421 | TerminalSerial_Wr((void *)pbuf, 422 | (CPU_SIZE_T)buf_len); 423 | 424 | return ((CPU_INT16S)buf_len); 425 | } 426 | 427 | 428 | /* 429 | ********************************************************************************************************* 430 | * Terminal_Help() 431 | * 432 | * Description : List all commands. 433 | * 434 | * Argument(s) : out_fnct The output function. 435 | * 436 | * pcmd_param Pointer to the command parameters. 437 | * 438 | * Return(s) : SHELL_EXEC_ERR, if an error is encountered. 439 | * SHELL_ERR_NONE, otherwise. 440 | * 441 | * Caller(s) : Shell, in response to command execution. 442 | * 443 | * Note(s) : none. 444 | ********************************************************************************************************* 445 | */ 446 | 447 | static CPU_INT16S Terminal_Help (SHELL_OUT_FNCT out_fnct, 448 | SHELL_CMD_PARAM *pcmd_param) 449 | { 450 | SHELL_CMD *pcmd; 451 | SHELL_MODULE_CMD *pmodule_cmd; 452 | 453 | 454 | pmodule_cmd = Shell_ModuleCmdUsedPoolPtr; 455 | while (pmodule_cmd != (SHELL_MODULE_CMD *)0) { 456 | pcmd = pmodule_cmd->CmdTblPtr; 457 | if (pcmd != (SHELL_CMD *)0) { 458 | while (pcmd->Fnct != (SHELL_CMD_FNCT)0) { 459 | (void)out_fnct((CPU_CHAR *)pcmd->Name, 460 | (CPU_INT16U)Str_Len(pcmd->Name), 461 | pcmd_param->pout_opt); 462 | (void)out_fnct(TERMINAL_NEW_LINE, 2, pcmd_param->pout_opt); 463 | pcmd++; 464 | } 465 | } 466 | pmodule_cmd = pmodule_cmd->NextModuleCmdPtr; 467 | } 468 | 469 | return (SHELL_ERR_NONE); 470 | } 471 | 472 | 473 | /* 474 | ********************************************************************************************************* 475 | * Terminal_HistoryInit() 476 | * 477 | * Description : Initialize terminal history. 478 | * 479 | * Argument(s) : none. 480 | * 481 | * Return(s) : none. 482 | * 483 | * Caller(s) : Terminal_Task(). 484 | * 485 | * Note(s) : (1) The history is implemented as a circular buffer of strings. Three indices and two 486 | * flags are used to track the state of the history buffer : 487 | * 488 | * (a) (1) If 'Terminal_HistoryShown' is DEF_YES, then the terminal displays a 489 | * (potentially modified) item from the history. This is the case after the up 490 | * key is pressed once the history buffer is no longer empty, until a command 491 | * is executed. 492 | * 493 | * (2) If 'Terminal_HistoryShown' is DEF_NO, then the terminal displays a bare 494 | * terminal, or text that the user typed on a bare terminal. This is the case 495 | * upon terminal startup or after execution of a command until the up key is 496 | * pressed. 497 | * 498 | * (b) If 'Terminal_HistoryEmpty' is DEF_YES, then the terminal history is empty. 499 | * This is used in two ways : 500 | * 501 | * (1) The 'up' key will not produce a change in the history state when the history 502 | * is empty. 503 | * 504 | * (2) The values of 'Terminal_HistoryIxFirst' and 'Terminal_HistoryIxLast' are 505 | * ignored when the first item is put into the buffer. Only when the terminal 506 | * history is non-empty are these valid indices. 507 | * 508 | * (c) 'Terminal_HistoryIxFirst' is the index of the first item in the history. The 509 | * index of the first item is ONLY changed once the user has logged more history 510 | * items than can be held in the history buffer, whereupon the index is incremented 511 | * to point to the next item in the buffer (since the old first item will have been 512 | * overwritten with the new last element). 513 | * 514 | * (d) 'Terminal_HistoryIxLast' is the index of the last item in the history. The 515 | * index of the last item is ONLY changed when elements are added to the history 516 | * buffer, whereupon the index is incremented to point to the new last item in the 517 | * buffer. 518 | * 519 | * (e) 'Terminal_HistoryIxShown' is the index of the history item shown on the terminal 520 | * (if 'Terminal_HistoryShown' is DEF_YES). 521 | ********************************************************************************************************* 522 | */ 523 | 524 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 525 | static void Terminal_HistoryInit (void) 526 | { 527 | CPU_INT16U history_ix; 528 | 529 | 530 | /* Clr history lines. */ 531 | for (history_ix = 0u; history_ix < TERMINAL_CFG_HISTORY_ITEMS_NBR; history_ix++) { 532 | Str_Copy(Terminal_History[history_ix], (CPU_CHAR *)""); 533 | } 534 | 535 | Terminal_HistoryIxFirst = 0u; /* See Notes #1b2. */ 536 | Terminal_HistoryIxLast = 0u; /* See Notes #1b2. */ 537 | Terminal_HistoryIxShown = 0u; 538 | Terminal_HistoryEmpty = DEF_YES; /* History empty (see Notes #1b). */ 539 | Terminal_HistoryShown = DEF_NO; /* History item NOT shown (see Notes #1a). */ 540 | 541 | Terminal_HistoryCnt = 0u; 542 | } 543 | #endif 544 | 545 | 546 | /* 547 | ********************************************************************************************************* 548 | * Terminal_HistoryPrevGet() 549 | * 550 | * Description : Copy previous history line into buffer. 551 | * 552 | * Argument(s) : pstr String buffer. 553 | * 554 | * Return(s) : none. 555 | * 556 | * Caller(s) : Terminal_Task(). 557 | * 558 | * Note(s) : See 'Terminal_HistoryInit() Note #1'. 559 | ********************************************************************************************************* 560 | */ 561 | 562 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 563 | static void Terminal_HistoryPrevGet (CPU_CHAR *pstr) 564 | { 565 | if (Terminal_HistoryShown == DEF_YES) { /* ---------- HISTORY ITEM DISP'D ON TERMINAL --------- */ 566 | /* If first item NOT shown ... show prev item. */ 567 | if (Terminal_HistoryIxShown != Terminal_HistoryIxFirst) { 568 | if (Terminal_HistoryIxShown == 0u) { 569 | Terminal_HistoryIxShown = TERMINAL_CFG_HISTORY_ITEMS_NBR - 1u; 570 | } else { 571 | Terminal_HistoryIxShown--; 572 | } 573 | } 574 | Str_Copy(pstr, Terminal_History[Terminal_HistoryIxShown]); 575 | 576 | 577 | 578 | 579 | } else { /* -------- HISTORY ITEM NOT DISP'D ON TERMINAL ------- */ 580 | if (Terminal_HistoryEmpty == DEF_NO) { /* If history buf NOT empty ... disp last item. */ 581 | Terminal_HistoryShown = DEF_YES; 582 | Terminal_HistoryIxShown = Terminal_HistoryIxLast; 583 | Str_Copy(pstr, Terminal_History[Terminal_HistoryIxShown]); 584 | } else { /* If history buf empty ... clr str buf. */ 585 | Str_Copy(pstr, (CPU_CHAR *)""); 586 | } 587 | } 588 | } 589 | #endif 590 | 591 | 592 | /* 593 | ********************************************************************************************************* 594 | * Terminal_HistoryNextGet() 595 | * 596 | * Description : Copy next history line into buffer. 597 | * 598 | * Argument(s) : pstr String buffer. 599 | * 600 | * Return(s) : none. 601 | * 602 | * Caller(s) : Terminal_Task(). 603 | * 604 | * Note(s) : See 'Terminal_HistoryInit() Note #1'. 605 | ********************************************************************************************************* 606 | */ 607 | 608 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 609 | static void Terminal_HistoryNextGet (CPU_CHAR *pstr) 610 | { 611 | if (Terminal_HistoryShown == DEF_YES) { /* ---------- HISTORY ITEM DISP'D ON TERMINAL --------- */ 612 | /* If last item is NOT being shown ... use next. */ 613 | if (Terminal_HistoryIxShown != Terminal_HistoryIxLast) { 614 | if (Terminal_HistoryIxShown == TERMINAL_CFG_HISTORY_ITEMS_NBR - 1u) { 615 | Terminal_HistoryIxShown = 0u; 616 | } else { 617 | Terminal_HistoryIxShown++; 618 | } 619 | } 620 | Str_Copy(pstr, Terminal_History[Terminal_HistoryIxShown]); 621 | } 622 | } 623 | #endif 624 | 625 | 626 | /* 627 | ********************************************************************************************************* 628 | * Terminal_HistoryPut() 629 | * 630 | * Description : Copy buffer into history. 631 | * 632 | * Argument(s) : pstr String buffer. 633 | * 634 | * Return(s) : none. 635 | * 636 | * Caller(s) : Terminal_Task(). 637 | * 638 | * Note(s) : See 'Terminal_HistoryInit() Note #1'. 639 | ********************************************************************************************************* 640 | */ 641 | 642 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 643 | static void Terminal_HistoryPut (CPU_CHAR *pstr) 644 | { 645 | CPU_INT16U cmp_val; 646 | 647 | 648 | Terminal_HistoryShown = DEF_NO; 649 | Terminal_HistoryIxShown = 0u; 650 | 651 | cmp_val = Str_Cmp(pstr, (CPU_CHAR *)""); 652 | if (cmp_val != 0) { 653 | Terminal_HistoryCnt++; 654 | 655 | if (Terminal_HistoryEmpty == DEF_YES) { 656 | Str_Copy_N(Terminal_History[0], pstr, TERMINAL_CFG_HISTORY_ITEM_LEN - 1u); 657 | Terminal_History[0][TERMINAL_CFG_HISTORY_ITEM_LEN - 1u] = (CPU_CHAR)0; 658 | Terminal_HistoryEmpty = DEF_NO; 659 | } else { 660 | /* Update ix of last item in history. */ 661 | if (Terminal_HistoryIxLast == TERMINAL_CFG_HISTORY_ITEMS_NBR - 1) { 662 | Terminal_HistoryIxLast = 0u; 663 | } else { 664 | Terminal_HistoryIxLast++; 665 | } 666 | 667 | /* Copy line into history. */ 668 | Str_Copy_N(Terminal_History[Terminal_HistoryIxLast], pstr, TERMINAL_CFG_HISTORY_ITEM_LEN - 1u); 669 | Terminal_History[Terminal_HistoryIxLast][TERMINAL_CFG_HISTORY_ITEM_LEN - 1u] = (CPU_CHAR)0; 670 | 671 | /* If last now first ... item overwr'n. */ 672 | if (Terminal_HistoryIxFirst == Terminal_HistoryIxLast) { 673 | if (Terminal_HistoryIxFirst == TERMINAL_CFG_HISTORY_ITEMS_NBR - 1u) { 674 | Terminal_HistoryIxFirst = 0u; 675 | } else { 676 | Terminal_HistoryIxFirst++; 677 | } 678 | } 679 | } 680 | } 681 | } 682 | #endif 683 | 684 | 685 | /* 686 | ********************************************************************************************************* 687 | * Terminal_fc() 688 | * 689 | * Description : Process the command history list. 690 | * 691 | * Argument(s) : argc The number of arguments. 692 | * 693 | * argv Array of arguments. 694 | * 695 | * out_fnct The output function. 696 | * 697 | * pcmd_param Pointer to the command parameters. 698 | * 699 | * Return(s) : SHELL_EXEC_ERR, if an error is encountered. 700 | * SHELL_ERR_NONE, otherwise. 701 | * 702 | * Caller(s) : Shell, in response to command execution. 703 | * 704 | * Note(s) : (1) (a) Usage(s) : Term_fc 705 | * 706 | * (b) Argument(s) : none. 707 | * 708 | * (c) Output : List of terminal history items. 709 | ********************************************************************************************************* 710 | */ 711 | 712 | #if (TERMINAL_CFG_HISTORY_EN == DEF_ENABLED) 713 | static CPU_INT16S Terminal_fc (CPU_INT16U argc, 714 | CPU_CHAR *argv[], 715 | SHELL_OUT_FNCT out_fnct, 716 | SHELL_CMD_PARAM *pcmd_param) 717 | { 718 | CPU_INT16U history_cnt; 719 | CPU_INT16U history_qty; 720 | CPU_INT16U history_item_len; 721 | CPU_INT16U history_ix; 722 | CPU_INT16U i; 723 | CPU_CHAR nbr_str[8]; 724 | 725 | 726 | /* ---------------- RESPOND TO HELP CMD --------------- */ 727 | if (argc == 2u) { 728 | if (Str_Cmp(argv[1], TERMINAL_STR_HELP) == 0) { 729 | (void)out_fnct(TERMINAL_ARG_ERR_FC, (CPU_INT16U)Str_Len(TERMINAL_ARG_ERR_FC), pcmd_param->pout_opt); 730 | (void)out_fnct(TERMINAL_NEW_LINE, 2u, pcmd_param->pout_opt); 731 | (void)out_fnct(TERMINAL_CMD_EXP_FC, (CPU_INT16U)Str_Len(TERMINAL_CMD_EXP_FC), pcmd_param->pout_opt); 732 | (void)out_fnct(TERMINAL_NEW_LINE, 2u, pcmd_param->pout_opt); 733 | return (SHELL_ERR_NONE); 734 | } 735 | } 736 | 737 | 738 | 739 | /* ----------------- HANDLE ARG QTY ERR --------------- */ 740 | if (argc != 1u) { 741 | (void)out_fnct(TERMINAL_ARG_ERR_FC, (CPU_INT16U)Str_Len(TERMINAL_ARG_ERR_FC), pcmd_param->pout_opt); 742 | (void)out_fnct(TERMINAL_NEW_LINE, 2u, pcmd_param->pout_opt); 743 | return (SHELL_EXEC_ERR); 744 | } 745 | 746 | 747 | 748 | /* --------------- LIST TERMINAL HISTORY -------------- */ 749 | if (Terminal_HistoryEmpty == DEF_YES) { /* If history empty ... rtn. */ 750 | return (SHELL_ERR_NONE); 751 | } 752 | 753 | /* Calc nbr of items in history. */ 754 | if (Terminal_HistoryIxLast >= Terminal_HistoryIxFirst) { 755 | history_qty = Terminal_HistoryIxLast - Terminal_HistoryIxFirst + 1u; 756 | } else { 757 | history_qty = TERMINAL_CFG_HISTORY_ITEMS_NBR; 758 | } 759 | 760 | history_cnt = Terminal_HistoryCnt - history_qty; 761 | history_ix = Terminal_HistoryIxFirst; 762 | for (i = 0u; i < history_qty; i++) { /* List each history item & item cnt. */ 763 | (void)Str_FmtNbr_Int32U(history_cnt, 764 | 7u, 765 | DEF_NBR_BASE_DEC, 766 | ASCII_CHAR_SPACE, 767 | DEF_NO, 768 | DEF_YES, 769 | nbr_str); 770 | 771 | history_item_len = (CPU_INT16U)Str_Len(Terminal_History[history_ix]); 772 | (void)out_fnct(nbr_str, 7u, pcmd_param->pout_opt); 773 | (void)out_fnct((CPU_CHAR *)" ", 5u, pcmd_param->pout_opt); 774 | (void)out_fnct(Terminal_History[history_ix], history_item_len, pcmd_param->pout_opt); 775 | (void)out_fnct(TERMINAL_NEW_LINE, 2u, pcmd_param->pout_opt); 776 | 777 | history_cnt++; 778 | history_ix++; 779 | if (history_ix == TERMINAL_CFG_HISTORY_ITEMS_NBR) { 780 | history_ix = 0u; 781 | } 782 | } 783 | 784 | return (SHELL_ERR_NONE); 785 | } 786 | #endif 787 | -------------------------------------------------------------------------------- /Source/shell.c: -------------------------------------------------------------------------------- 1 | /* 2 | ********************************************************************************************************* 3 | * uC/Shell 4 | * Shell utility 5 | * 6 | * Copyright 2007-2020 Silicon Laboratories Inc. www.silabs.com 7 | * 8 | * SPDX-License-Identifier: APACHE-2.0 9 | * 10 | * This software is subject to an open source license and is distributed by 11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License, 12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0. 13 | * 14 | ********************************************************************************************************* 15 | */ 16 | 17 | /* 18 | ********************************************************************************************************* 19 | * 20 | * SHELL UTILITY 21 | * 22 | * Filename : shell.c 23 | * Version : V1.04.00 24 | ********************************************************************************************************* 25 | */ 26 | 27 | /* 28 | ********************************************************************************************************* 29 | * INCLUDE FILES 30 | ********************************************************************************************************* 31 | */ 32 | 33 | #define SHELL_MODULE 34 | #include 35 | 36 | #include 37 | 38 | 39 | /* 40 | ********************************************************************************************************* 41 | * LOCAL DEFINES 42 | ********************************************************************************************************* 43 | */ 44 | 45 | 46 | /* 47 | ********************************************************************************************************* 48 | * LOCAL CONSTANTS 49 | ********************************************************************************************************* 50 | */ 51 | 52 | 53 | /* 54 | ********************************************************************************************************* 55 | * LOCAL DATA TYPES 56 | ********************************************************************************************************* 57 | */ 58 | 59 | 60 | /* 61 | ********************************************************************************************************* 62 | * LOCAL TABLES 63 | ********************************************************************************************************* 64 | */ 65 | 66 | 67 | /* 68 | ********************************************************************************************************* 69 | * LOCAL GLOBAL VARIABLES 70 | ********************************************************************************************************* 71 | */ 72 | 73 | 74 | /* 75 | ********************************************************************************************************* 76 | * INITIALIZED DATA 77 | ********************************************************************************************************* 78 | */ 79 | 80 | 81 | /* 82 | ********************************************************************************************************* 83 | * LOCAL FUNCTION PROTOTYPES 84 | ********************************************************************************************************* 85 | */ 86 | 87 | static CPU_INT16U Shell_Scanner (CPU_CHAR *in, 88 | CPU_CHAR *arg_tbl[], 89 | CPU_INT16U arg_tbl_size, 90 | SHELL_ERR *perr); 91 | 92 | static SHELL_CMD_FNCT Shell_CmdSearch (CPU_CHAR *cmd_name, 93 | SHELL_ERR *perr); 94 | 95 | static void Shell_ModuleCmdNameGet (CPU_CHAR *cmd_name, 96 | CPU_CHAR module_cmd_name[], 97 | CPU_INT16U len, 98 | SHELL_ERR *perr); 99 | 100 | static void Shell_ModuleCmdClr (SHELL_MODULE_CMD *pmodule_cmd); 101 | 102 | 103 | /* 104 | ********************************************************************************************************* 105 | * LOCAL CONFIGURATION ERRORS 106 | ********************************************************************************************************* 107 | */ 108 | 109 | 110 | /* 111 | ********************************************************************************************************* 112 | * Shell_Init() 113 | * 114 | * Description : Initialize the shell. 115 | * 116 | * Arguments : none. 117 | * 118 | * Returns : DEF_OK Shell initialization successful. 119 | * DEF_FAIL Shell server initialization failed. 120 | * 121 | * Caller(s) : Your Product's Application. 122 | * 123 | * This function is a Shell initialization function & MAY be called by 124 | * application/initialization function(s). 125 | * 126 | * Note(s) : (1) Shell_Init() MUST be called ... 127 | * 128 | * (a) BEFORE the other Shell function are invoked. 129 | * 130 | * (2) Shell_Init() MUST ONLY be called ONCE from product's application. 131 | * 132 | * (3) Module command pools MUST be initialized PRIOR to initializing the pool with 133 | * pointers to module commands. 134 | ********************************************************************************************************* 135 | */ 136 | 137 | CPU_BOOLEAN Shell_Init (void) 138 | { 139 | CPU_INT16U i; 140 | SHELL_MODULE_CMD *pmodule_cmd; 141 | 142 | 143 | /* ---------------- INIT SHELL CMD TBL ---------------- */ 144 | Shell_ModuleCmdUsedPoolPtr = DEF_NULL; /* Init-clr module cmd pools (see Note #3). */ 145 | Shell_ModuleCmdFreePoolPtr = DEF_NULL; 146 | 147 | pmodule_cmd = &Shell_ModuleCmdTbl[0]; 148 | for (i = 0; i < SHELL_CFG_CMD_TBL_SIZE; i++) { /* Free each module cmd to pool (see Note #3). */ 149 | Shell_ModuleCmdClr(pmodule_cmd); 150 | 151 | /* Init doubly-linked list. */ 152 | pmodule_cmd->PrevModuleCmdPtr = DEF_NULL; 153 | pmodule_cmd->NextModuleCmdPtr = Shell_ModuleCmdFreePoolPtr; 154 | 155 | if (Shell_ModuleCmdFreePoolPtr != DEF_NULL) { 156 | Shell_ModuleCmdFreePoolPtr->PrevModuleCmdPtr = pmodule_cmd; 157 | } 158 | 159 | Shell_ModuleCmdFreePoolPtr = pmodule_cmd; 160 | 161 | 162 | pmodule_cmd++; 163 | } 164 | 165 | return (DEF_OK); 166 | } 167 | 168 | 169 | /* 170 | ********************************************************************************************************* 171 | * Shell_Exec() 172 | * 173 | * Description : (1) Parse and execute command passed in parameter : 174 | * 175 | * (a) Parse input string 176 | * (b) Search command 177 | * (c) Execute command 178 | * 179 | * 180 | * Argument(s) : in Pointer to a CPU_CHAR string holding a complete command and its argument(s). 181 | * out_funt Pointer to 'output' function used by command (see Note #1). 182 | * pcmd_param Pointer to command additional parameters. 183 | * perr Pointer to variable that will receive the return error code from this 184 | * function : 185 | * 186 | * SHELL_ERR_NONE No error. 187 | * SHELL_ERR_NULL_PTR Argument 'in' passed a NULL pointer. 188 | * SHELL_ERR_CMD_NOT_FOUND Command NOT found. 189 | * SHELL_ERR_CMD_SEARCH Error searching for command. 190 | * SHELL_ERR_CMD_EXEC Error executing command. 191 | * 192 | * ----- RETURNED BY Shell_Scanner() : ----- 193 | * SHELL_ERR_ARG_TBL_FULL Argument table full and token still to be parsed. 194 | * 195 | * Return(s) : Command specific return value. 196 | * 197 | * Caller(s) : Application. 198 | * 199 | * Note(s) : (1) The command may generate some output that should be transmitted to some device (socket, 200 | * RS-232 link, ...). The caller of this function is hence responsible for the 201 | * implementation of such function, if output is desired. 202 | ********************************************************************************************************* 203 | */ 204 | 205 | CPU_INT16S Shell_Exec (CPU_CHAR *in, 206 | SHELL_OUT_FNCT out_fnct, 207 | SHELL_CMD_PARAM *pcmd_param, 208 | SHELL_ERR *perr) 209 | { 210 | CPU_INT16U argc; 211 | CPU_CHAR *argv[SHELL_CFG_CMD_ARG_NBR_MAX]; 212 | SHELL_CMD_FNCT cmd_fnct; 213 | CPU_INT16S ret_val; 214 | 215 | 216 | /* ------------------- VALIDATE PTR ------------------- */ 217 | if (in == DEF_NULL) { 218 | *perr = SHELL_ERR_NULL_PTR; 219 | return (0); 220 | } 221 | 222 | 223 | /* ------------------ PARSE INPUT STR ----------------- */ 224 | argc = Shell_Scanner(in, 225 | argv, 226 | SHELL_CFG_CMD_ARG_NBR_MAX, 227 | perr); 228 | 229 | if (*perr != SHELL_ERR_NONE) { 230 | return (0); 231 | } else if (argc == 0) { 232 | *perr = SHELL_ERR_MODULE_CMD_EMPTY; 233 | return (0); 234 | } 235 | 236 | 237 | /* -------------------- SEARCH CMD -------------------- */ 238 | cmd_fnct = Shell_CmdSearch(argv[0], perr); 239 | switch (*perr) { 240 | case SHELL_ERR_NONE: 241 | break; 242 | 243 | case SHELL_ERR_MODULE_CMD_NOT_FOUND: 244 | case SHELL_ERR_CMD_NOT_FOUND: 245 | case SHELL_ERR_MODULE_CMD_NAME_NONE: 246 | case SHELL_ERR_MODULE_CMD_NAME_TOO_LONG: 247 | *perr = SHELL_ERR_CMD_NOT_FOUND; 248 | return (0); 249 | 250 | case SHELL_ERR_MODULE_CMD_NAME_COPY: 251 | default: 252 | *perr = SHELL_ERR_CMD_SEARCH; 253 | return (0); 254 | } 255 | 256 | 257 | /* -------------------- EXECUTE CMD ------------------- */ 258 | ret_val = cmd_fnct(argc, argv, out_fnct, pcmd_param); 259 | 260 | if (ret_val == SHELL_EXEC_ERR) { 261 | *perr = SHELL_ERR_CMD_EXEC; 262 | } 263 | 264 | return (ret_val); 265 | } 266 | 267 | 268 | /* 269 | ********************************************************************************************************* 270 | * Shell_CmdTblAdd() 271 | * 272 | * Description : (1) Allocate & initialize a module command : 273 | * 274 | * (a) Validate module command 275 | * (b) Get a free module command 276 | * (c) Initialize module command 277 | * (d) Add to module command used pool. 278 | * 279 | * (2) The module command pools are implemented as doubly-linked lists : 280 | * 281 | * (a) 'Shell_ModuleCmdUsedPoolPtr' and 'Shell_ModuleCmdFreePoolPtr' point to the head 282 | * their module command pool. 283 | * 284 | * (b) Module command NextModuleCmdPtr's and PrevModuleCmdPtr's link each command to form 285 | * the module command pool doubly-linked list. 286 | * 287 | * (c) Module command are inserted & removed at the head of the module command pool lists. 288 | * 289 | * 290 | * Module commands are 291 | * inserted & removed 292 | * at the head 293 | * (see Note #2c) 294 | * 295 | * | NextModuleCmdPtr 296 | * | (see Note #2b) 297 | * v | 298 | * | 299 | * ------- ------- v ------- ------- 300 | * Module command Pool ---->| |------>| |------>| |------>| | 301 | * Pointer | | | | | | | | 302 | * | |<------| |<------| |<------| | 303 | * (see Note #2a) ------- ------- ------- ^ ------- 304 | * | 305 | * | 306 | * PrevModuleCmdPtr 307 | * (see Note #2b) 308 | * 309 | * | | 310 | * |<-----Pool of Free/Used Module Commands ------>| 311 | * | (see Note #2) | 312 | * 313 | * 314 | * 315 | * Argument(s) : cmd_tbl_name Pointer to character string representing the name of the command table. 316 | * cmd_tbl Command table to add. 317 | * perr Pointer to variable that will receive the return error code from this 318 | * function : 319 | * 320 | * SHELL_ERR_NONE No error. 321 | * SHELL_ERR_NULL_PTR Argument 'cmd_tbl' passed a NULL pointer. 322 | * SHELL_ERR_MODULE_CMD_EMPTY Command table empty. 323 | * SHELL_ERR_MODULE_CMD_ALREADY_IN Command table already added, or command 324 | * table name already used. 325 | * SHELL_ERR_MODULE_CMD_NONE_AVAIL NO available module command to allocate. 326 | * 327 | * ----- RETURNED BY Shell_ModuleCmdNameGet() : ----- 328 | * SHELL_ERR_MODULE_CMD_NAME_NONE NO module command name found. 329 | * SHELL_ERR_MODULE_CMD_NAME_TOO_LONG Module command name too long. 330 | * SHELL_ERR_MODULE_CMD_NAME_COPY Copy error. 331 | * 332 | * Return(s) : none. 333 | * 334 | * Caller(s) : Application. 335 | * 336 | * Note(s) : (3) The 'name' argument is the prefix of the commands in 'cmd_tbl'. In order to speed up 337 | * the command search, the shell first locate the appropriate table based on the prefix 338 | * of the command. Hence, it is mandatory that all commands in a table be named with 339 | * the same prefix. For instance, uC/TCP-IP related command displaying statistics should 340 | * look like : 341 | * 342 | * Net_stats 343 | * 344 | * while a file system command listing the current directory would be : 345 | * 346 | * FS_ls 347 | * 348 | * The names of those module commands are respectively 'Net' and 'FS'. 349 | * 350 | * (4) #### The 'cmd_tbl_name' parameter is not mandatory in the current implementation. 351 | * Although you could pass a 'NULL' value for this parameter, it is recommended to provide 352 | * the prefix of the commands in 'cmd_tbl' for future compatibility. 353 | * 354 | * However, passing NULL for this parameter will result in the first command prefix to 355 | * be extracted and used as the command table name. 356 | * 357 | * (5) If an empty character array is passed in the cmd_tbl_name parameter, the function 358 | * will extract the first command prefix to use as the command table name. 359 | ********************************************************************************************************* 360 | */ 361 | 362 | void Shell_CmdTblAdd (CPU_CHAR *cmd_tbl_name, 363 | SHELL_CMD cmd_tbl[], 364 | SHELL_ERR *perr) 365 | { 366 | SHELL_CMD *pcmd; 367 | CPU_SIZE_T name_len; 368 | CPU_CHAR tbl_name[SHELL_CFG_MODULE_CMD_NAME_LEN_MAX]; 369 | CPU_CHAR *ptbl_name; 370 | SHELL_MODULE_CMD *pmodule_cmd; 371 | CPU_INT16S name_compare; 372 | 373 | 374 | /* ------------------- VALIDATE PTR ------------------- */ 375 | if (cmd_tbl == DEF_NULL) { 376 | *perr = SHELL_ERR_NULL_PTR; 377 | return; 378 | } 379 | 380 | if (cmd_tbl[0].Fnct == (SHELL_CMD_FNCT)0) { /* If cmd tbl empty ... */ 381 | *perr = SHELL_ERR_MODULE_CMD_EMPTY; /* ... rtn err. */ 382 | return; 383 | } 384 | 385 | 386 | ptbl_name = DEF_NULL; 387 | 388 | if (cmd_tbl_name != DEF_NULL) { /* If cmd_tbl_name not null ... */ 389 | name_len = Str_Len(cmd_tbl_name); 390 | if (name_len >= SHELL_CFG_MODULE_CMD_NAME_LEN_MAX) { /* ... If name too long ... */ 391 | *perr = SHELL_ERR_MODULE_CMD_NAME_TOO_LONG; /* ... rtn err. */ 392 | return; 393 | 394 | } else if (name_len > 0) { /* ... else if name greater of 0 ... */ 395 | ptbl_name = cmd_tbl_name; /* ... use as tbl name. */ 396 | } 397 | } 398 | 399 | if (ptbl_name == DEF_NULL) { /* If cmd tbl name not gotten from param ... */ 400 | pcmd = &cmd_tbl[0]; 401 | Shell_ModuleCmdNameGet((CPU_CHAR *)pcmd->Name, /* ... get name from first command. */ 402 | tbl_name, 403 | SHELL_CFG_MODULE_CMD_NAME_LEN_MAX, 404 | perr); 405 | 406 | if (*perr != SHELL_ERR_NONE) { 407 | return; 408 | } 409 | ptbl_name = tbl_name; 410 | } 411 | 412 | 413 | /* -------------- CHK FOR DUPLICATE ENTRY ------------- */ 414 | pmodule_cmd = Shell_ModuleCmdUsedPoolPtr; 415 | while (pmodule_cmd != DEF_NULL) { 416 | name_compare = Str_Cmp(pmodule_cmd->Name, ptbl_name); 417 | 418 | if ((pmodule_cmd->CmdTblPtr == cmd_tbl) || /* If module name already used ... */ 419 | (name_compare == 0 )) { 420 | 421 | *perr = SHELL_ERR_MODULE_CMD_ALREADY_IN; /* ... rtn err. */ 422 | return; 423 | } 424 | 425 | pmodule_cmd = pmodule_cmd->NextModuleCmdPtr; 426 | } 427 | 428 | 429 | /* ------------------ GET MODULE CMD ------------------ */ 430 | if (Shell_ModuleCmdFreePoolPtr != DEF_NULL) { /* If module cmd pool NOT empty ... */ 431 | /* ... get one from pool. */ 432 | pmodule_cmd = Shell_ModuleCmdFreePoolPtr; 433 | Shell_ModuleCmdFreePoolPtr = pmodule_cmd->NextModuleCmdPtr; 434 | 435 | } else { /* If none avail ... */ 436 | *perr = SHELL_ERR_MODULE_CMD_NONE_AVAIL; /* ... rtn err. */ 437 | return; 438 | } 439 | 440 | 441 | /* ----------------- INIT MODULE CMD ------------------ */ 442 | Str_Copy(pmodule_cmd->Name, ptbl_name); 443 | pmodule_cmd->CmdTblPtr = cmd_tbl; 444 | 445 | 446 | /* ---------- ADD TO MODULE CMD TBL USED POOL --------- */ 447 | /* Update doubly-linked list. */ 448 | pmodule_cmd->PrevModuleCmdPtr = DEF_NULL; 449 | pmodule_cmd->NextModuleCmdPtr = Shell_ModuleCmdUsedPoolPtr; 450 | 451 | if (Shell_ModuleCmdUsedPoolPtr != DEF_NULL) { 452 | Shell_ModuleCmdUsedPoolPtr->PrevModuleCmdPtr = pmodule_cmd; 453 | } 454 | 455 | Shell_ModuleCmdUsedPoolPtr = pmodule_cmd; 456 | 457 | 458 | *perr = SHELL_ERR_NONE; 459 | } 460 | 461 | 462 | /* 463 | ********************************************************************************************************* 464 | * Shell_CmdTblRem() 465 | * 466 | * Description : (1) Remove a module command : 467 | * 468 | * (a) Search module command 469 | * (b) Remove module command 470 | * (c) Update module command pools 471 | * 472 | * 473 | * Argument(s) : cmd_tbl_name Pointer to character string representing the name of the command table. 474 | * perr Pointer to variable that will receive the return error code from this 475 | * function : 476 | * 477 | * SHELL_ERR_NONE No error. 478 | * SHELL_ERR_NULL_PTR Argument 'cmd_tbl_name' passed a NULL pointer. 479 | * SHELL_ERR_MODULE_CMD_NOT_FOUND Module command NOT found. 480 | * 481 | * Return(s) : none. 482 | * 483 | * Caller(s) : Application. 484 | * 485 | * Note(s) : none. 486 | ********************************************************************************************************* 487 | */ 488 | 489 | void Shell_CmdTblRem (CPU_CHAR *cmd_tbl_name, 490 | SHELL_ERR *perr) 491 | { 492 | SHELL_MODULE_CMD *pmodule_cmd_list; 493 | SHELL_MODULE_CMD *pmodule_cmd; 494 | CPU_INT16S name_compare; 495 | 496 | 497 | /* ------------------- VALIDATE PTR ------------------- */ 498 | if (cmd_tbl_name == DEF_NULL) { 499 | *perr = SHELL_ERR_NULL_PTR; 500 | return; 501 | } 502 | 503 | /* ----------------- SEARCH MODULE CMD ---------------- */ 504 | pmodule_cmd_list = Shell_ModuleCmdUsedPoolPtr; 505 | pmodule_cmd = DEF_NULL; 506 | 507 | while (pmodule_cmd_list != DEF_NULL) { 508 | name_compare = Str_Cmp(cmd_tbl_name, pmodule_cmd_list->Name); 509 | if (name_compare == 0) { 510 | pmodule_cmd = pmodule_cmd_list; 511 | break; 512 | } 513 | pmodule_cmd_list = pmodule_cmd_list->NextModuleCmdPtr; 514 | } 515 | 516 | if (pmodule_cmd == DEF_NULL) { 517 | *perr = SHELL_ERR_MODULE_CMD_NOT_FOUND; 518 | return; 519 | } 520 | 521 | 522 | /* ----------- REM MODULE CMD & UPDATE POOLS ---------- */ 523 | /* Update used module cmd pool. */ 524 | if (pmodule_cmd->PrevModuleCmdPtr != DEF_NULL) { /* If prev NOT NULL ... set prev's next to next. */ 525 | (pmodule_cmd->PrevModuleCmdPtr)->NextModuleCmdPtr = pmodule_cmd->NextModuleCmdPtr; 526 | } else { /* Else ... set used pool ptr to next. */ 527 | Shell_ModuleCmdUsedPoolPtr = pmodule_cmd->NextModuleCmdPtr; 528 | } 529 | 530 | if (pmodule_cmd->NextModuleCmdPtr != DEF_NULL) { /* If next NOT NULL ... set next's prev to prev. */ 531 | (pmodule_cmd->NextModuleCmdPtr)->PrevModuleCmdPtr = pmodule_cmd->PrevModuleCmdPtr; 532 | } 533 | 534 | /* Update free module cmd pool. */ 535 | Shell_ModuleCmdClr(pmodule_cmd); 536 | pmodule_cmd->NextModuleCmdPtr = Shell_ModuleCmdFreePoolPtr; 537 | 538 | if (Shell_ModuleCmdFreePoolPtr != DEF_NULL) { 539 | Shell_ModuleCmdFreePoolPtr->PrevModuleCmdPtr = pmodule_cmd; 540 | } 541 | 542 | Shell_ModuleCmdFreePoolPtr = pmodule_cmd; 543 | 544 | 545 | *perr = SHELL_ERR_NONE; 546 | } 547 | 548 | 549 | /* 550 | ********************************************************************************************************* 551 | ********************************************************************************************************* 552 | * LOCAL FUNCTIONS 553 | ********************************************************************************************************* 554 | ********************************************************************************************************* 555 | */ 556 | 557 | /* 558 | ********************************************************************************************************* 559 | * Shell_Scanner() 560 | * 561 | * Description : Scan and parse the command line. 562 | * 563 | * Argument(s) : in Pointer to a NUL terminated string holding a complete command and its 564 | * argument(s). 565 | * arg_tbl Array of pointer that will receive pointers to token. 566 | * arg_tbl_size Size of arg_tbl array. 567 | * perr Pointer to variable that will receive the return error code from this 568 | * function : 569 | * 570 | * SHELL_ERR_NONE No error. 571 | * SHELL_ERR_ARG_TBL_FULL Argument table full and token still to be parsed. 572 | * 573 | * Return(s) : Number of token(s) (command name and argument(s)). 574 | * 575 | * Caller(s) : Shell_Exec(). 576 | * 577 | * Note(s) : (1) The first token is always the command name itself. 578 | * 579 | * (2) This function modify the 'in' arguments by replacing token's delimiter characters by 580 | * termination character ('\0'). 581 | ********************************************************************************************************* 582 | */ 583 | 584 | static CPU_INT16U Shell_Scanner (CPU_CHAR *in, 585 | CPU_CHAR *arg_tbl[], 586 | CPU_INT16U arg_tbl_size, 587 | SHELL_ERR *perr) 588 | { 589 | CPU_CHAR *in_rd; 590 | CPU_INT16U tok_ix; 591 | CPU_BOOLEAN end_tok_found; 592 | CPU_BOOLEAN quote_opened; 593 | 594 | 595 | in_rd = in; 596 | tok_ix = 0; 597 | end_tok_found = DEF_YES; 598 | quote_opened = DEF_NO; 599 | 600 | /* ------------------ SCAN CMD LINE ------------------ */ 601 | while (*in_rd) { 602 | switch (*in_rd) { 603 | case SHELL_ASCII_QUOTE: /* Quote char found. */ 604 | if (quote_opened == DEF_YES) { 605 | quote_opened = DEF_NO; 606 | *in_rd = (CPU_CHAR)0; 607 | end_tok_found = DEF_YES; 608 | } else { 609 | quote_opened = DEF_YES; 610 | } 611 | 612 | break; 613 | 614 | case SHELL_ASCII_SPACE: /* Space char found. */ 615 | if ((end_tok_found == DEF_NO) && /* If first space between tok && quote NOT opened ... */ 616 | (quote_opened == DEF_NO)) { 617 | *in_rd = SHELL_ASCII_ARG_END; /* ... put termination char. */ 618 | end_tok_found = DEF_YES; 619 | } 620 | 621 | break; 622 | 623 | default: /* Other char found ... */ 624 | if (end_tok_found == DEF_YES) { 625 | if (tok_ix < arg_tbl_size) { 626 | arg_tbl[tok_ix] = in_rd; /* Set arg_tbl ptr to tok location. */ 627 | tok_ix++; 628 | end_tok_found = DEF_NO; 629 | } else { 630 | *perr = SHELL_ERR_ARG_TBL_FULL; 631 | return (0); 632 | } 633 | } 634 | 635 | break; 636 | } 637 | in_rd++; 638 | } 639 | 640 | 641 | *perr = SHELL_ERR_NONE; 642 | 643 | return (tok_ix); 644 | } 645 | 646 | 647 | /* 648 | ********************************************************************************************************* 649 | * Shell_CmdSearch() 650 | * 651 | * Description : (1) Search for specified command : 652 | * 653 | * (a) Extract module command name 654 | * (b) Search module command 655 | * (c) Search command in table 656 | * 657 | * 658 | * Argument(s) : cmd_name Pointer to command name. 659 | * perr Pointer to variable that will receive the return error code from this 660 | * function : 661 | * 662 | * SHELL_ERR_NONE No error. 663 | * SHELL_ERR_MODULE_CMD_NOT_FOUND Module command NOT found. 664 | * SHELL_ERR_CMD_NOT_FOUND Command NOT found. 665 | * 666 | * ----- RETURNED BY Shell_ModuleCmdNameGet() : ----- 667 | * SHELL_ERR_MODULE_CMD_NAME_NONE No module command name found. 668 | * SHELL_ERR_MODULE_CMD_NAME_TOO_LONG Module command name too long. 669 | * SHELL_ERR_MODULE_CMD_NAME_COPY Copy error. 670 | * 671 | * Return(s) : Pointer to command function. 672 | * 673 | * Caller(s) : Shell_Exec(). 674 | * 675 | * Note(s) : none. 676 | ********************************************************************************************************* 677 | */ 678 | 679 | static SHELL_CMD_FNCT Shell_CmdSearch (CPU_CHAR *cmd_name, 680 | SHELL_ERR *perr) 681 | { 682 | CPU_CHAR module_cmd_name[SHELL_CFG_MODULE_CMD_NAME_LEN_MAX]; 683 | SHELL_MODULE_CMD *pmodule_cmd_list; 684 | SHELL_MODULE_CMD *pmodule_cmd; 685 | SHELL_CMD *pcmd_list; 686 | SHELL_CMD *pcmd; 687 | CPU_INT16S name_compare; 688 | CPU_INT16U i; 689 | SHELL_CMD_FNCT fnct; 690 | 691 | /* ------------- INIT RECEIVE CMD NAME TBL ------------ */ 692 | for (i = 0; i < SHELL_CFG_MODULE_CMD_NAME_LEN_MAX; i++) { 693 | module_cmd_name[i] = SHELL_ASCII_ARG_END; 694 | } 695 | 696 | /* -------------- EXTRACT MODULE CMD NAME ------------- */ 697 | Shell_ModuleCmdNameGet(cmd_name, 698 | module_cmd_name, 699 | SHELL_CFG_MODULE_CMD_NAME_LEN_MAX, 700 | perr); 701 | 702 | if (*perr != SHELL_ERR_NONE) { 703 | return ((SHELL_CMD_FNCT)0); 704 | } 705 | 706 | /* ----------------- SEARCH MODULE CMD ---------------- */ 707 | pmodule_cmd_list = Shell_ModuleCmdUsedPoolPtr; 708 | pmodule_cmd = DEF_NULL; 709 | 710 | while (pmodule_cmd_list != DEF_NULL) { 711 | name_compare = Str_Cmp(module_cmd_name, pmodule_cmd_list->Name); 712 | if (name_compare == 0) { 713 | pmodule_cmd = pmodule_cmd_list; 714 | break; 715 | } 716 | pmodule_cmd_list = pmodule_cmd_list->NextModuleCmdPtr; 717 | } 718 | 719 | if (pmodule_cmd == DEF_NULL) { 720 | *perr = SHELL_ERR_MODULE_CMD_NOT_FOUND; 721 | return ((SHELL_CMD_FNCT)0); 722 | } 723 | 724 | 725 | /* -------------------- SEARCH CMD -------------------- */ 726 | pcmd_list = pmodule_cmd->CmdTblPtr; 727 | pcmd = DEF_NULL; 728 | 729 | while (pcmd_list->Fnct != (SHELL_CMD_FNCT)0) { 730 | name_compare = Str_Cmp(cmd_name, pcmd_list->Name); 731 | if (name_compare == 0) { 732 | pcmd = pcmd_list; 733 | break; 734 | } 735 | pcmd_list++; 736 | } 737 | 738 | if (pcmd == DEF_NULL) { 739 | *perr = SHELL_ERR_CMD_NOT_FOUND; 740 | return ((SHELL_CMD_FNCT)0); 741 | } 742 | 743 | /* ---------------------- RTN CMD --------------------- */ 744 | *perr = SHELL_ERR_NONE; 745 | fnct = (SHELL_CMD_FNCT)pcmd->Fnct; 746 | 747 | return (fnct); 748 | } 749 | 750 | 751 | /* 752 | ********************************************************************************************************* 753 | * Shell_ModuleCmdNameGet() 754 | * 755 | * Description : (1) Get the command module name (prefix) from a command string : 756 | * 757 | * (a) Search for module command name delimiter 758 | * (b) Copy module command name 759 | * 760 | * 761 | * Argument(s) : cmd_str Pointer to command string holding the command module name. 762 | * module_cmd_name Pointer to a preallocated variable that will receive the module 763 | * command name. 764 | * len Length of the array pointed by 'module_cmd_name'. 765 | * perr Pointer to variable that will receive the return error code from this 766 | * function : 767 | * 768 | * SHELL_ERR_NONE No error. 769 | * SHELL_ERR_MODULE_CMD_NAME_NONE No module command name found. 770 | * SHELL_ERR_MODULE_CMD_NAME_TOO_LONG Module command name too long. 771 | * SHELL_ERR_MODULE_CMD_NAME_COPY Copy error. 772 | * 773 | * Return(s) : none. 774 | * 775 | * Caller(s) : Shell_CmdTblAdd(), 776 | * Shell_CmdSearch(). 777 | * 778 | * Note(s) : (2) The command module name consists in the first part of a command part, that is the 779 | * part preceding the underscore ('_') character. If there is no underscored character, 780 | * the command name is interpreted as the commande module name. 781 | ********************************************************************************************************* 782 | */ 783 | 784 | static void Shell_ModuleCmdNameGet (CPU_CHAR *cmd_str, 785 | CPU_CHAR module_cmd_name[], 786 | CPU_INT16U len, 787 | SHELL_ERR *perr) 788 | { 789 | CPU_CHAR *pcmd; 790 | CPU_BOOLEAN found; 791 | CPU_INT16U name_len; 792 | CPU_CHAR *copy_ret_val; 793 | 794 | 795 | pcmd = cmd_str; 796 | found = DEF_NO; 797 | 798 | /* --------- SEARCH MODULE CMD NAME DELIMITER --------- */ 799 | while ((pcmd != DEF_NULL) && 800 | (found == DEF_NO)) { 801 | 802 | if (*pcmd == SHELL_ASCII_CDM_NAME_DELIMITER) { 803 | found = DEF_YES; 804 | break; 805 | } else if (*pcmd == SHELL_ASCII_ARG_END) { 806 | found = DEF_YES; 807 | break; 808 | } 809 | pcmd++; 810 | } 811 | 812 | if (found == DEF_NO) { 813 | *perr = SHELL_ERR_MODULE_CMD_NAME_NONE; 814 | return; 815 | } 816 | 817 | 818 | /* --------------- COPY MODULE CMD NAME --------------- */ 819 | name_len = (pcmd - cmd_str); 820 | if (name_len >= len) { /* If module cmd name too long ... */ 821 | *perr = SHELL_ERR_MODULE_CMD_NAME_TOO_LONG; /* ... rtn with error. */ 822 | return; 823 | } 824 | 825 | copy_ret_val = Str_Copy_N(module_cmd_name, cmd_str, name_len); 826 | if (copy_ret_val == (CPU_CHAR)0) { 827 | *perr = SHELL_ERR_MODULE_CMD_NAME_COPY; 828 | return; 829 | } 830 | 831 | 832 | *perr = SHELL_ERR_NONE; 833 | } 834 | 835 | 836 | /* 837 | ********************************************************************************************************* 838 | * Shell_ModuleCmdClr() 839 | * 840 | * Description : Clear module command. 841 | * 842 | * Argument(s) : pmodule_cmd Pointer to module command. 843 | * 844 | * Return(s) : none. 845 | * 846 | * Caller(s) : Shell_Init(), 847 | * Shell_CmdTblRem(). 848 | * 849 | * Note(s) : none. 850 | ********************************************************************************************************* 851 | */ 852 | 853 | static void Shell_ModuleCmdClr (SHELL_MODULE_CMD *pmodule_cmd) 854 | { 855 | Str_Copy(pmodule_cmd->Name, ""); 856 | 857 | pmodule_cmd->PrevModuleCmdPtr = DEF_NULL; 858 | pmodule_cmd->NextModuleCmdPtr = DEF_NULL; 859 | 860 | pmodule_cmd->CmdTblPtr = DEF_NULL; 861 | } 862 | 863 | --------------------------------------------------------------------------------