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