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