1 /* 2 * Copyright (c) 2015, Freescale Semiconductor, Inc. 3 * Copyright 2016-2022 NXP 4 * All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 #ifndef __FSL_SHELL_H__ 10 #define __FSL_SHELL_H__ 11 12 /*! 13 * @addtogroup SHELL 14 * @{ 15 */ 16 17 #include "fsl_common.h" 18 #include "fsl_component_serial_manager.h" 19 #include "fsl_component_generic_list.h" 20 21 /******************************************************************************* 22 * Definitions 23 ******************************************************************************/ 24 25 /*! @brief Whether use non-blocking mode. */ 26 #ifndef SHELL_NON_BLOCKING_MODE 27 #define SHELL_NON_BLOCKING_MODE SERIAL_MANAGER_NON_BLOCKING_MODE 28 #endif 29 30 /*! @brief Macro to set on/off auto-complete feature. */ 31 #define SHELL_AUTO_COMPLETE (1U) 32 33 /*! @brief Macro to set console buffer size. */ 34 #ifndef SHELL_BUFFER_SIZE 35 #define SHELL_BUFFER_SIZE (64U) 36 #endif 37 38 /*! @brief Macro to set maximum arguments in command. */ 39 #define SHELL_MAX_ARGS (8U) 40 41 /*! @brief Macro to set maximum count of history commands. */ 42 #ifndef SHELL_HISTORY_COUNT 43 #define SHELL_HISTORY_COUNT (3U) 44 #endif 45 46 /*! @brief Macro to bypass arguments check */ 47 #define SHELL_IGNORE_PARAMETER_COUNT (0xFF) 48 49 /*! @brief The handle size of the shell module. It is the sum of the SHELL_HISTORY_COUNT * SHELL_BUFFER_SIZE + 50 * SHELL_BUFFER_SIZE + SERIAL_MANAGER_READ_HANDLE_SIZE + SERIAL_MANAGER_WRITE_HANDLE_SIZE*/ 51 #define SHELL_HANDLE_SIZE \ 52 (160U + SHELL_HISTORY_COUNT * SHELL_BUFFER_SIZE + SHELL_BUFFER_SIZE + SERIAL_MANAGER_READ_HANDLE_SIZE + \ 53 SERIAL_MANAGER_WRITE_HANDLE_SIZE) 54 55 /*! @brief Macro to determine whether use common task. */ 56 #ifndef SHELL_USE_COMMON_TASK 57 #define SHELL_USE_COMMON_TASK (0U) 58 #endif 59 60 /*! @brief Macro to set shell task priority. */ 61 #ifndef SHELL_TASK_PRIORITY 62 #define SHELL_TASK_PRIORITY (2U) 63 #endif 64 65 /*! @brief Macro to set shell task stack size. */ 66 #ifndef SHELL_TASK_STACK_SIZE 67 #define SHELL_TASK_STACK_SIZE (1000U) 68 #endif 69 70 /*! @brief Shell status */ 71 typedef enum _shell_status 72 { 73 kStatus_SHELL_Success = kStatus_Success, /*!< Success */ 74 kStatus_SHELL_Error = MAKE_STATUS(kStatusGroup_SHELL, 1), /*!< Failed */ 75 kStatus_SHELL_OpenWriteHandleFailed = MAKE_STATUS(kStatusGroup_SHELL, 2), /*!< Open write handle failed */ 76 kStatus_SHELL_OpenReadHandleFailed = MAKE_STATUS(kStatusGroup_SHELL, 3), /*!< Open read handle failed */ 77 kStatus_SHELL_RetUsage = MAKE_STATUS(kStatusGroup_SHELL, 4), /*!< RetUsage for print cmd usage */ 78 } shell_status_t; 79 80 /*! @brief The handle of the shell module */ 81 typedef void *shell_handle_t; 82 83 /*! @brief User command function prototype. */ 84 typedef shell_status_t (*cmd_function_t)(shell_handle_t shellHandle, int32_t argc, char **argv); 85 86 /*! @brief User command data configuration structure. */ 87 typedef struct _shell_command 88 { 89 const char *pcCommand; /*!< The command that is executed. For example "help". It must be all lower case. */ 90 char *pcHelpString; /*!< String that describes how to use the command. It should start with the command itself, 91 and end with "\r\n". For example "help: Returns a list of all the commands\r\n". */ 92 const cmd_function_t 93 pFuncCallBack; /*!< A pointer to the callback function that returns the output generated by the command. */ 94 uint8_t cExpectedNumberOfParameters; /*!< Commands expect a fixed number of parameters, which may be zero. */ 95 list_element_t link; /*!< link of the element */ 96 } shell_command_t; 97 98 /*! 99 * @brief Defines the shell handle 100 * 101 * This macro is used to define a 4 byte aligned shell handle. 102 * Then use "(shell_handle_t)name" to get the shell handle. 103 * 104 * The macro should be global and could be optional. You could also define shell handle by yourself. 105 * 106 * This is an example, 107 * @code 108 * SHELL_HANDLE_DEFINE(shellHandle); 109 * @endcode 110 * 111 * @param name The name string of the shell handle. 112 */ 113 #define SHELL_HANDLE_DEFINE(name) uint32_t name[((SHELL_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))] 114 115 #if defined(__ICCARM__) 116 /* disable misra 19.13 */ 117 _Pragma("diag_suppress=Pm120") 118 #endif 119 /*! 120 * @brief Defines the shell command structure 121 * 122 * This macro is used to define the shell command structure #shell_command_t. 123 * And then uses the macro SHELL_COMMAND to get the command structure pointer. 124 * The macro should not be used in any function. 125 * 126 * This is a example, 127 * @code 128 * SHELL_COMMAND_DEFINE(exit, "\r\n\"exit\": Exit program\r\n", SHELL_ExitCommand, 0); 129 * SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(exit)); 130 * @endcode 131 * 132 * @param command The command string of the command. The double quotes do not need. Such as exit for "exit", 133 * help for "Help", read for "read". 134 * @param descriptor The description of the command is used for showing the command usage when "help" is typing. 135 * @param callback The callback of the command is used to handle the command line when the input command is matched. 136 * @param paramCount The max parameter count of the current command. 137 */ 138 #define SHELL_COMMAND_DEFINE(command, descriptor, callback, paramCount) \ 139 \ 140 shell_command_t g_shellCommand##command = { \ 141 (#command), (descriptor), (callback), (paramCount), {0}, \ 142 } 143 144 /*! 145 * @brief Gets the shell command pointer 146 * 147 * This macro is used to get the shell command pointer. The macro should not be used before the macro 148 * SHELL_COMMAND_DEFINE is used. 149 * 150 * @param command The command string of the command. The double quotes do not need. Such as exit for "exit", 151 * help for "Help", read for "read". 152 */ 153 #define SHELL_COMMAND(command) &g_shellCommand##command 154 155 #if defined(__ICCARM__) 156 _Pragma("diag_default=Pm120") 157 #endif 158 159 /******************************************************************************* 160 * API 161 ******************************************************************************/ 162 163 #if defined(__cplusplus) 164 extern "C" 165 { 166 #endif /* _cplusplus */ 167 168 /*! 169 * @name Shell functional operation 170 * @{ 171 */ 172 173 /*! 174 * @brief Initializes the shell module 175 * 176 * This function must be called before calling all other Shell functions. 177 * Call operation the Shell commands with user-defined settings. 178 * The example below shows how to set up the Shell and 179 * how to call the SHELL_Init function by passing in these parameters. 180 * This is an example. 181 * @code 182 * static SHELL_HANDLE_DEFINE(s_shellHandle); 183 * SHELL_Init((shell_handle_t)s_shellHandle, (serial_handle_t)s_serialHandle, "Test@SHELL>"); 184 * @endcode 185 * @param shellHandle Pointer to point to a memory space of size #SHELL_HANDLE_SIZE allocated by the caller. 186 * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices. 187 * You can define the handle in the following two ways: 188 * #SHELL_HANDLE_DEFINE(shellHandle); 189 * or 190 * uint32_t shellHandle[((SHELL_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))]; 191 * @param serialHandle The serial manager module handle pointer. 192 * @param prompt The string prompt pointer of Shell. Only the global variable can be passed. 193 * @retval kStatus_SHELL_Success The shell initialization succeed. 194 * @retval kStatus_SHELL_Error An error occurred when the shell is initialized. 195 * @retval kStatus_SHELL_OpenWriteHandleFailed Open the write handle failed. 196 * @retval kStatus_SHELL_OpenReadHandleFailed Open the read handle failed. 197 */ 198 shell_status_t SHELL_Init(shell_handle_t shellHandle, serial_handle_t serialHandle, char *prompt); 199 200 /*! 201 * @brief Registers the shell command 202 * 203 * This function is used to register the shell command by using the command configuration shell_command_config_t. 204 * This is a example, 205 * @code 206 * SHELL_COMMAND_DEFINE(exit, "\r\n\"exit\": Exit program\r\n", SHELL_ExitCommand, 0); 207 * SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(exit)); 208 * @endcode 209 * @param shellHandle The shell module handle pointer. 210 * @param shellCommand The command element. 211 * @retval kStatus_SHELL_Success Successfully register the command. 212 * @retval kStatus_SHELL_Error An error occurred. 213 */ 214 shell_status_t SHELL_RegisterCommand(shell_handle_t shellHandle, shell_command_t * shellCommand); 215 216 /*! 217 * @brief Unregisters the shell command 218 * 219 * This function is used to unregister the shell command. 220 * 221 * @param shellCommand The command element. 222 * @retval kStatus_SHELL_Success Successfully unregister the command. 223 */ 224 shell_status_t SHELL_UnregisterCommand(shell_command_t * shellCommand); 225 226 /*! 227 * @brief Sends data to the shell output stream. 228 * 229 * This function is used to send data to the shell output stream. 230 * 231 * @param shellHandle The shell module handle pointer. 232 * @param buffer Start address of the data to write. 233 * @param length Length of the data to write. 234 * @retval kStatus_SHELL_Success Successfully send data. 235 * @retval kStatus_SHELL_Error An error occurred. 236 */ 237 shell_status_t SHELL_Write(shell_handle_t shellHandle, const char *buffer, uint32_t length); 238 239 /*! 240 * @brief Writes formatted output to the shell output stream. 241 * 242 * Call this function to write a formatted output to the shell output stream. 243 * 244 * @param shellHandle The shell module handle pointer. 245 * 246 * @param formatString Format string. 247 * @return Returns the number of characters printed or a negative value if an error occurs. 248 */ 249 int SHELL_Printf(shell_handle_t shellHandle, const char *formatString, ...); 250 /*! 251 * @brief Sends data to the shell output stream with OS synchronization. 252 * 253 * This function is used to send data to the shell output stream with OS synchronization, note the function could 254 * not be called in ISR. 255 * 256 * @param shellHandle The shell module handle pointer. 257 * @param buffer Start address of the data to write. 258 * @param length Length of the data to write. 259 * @retval kStatus_SHELL_Success Successfully send data. 260 * @retval kStatus_SHELL_Error An error occurred. 261 */ 262 shell_status_t SHELL_WriteSynchronization(shell_handle_t shellHandle, const char *buffer, uint32_t length); 263 264 /*! 265 * @brief Writes formatted output to the shell output stream with OS synchronization. 266 * 267 * Call this function to write a formatted output to the shell output stream with OS synchronization, note the 268 * function could not be called in ISR. 269 * 270 * @param shellHandle The shell module handle pointer. 271 * 272 * @param formatString Format string. 273 * @return Returns the number of characters printed or a negative value if an error occurs. 274 */ 275 int SHELL_PrintfSynchronization(shell_handle_t shellHandle, const char *formatString, ...); 276 /*! 277 * @brief Change shell prompt. 278 * 279 * Call this function to change shell prompt. 280 * 281 * @param shellHandle The shell module handle pointer. 282 * 283 * @param prompt The string which will be used for command prompt 284 * @return NULL. 285 */ 286 void SHELL_ChangePrompt(shell_handle_t shellHandle, char *prompt); 287 288 /*! 289 * @brief Print shell prompt. 290 * 291 * Call this function to print shell prompt. 292 * 293 * @param shellHandle The shell module handle pointer. 294 * 295 * @return NULL. 296 */ 297 void SHELL_PrintPrompt(shell_handle_t shellHandle); 298 299 /*! 300 * @brief The task function for Shell. 301 * The task function for Shell; The function should be polled by upper layer. 302 * This function does not return until Shell command exit was called. 303 * 304 * @param shellHandle The shell module handle pointer. 305 */ 306 #if !(defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U)) 307 void SHELL_Task(shell_handle_t shellHandle); 308 #endif 309 310 /*! 311 * @brief Check if code is running in ISR. 312 * 313 * This function is used to check if code running in ISR. 314 * 315 * @retval TRUE if code runing in ISR. 316 */ SHELL_checkRunningInIsr(void)317 static inline bool SHELL_checkRunningInIsr(void) 318 { 319 #if (defined(__DSC__) && defined(__CW__)) 320 return !(isIRQAllowed()); 321 #elif defined(__GIC_PRIO_BITS) 322 return (0x13 == (__get_CPSR() & CPSR_M_Msk)); 323 #elif defined(__get_IPSR) 324 return (0U != __get_IPSR()); 325 #else 326 return false; 327 #endif 328 } 329 330 /* @} */ 331 332 #if defined(__cplusplus) 333 } 334 #endif 335 336 /*! @}*/ 337 338 #endif /* __FSL_SHELL_H__ */ 339