1 | /* |
2 | * This is a modified version of the file printf.c, which was distributed |
3 | * by Motorola as part of the M5407C3BOOT.zip package used to initialize |
4 | * the M5407C3 evaluation board. |
5 | * |
6 | * Copyright: |
7 | * 1999-2000 MOTOROLA, INC. All Rights Reserved. |
8 | * You are hereby granted a copyright license to use, modify, and |
9 | * distribute the SOFTWARE so long as this entire notice is |
10 | * retained without alteration in any modified and/or redistributed |
11 | * versions, and that such modified versions are clearly identified |
12 | * as such. No licenses are granted by implication, estoppel or |
13 | * otherwise under any patents or trademarks of Motorola, Inc. This |
14 | * software is provided on an "AS IS" basis and without warranty. |
15 | * |
16 | * To the maximum extent permitted by applicable law, MOTOROLA |
17 | * DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR |
19 | * PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE |
20 | * SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY |
21 | * ACCOMPANYING WRITTEN MATERIALS. |
22 | * |
23 | * To the maximum extent permitted by applicable law, IN NO EVENT |
24 | * SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING |
25 | * WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS |
26 | * INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY |
27 | * LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. |
28 | * |
29 | * Motorola assumes no responsibility for the maintenance and support |
30 | * of this software |
31 | |
32 | * Copyright (c) 2015, Freescale Semiconductor, Inc. |
33 | * Copyright 2016-2020 NXP |
34 | * |
35 | * SPDX-License-Identifier: BSD-3-Clause |
36 | */ |
37 | |
38 | #include <stdarg.h> |
39 | #include <stdlib.h> |
40 | #if defined(__CC_ARM) || defined(__ARMCC_VERSION) |
41 | #include <stdio.h> |
42 | #endif |
43 | |
44 | #ifdef SDK_OS_FREE_RTOS |
45 | #include "FreeRTOS.h" |
46 | #include "semphr.h" |
47 | #include "task.h" |
48 | #endif |
49 | |
50 | #include "fsl_debug_console_conf.h" |
51 | #include "fsl_str.h" |
52 | |
53 | #include "fsl_common.h" |
54 | #include "fsl_component_serial_manager.h" |
55 | |
56 | #include "fsl_debug_console.h" |
57 | |
58 | /******************************************************************************* |
59 | * Definitions |
60 | ******************************************************************************/ |
61 | #ifndef NDEBUG |
62 | #if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U)) |
63 | #undef assert |
64 | #define assert(n) |
65 | #else |
66 | /* MISRA C-2012 Rule 17.2 */ |
67 | #undef assert |
68 | #define assert(n) \ |
69 | while (!(n)) \ |
70 | { \ |
71 | ; \ |
72 | } |
73 | #endif |
74 | #endif |
75 | |
76 | #if SDK_DEBUGCONSOLE |
77 | #define DEBUG_CONSOLE_FUNCTION_PREFIX |
78 | #else |
79 | #define DEBUG_CONSOLE_FUNCTION_PREFIX static |
80 | #endif |
81 | |
82 | /*! @brief character backspace ASCII value */ |
83 | #define DEBUG_CONSOLE_BACKSPACE 127U |
84 | |
85 | /* lock definition */ |
86 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
87 | |
88 | static SemaphoreHandle_t s_debugConsoleReadSemaphore; |
89 | #if configSUPPORT_STATIC_ALLOCATION |
90 | static StaticSemaphore_t s_debugConsoleReadSemaphoreStatic; |
91 | #endif |
92 | #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
93 | static SemaphoreHandle_t s_debugConsoleReadWaitSemaphore; |
94 | #if configSUPPORT_STATIC_ALLOCATION |
95 | static StaticSemaphore_t s_debugConsoleReadWaitSemaphoreStatic; |
96 | #endif |
97 | #endif |
98 | |
99 | #elif (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) |
100 | |
101 | #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
102 | static volatile bool s_debugConsoleReadWaitSemaphore; |
103 | #endif |
104 | |
105 | #else |
106 | |
107 | #endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */ |
108 | |
109 | /*! @brief get current runing environment is ISR or not */ |
110 | #ifdef __CA7_REV |
111 | #define IS_RUNNING_IN_ISR() SystemGetIRQNestingLevel() |
112 | #else |
113 | #define IS_RUNNING_IN_ISR() __get_IPSR() |
114 | #endif /* __CA7_REV */ |
115 | |
116 | /* semaphore definition */ |
117 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
118 | |
119 | /* mutex semaphore */ |
120 | /* clang-format off */ |
121 | #if configSUPPORT_STATIC_ALLOCATION |
122 | #define DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(mutex, stack) ((mutex) = xSemaphoreCreateMutexStatic(stack)) |
123 | #else |
124 | #define DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(mutex) ((mutex) = xSemaphoreCreateMutex()) |
125 | #endif |
126 | #define DEBUG_CONSOLE_DESTROY_MUTEX_SEMAPHORE(mutex) \ |
127 | do \ |
128 | { \ |
129 | if(NULL != (mutex)) \ |
130 | { \ |
131 | vSemaphoreDelete(mutex); \ |
132 | (mutex) = NULL; \ |
133 | } \ |
134 | } while(false) |
135 | |
136 | #define DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(mutex) \ |
137 | { \ |
138 | if (IS_RUNNING_IN_ISR() == 0U) \ |
139 | { \ |
140 | (void)xSemaphoreGive(mutex); \ |
141 | } \ |
142 | } |
143 | |
144 | #define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) \ |
145 | { \ |
146 | if (IS_RUNNING_IN_ISR() == 0U) \ |
147 | { \ |
148 | (void)xSemaphoreTake(mutex, portMAX_DELAY); \ |
149 | } \ |
150 | } |
151 | |
152 | #define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) \ |
153 | { \ |
154 | if (IS_RUNNING_IN_ISR() == 0U) \ |
155 | { \ |
156 | result = xSemaphoreTake(mutex, 0U); \ |
157 | } \ |
158 | else \ |
159 | { \ |
160 | result = 1U; \ |
161 | } \ |
162 | } |
163 | |
164 | /* Binary semaphore */ |
165 | #if configSUPPORT_STATIC_ALLOCATION |
166 | #define DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(binary,stack) ((binary) = xSemaphoreCreateBinaryStatic(stack)) |
167 | #else |
168 | #define DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(binary) ((binary) = xSemaphoreCreateBinary()) |
169 | #endif |
170 | #define DEBUG_CONSOLE_DESTROY_BINARY_SEMAPHORE(binary) \ |
171 | do \ |
172 | { \ |
173 | if(NULL != (binary)) \ |
174 | { \ |
175 | vSemaphoreDelete((binary)); \ |
176 | (binary) = NULL; \ |
177 | } \ |
178 | } while(false) |
179 | #define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) ((void)xSemaphoreTake((binary), portMAX_DELAY)) |
180 | #define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) ((void)xSemaphoreGiveFromISR((binary), NULL)) |
181 | |
182 | #elif (DEBUG_CONSOLE_SYNCHRONIZATION_BM == DEBUG_CONSOLE_SYNCHRONIZATION_MODE) |
183 | |
184 | #define DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(mutex) (void)(mutex) |
185 | #define DEBUG_CONSOLE_DESTROY_MUTEX_SEMAPHORE(mutex) (void)(mutex) |
186 | #define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) (void)(mutex) |
187 | #define DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(mutex) (void)(mutex) |
188 | #define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) (result = 1U) |
189 | |
190 | #define DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(binary) (void)(binary) |
191 | #define DEBUG_CONSOLE_DESTROY_BINARY_SEMAPHORE(binary) (void)(binary) |
192 | #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING |
193 | #define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) \ |
194 | { \ |
195 | while (!(binary)) \ |
196 | { \ |
197 | } \ |
198 | (binary) = false; \ |
199 | } |
200 | #define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) \ |
201 | do \ |
202 | { \ |
203 | (binary) = true; \ |
204 | } while(false) |
205 | #else |
206 | #define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) (void)(binary) |
207 | #define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) (void)(binary) |
208 | #endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
209 | /* clang-format on */ |
210 | |
211 | /* add other implementation here |
212 | *such as : |
213 | * #elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DDEBUG_CONSOLE_SYNCHRONIZATION_xxx) |
214 | */ |
215 | |
216 | #else |
217 | |
218 | #error RTOS type is not defined by DEBUG_CONSOLE_SYNCHRONIZATION_MODE. |
219 | |
220 | #endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */ |
221 | |
222 | #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING |
223 | /* receive state structure */ |
224 | typedef struct _debug_console_write_ring_buffer |
225 | { |
226 | uint32_t ringBufferSize; |
227 | volatile uint32_t ringHead; |
228 | volatile uint32_t ringTail; |
229 | uint8_t ringBuffer[DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN]; |
230 | } debug_console_write_ring_buffer_t; |
231 | #endif |
232 | |
233 | typedef struct _debug_console_state_struct |
234 | { |
235 | serial_handle_t serialHandle; /*!< serial manager handle */ |
236 | #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING |
237 | SERIAL_MANAGER_HANDLE_DEFINE(serialHandleBuffer); |
238 | debug_console_write_ring_buffer_t writeRingBuffer; |
239 | uint8_t readRingBuffer[DEBUG_CONSOLE_RECEIVE_BUFFER_LEN]; |
240 | SERIAL_MANAGER_WRITE_HANDLE_DEFINE(serialWriteHandleBuffer); |
241 | SERIAL_MANAGER_WRITE_HANDLE_DEFINE(serialWriteHandleBuffer2); |
242 | SERIAL_MANAGER_READ_HANDLE_DEFINE(serialReadHandleBuffer); |
243 | #else |
244 | SERIAL_MANAGER_BLOCK_HANDLE_DEFINE(serialHandleBuffer); |
245 | SERIAL_MANAGER_WRITE_BLOCK_HANDLE_DEFINE(serialWriteHandleBuffer); |
246 | SERIAL_MANAGER_READ_BLOCK_HANDLE_DEFINE(serialReadHandleBuffer); |
247 | #endif |
248 | } debug_console_state_struct_t; |
249 | |
250 | /******************************************************************************* |
251 | * Variables |
252 | ******************************************************************************/ |
253 | |
254 | /*! @brief Debug console state information. */ |
255 | #if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE > 0)) |
256 | AT_NONCACHEABLE_SECTION(static debug_console_state_struct_t s_debugConsoleState); |
257 | #else |
258 | static debug_console_state_struct_t s_debugConsoleState; |
259 | #endif |
260 | serial_handle_t g_serialHandle; /*!< serial manager handle */ |
261 | |
262 | /******************************************************************************* |
263 | * Prototypes |
264 | ******************************************************************************/ |
265 | /*! |
266 | * @brief This is a printf call back function which is used to relocate the log to buffer |
267 | * or print the log immediately when the local buffer is full. |
268 | * |
269 | * @param[in] buf Buffer to store log. |
270 | * @param[in] indicator Buffer index. |
271 | * @param[in] val Target character to store. |
272 | * @param[in] len length of the character |
273 | * |
274 | */ |
275 | #if SDK_DEBUGCONSOLE |
276 | static void DbgConsole_PrintCallback(char *buf, int32_t *indicator, char dbgVal, int len); |
277 | #endif |
278 | |
279 | status_t DbgConsole_ReadOneCharacter(uint8_t *ch); |
280 | int DbgConsole_SendData(uint8_t *ch, size_t size); |
281 | int DbgConsole_SendDataReliable(uint8_t *ch, size_t size); |
282 | int DbgConsole_ReadLine(uint8_t *buf, size_t size); |
283 | int DbgConsole_ReadCharacter(uint8_t *ch); |
284 | |
285 | #if ((SDK_DEBUGCONSOLE == 0U) && defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \ |
286 | (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))) |
287 | DEBUG_CONSOLE_FUNCTION_PREFIX status_t DbgConsole_Flush(void); |
288 | #endif |
289 | /******************************************************************************* |
290 | * Code |
291 | ******************************************************************************/ |
292 | |
293 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
294 | |
295 | static status_t DbgConsole_SerialManagerPerformTransfer(debug_console_state_struct_t *ioState) |
296 | { |
297 | serial_manager_status_t ret = kStatus_SerialManager_Error; |
298 | uint32_t sendDataLength; |
299 | uint32_t startIndex; |
300 | uint32_t regPrimask; |
301 | |
302 | regPrimask = DisableGlobalIRQ(); |
303 | if (ioState->writeRingBuffer.ringTail != ioState->writeRingBuffer.ringHead) |
304 | { |
305 | if (ioState->writeRingBuffer.ringHead > ioState->writeRingBuffer.ringTail) |
306 | { |
307 | sendDataLength = ioState->writeRingBuffer.ringHead - ioState->writeRingBuffer.ringTail; |
308 | startIndex = ioState->writeRingBuffer.ringTail; |
309 | } |
310 | else |
311 | { |
312 | sendDataLength = ioState->writeRingBuffer.ringBufferSize - ioState->writeRingBuffer.ringTail; |
313 | startIndex = ioState->writeRingBuffer.ringTail; |
314 | if (0U != ioState->writeRingBuffer.ringHead) |
315 | { |
316 | ret = SerialManager_WriteNonBlocking(((serial_write_handle_t)&ioState->serialWriteHandleBuffer2[0]), |
317 | &ioState->writeRingBuffer.ringBuffer[startIndex], sendDataLength); |
318 | sendDataLength = ioState->writeRingBuffer.ringHead - 0U; |
319 | startIndex = 0U; |
320 | } |
321 | } |
322 | ret = SerialManager_WriteNonBlocking(((serial_write_handle_t)&ioState->serialWriteHandleBuffer[0]), |
323 | &ioState->writeRingBuffer.ringBuffer[startIndex], sendDataLength); |
324 | } |
325 | EnableGlobalIRQ(regPrimask); |
326 | return (status_t)ret; |
327 | } |
328 | |
329 | static void DbgConsole_SerialManagerTxCallback(void *callbackParam, |
330 | serial_manager_callback_message_t *message, |
331 | serial_manager_status_t status) |
332 | { |
333 | debug_console_state_struct_t *ioState; |
334 | |
335 | if ((NULL == callbackParam) || (NULL == message)) |
336 | { |
337 | return; |
338 | } |
339 | |
340 | ioState = (debug_console_state_struct_t *)callbackParam; |
341 | |
342 | ioState->writeRingBuffer.ringTail += message->length; |
343 | if (ioState->writeRingBuffer.ringTail >= ioState->writeRingBuffer.ringBufferSize) |
344 | { |
345 | ioState->writeRingBuffer.ringTail = 0U; |
346 | } |
347 | |
348 | if (kStatus_SerialManager_Success == status) |
349 | { |
350 | (void)DbgConsole_SerialManagerPerformTransfer(ioState); |
351 | } |
352 | else if (kStatus_SerialManager_Canceled == status) |
353 | { |
354 | ioState->writeRingBuffer.ringTail = 0U; |
355 | ioState->writeRingBuffer.ringHead = 0U; |
356 | } |
357 | else |
358 | { |
359 | /*MISRA rule 16.4*/ |
360 | } |
361 | } |
362 | |
363 | static void DbgConsole_SerialManagerTx2Callback(void *callbackParam, |
364 | serial_manager_callback_message_t *message, |
365 | serial_manager_status_t status) |
366 | { |
367 | debug_console_state_struct_t *ioState; |
368 | |
369 | if ((NULL == callbackParam) || (NULL == message)) |
370 | { |
371 | return; |
372 | } |
373 | |
374 | ioState = (debug_console_state_struct_t *)callbackParam; |
375 | |
376 | ioState->writeRingBuffer.ringTail += message->length; |
377 | if (ioState->writeRingBuffer.ringTail >= ioState->writeRingBuffer.ringBufferSize) |
378 | { |
379 | ioState->writeRingBuffer.ringTail = 0U; |
380 | } |
381 | |
382 | if (kStatus_SerialManager_Success == status) |
383 | { |
384 | /* Empty block*/ |
385 | } |
386 | else if (kStatus_SerialManager_Canceled == status) |
387 | { |
388 | /* Empty block*/ |
389 | } |
390 | else |
391 | { |
392 | /*MISRA rule 16.4*/ |
393 | } |
394 | } |
395 | |
396 | #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
397 | |
398 | static void DbgConsole_SerialManagerRxCallback(void *callbackParam, |
399 | serial_manager_callback_message_t *message, |
400 | serial_manager_status_t status) |
401 | { |
402 | if ((NULL == callbackParam) || (NULL == message)) |
403 | { |
404 | return; |
405 | } |
406 | |
407 | if (kStatus_SerialManager_Notify == status) |
408 | { |
409 | } |
410 | else if (kStatus_SerialManager_Success == status) |
411 | { |
412 | /* release s_debugConsoleReadWaitSemaphore from RX callback */ |
413 | DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(s_debugConsoleReadWaitSemaphore); |
414 | } |
415 | else |
416 | { |
417 | /*MISRA rule 16.4*/ |
418 | } |
419 | } |
420 | #endif |
421 | |
422 | #endif |
423 | |
424 | status_t DbgConsole_ReadOneCharacter(uint8_t *ch) |
425 | { |
426 | #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
427 | |
428 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \ |
429 | (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED) |
430 | return (status_t)kStatus_Fail; |
431 | #else /*defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == \ |
432 | DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED)*/ |
433 | serial_manager_status_t status = kStatus_SerialManager_Error; |
434 | |
435 | /* recieve one char every time */ |
436 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
437 | status = |
438 | SerialManager_ReadNonBlocking(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), ch, 1); |
439 | #else /*defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)*/ |
440 | status = SerialManager_ReadBlocking(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), ch, 1); |
441 | #endif /*defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)*/ |
442 | if (kStatus_SerialManager_Success != status) |
443 | { |
444 | status = (serial_manager_status_t)kStatus_Fail; |
445 | } |
446 | else |
447 | { |
448 | /* wait s_debugConsoleReadWaitSemaphore from RX callback */ |
449 | DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(s_debugConsoleReadWaitSemaphore); |
450 | status = (serial_manager_status_t)kStatus_Success; |
451 | } |
452 | return (status_t)status; |
453 | #endif /*defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == \ |
454 | DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED)*/ |
455 | |
456 | #else /*(defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))*/ |
457 | |
458 | return (status_t)kStatus_Fail; |
459 | |
460 | #endif /*(defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))*/ |
461 | } |
462 | |
463 | #if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION |
464 | static status_t DbgConsole_EchoCharacter(uint8_t *ch, bool isGetChar, int *index) |
465 | { |
466 | /* Due to scanf take \n and \r as end of string,should not echo */ |
467 | if (((*ch != (uint8_t)'\r') && (*ch != (uint8_t)'\n')) || (isGetChar)) |
468 | { |
469 | /* recieve one char every time */ |
470 | if (1 != DbgConsole_SendDataReliable(ch, 1U)) |
471 | { |
472 | return (status_t)kStatus_Fail; |
473 | } |
474 | } |
475 | |
476 | if ((!isGetChar) && (index != NULL)) |
477 | { |
478 | if (DEBUG_CONSOLE_BACKSPACE == *ch) |
479 | { |
480 | if ((*index >= 2)) |
481 | { |
482 | *index -= 2; |
483 | } |
484 | else |
485 | { |
486 | *index = 0; |
487 | } |
488 | } |
489 | } |
490 | |
491 | return (status_t)kStatus_Success; |
492 | } |
493 | #endif |
494 | |
495 | int DbgConsole_SendData(uint8_t *ch, size_t size) |
496 | { |
497 | status_t status; |
498 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
499 | uint32_t sendDataLength; |
500 | int txBusy = 0; |
501 | #endif |
502 | assert(NULL != ch); |
503 | assert(0U != size); |
504 | |
505 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
506 | uint32_t regPrimask = DisableGlobalIRQ(); |
507 | if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail) |
508 | { |
509 | txBusy = 1; |
510 | sendDataLength = |
511 | (s_debugConsoleState.writeRingBuffer.ringHead + s_debugConsoleState.writeRingBuffer.ringBufferSize - |
512 | s_debugConsoleState.writeRingBuffer.ringTail) % |
513 | s_debugConsoleState.writeRingBuffer.ringBufferSize; |
514 | } |
515 | else |
516 | { |
517 | sendDataLength = 0U; |
518 | } |
519 | sendDataLength = s_debugConsoleState.writeRingBuffer.ringBufferSize - sendDataLength - 1U; |
520 | if (sendDataLength < size) |
521 | { |
522 | EnableGlobalIRQ(regPrimask); |
523 | return -1; |
524 | } |
525 | for (int i = 0; i < (int)size; i++) |
526 | { |
527 | s_debugConsoleState.writeRingBuffer.ringBuffer[s_debugConsoleState.writeRingBuffer.ringHead++] = ch[i]; |
528 | if (s_debugConsoleState.writeRingBuffer.ringHead >= s_debugConsoleState.writeRingBuffer.ringBufferSize) |
529 | { |
530 | s_debugConsoleState.writeRingBuffer.ringHead = 0U; |
531 | } |
532 | } |
533 | |
534 | status = (status_t)kStatus_SerialManager_Success; |
535 | |
536 | if (txBusy == 0) |
537 | { |
538 | status = DbgConsole_SerialManagerPerformTransfer(&s_debugConsoleState); |
539 | } |
540 | EnableGlobalIRQ(regPrimask); |
541 | #else |
542 | status = (status_t)SerialManager_WriteBlocking( |
543 | ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), ch, size); |
544 | #endif |
545 | return (((status_t)kStatus_Success == status) ? (int)size : -1); |
546 | } |
547 | |
548 | int DbgConsole_SendDataReliable(uint8_t *ch, size_t size) |
549 | { |
550 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
551 | #if (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U)) |
552 | serial_manager_status_t status = kStatus_SerialManager_Error; |
553 | uint32_t sendDataLength; |
554 | uint32_t totalLength = size; |
555 | int sentLength; |
556 | #endif /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */ |
557 | #else /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
558 | serial_manager_status_t status; |
559 | #endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
560 | |
561 | assert(NULL != ch); |
562 | |
563 | if (0U == size) |
564 | { |
565 | return 0; |
566 | } |
567 | |
568 | if (NULL == g_serialHandle) |
569 | { |
570 | return 0; |
571 | } |
572 | |
573 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
574 | |
575 | #if (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U)) |
576 | do |
577 | { |
578 | uint32_t regPrimask = DisableGlobalIRQ(); |
579 | if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail) |
580 | { |
581 | sendDataLength = |
582 | (s_debugConsoleState.writeRingBuffer.ringHead + s_debugConsoleState.writeRingBuffer.ringBufferSize - |
583 | s_debugConsoleState.writeRingBuffer.ringTail) % |
584 | s_debugConsoleState.writeRingBuffer.ringBufferSize; |
585 | } |
586 | else |
587 | { |
588 | sendDataLength = 0U; |
589 | } |
590 | sendDataLength = s_debugConsoleState.writeRingBuffer.ringBufferSize - sendDataLength - 1U; |
591 | |
592 | if ((sendDataLength > 0U) && ((sendDataLength >= totalLength) || |
593 | (totalLength >= (s_debugConsoleState.writeRingBuffer.ringBufferSize - 1U)))) |
594 | { |
595 | if (sendDataLength > totalLength) |
596 | { |
597 | sendDataLength = totalLength; |
598 | } |
599 | |
600 | sentLength = DbgConsole_SendData(&ch[size - totalLength], sendDataLength); |
601 | if (sentLength > 0) |
602 | { |
603 | totalLength = totalLength - (uint32_t)sentLength; |
604 | } |
605 | } |
606 | EnableGlobalIRQ(regPrimask); |
607 | |
608 | if (totalLength != 0U) |
609 | { |
610 | status = (serial_manager_status_t)DbgConsole_Flush(); |
611 | if (kStatus_SerialManager_Success != status) |
612 | { |
613 | break; |
614 | } |
615 | } |
616 | } while (totalLength != 0U); |
617 | return ((int)size - (int)totalLength); |
618 | #else /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */ |
619 | return DbgConsole_SendData(ch, size); |
620 | #endif /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */ |
621 | |
622 | #else /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
623 | status = |
624 | SerialManager_WriteBlocking(((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), ch, size); |
625 | return ((kStatus_SerialManager_Success == status) ? (int)size : -1); |
626 | #endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
627 | } |
628 | |
629 | int DbgConsole_ReadLine(uint8_t *buf, size_t size) |
630 | { |
631 | int i = 0; |
632 | |
633 | assert(buf != NULL); |
634 | |
635 | if (NULL == g_serialHandle) |
636 | { |
637 | return -1; |
638 | } |
639 | |
640 | /* take mutex lock function */ |
641 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
642 | DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore); |
643 | #endif |
644 | |
645 | do |
646 | { |
647 | /* recieve one char every time */ |
648 | if ((status_t)kStatus_Success != DbgConsole_ReadOneCharacter(&buf[i])) |
649 | { |
650 | /* release mutex lock function */ |
651 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
652 | DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
653 | #endif |
654 | i = -1; |
655 | break; |
656 | } |
657 | #if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION |
658 | (void)DbgConsole_EchoCharacter(&buf[i], false, &i); |
659 | #endif |
660 | /* analysis data */ |
661 | if (((uint8_t)'\r' == buf[i]) || ((uint8_t)'\n' == buf[i])) |
662 | { |
663 | /* End of Line. */ |
664 | if (0 == i) |
665 | { |
666 | buf[i] = (uint8_t)'\0'; |
667 | continue; |
668 | } |
669 | else |
670 | { |
671 | break; |
672 | } |
673 | } |
674 | i++; |
675 | } while (i < (int)size); |
676 | |
677 | /* get char should not add '\0'*/ |
678 | if (i == (int)size) |
679 | { |
680 | buf[i] = (uint8_t)'\0'; |
681 | } |
682 | else |
683 | { |
684 | buf[i + 1] = (uint8_t)'\0'; |
685 | } |
686 | |
687 | /* release mutex lock function */ |
688 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
689 | DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
690 | #endif |
691 | |
692 | return i; |
693 | } |
694 | |
695 | int DbgConsole_ReadCharacter(uint8_t *ch) |
696 | { |
697 | int ret; |
698 | |
699 | assert(ch); |
700 | |
701 | if (NULL == g_serialHandle) |
702 | { |
703 | return -1; |
704 | } |
705 | |
706 | /* take mutex lock function */ |
707 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
708 | DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore); |
709 | #endif |
710 | /* read one character */ |
711 | if ((status_t)kStatus_Success == DbgConsole_ReadOneCharacter(ch)) |
712 | { |
713 | ret = 1; |
714 | #if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION |
715 | (void)DbgConsole_EchoCharacter(ch, true, NULL); |
716 | #endif |
717 | } |
718 | else |
719 | { |
720 | ret = -1; |
721 | } |
722 | |
723 | /* release mutex lock function */ |
724 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
725 | DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
726 | #endif |
727 | |
728 | return ret; |
729 | } |
730 | |
731 | #if SDK_DEBUGCONSOLE |
732 | static void DbgConsole_PrintCallback(char *buf, int32_t *indicator, char dbgVal, int len) |
733 | { |
734 | int i = 0; |
735 | |
736 | for (i = 0; i < len; i++) |
737 | { |
738 | if (((uint32_t)*indicator + 1UL) >= (uint32_t)DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN) |
739 | { |
740 | (void)DbgConsole_SendDataReliable((uint8_t *)buf, (uint32_t)(*indicator)); |
741 | *indicator = 0; |
742 | } |
743 | |
744 | buf[*indicator] = dbgVal; |
745 | (*indicator)++; |
746 | } |
747 | } |
748 | #endif |
749 | |
750 | /*************Code for DbgConsole Init, Deinit, Printf, Scanf *******************************/ |
751 | #if ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) |
752 | #if (defined(SERIAL_USE_CONFIGURE_STRUCTURE) && (SERIAL_USE_CONFIGURE_STRUCTURE > 0U)) |
753 | #include "board.h" |
754 | #if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U)) |
755 | static const serial_port_uart_config_t uartConfig = {.instance = BOARD_DEBUG_UART_INSTANCE, |
756 | .clockRate = BOARD_DEBUG_UART_CLK_FREQ, |
757 | .baudRate = BOARD_DEBUG_UART_BAUDRATE, |
758 | .parityMode = kSerialManager_UartParityDisabled, |
759 | .stopBitCount = kSerialManager_UartOneStopBit, |
760 | #if !defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
761 | #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U)) |
762 | .mode = kSerialManager_UartBlockMode, |
763 | #endif |
764 | #endif |
765 | .enableRx = 1U, |
766 | .enableTx = 1U, |
767 | .enableRxRTS = 0U, |
768 | .enableTxCTS = 0U, |
769 | #if (defined(HAL_UART_ADAPTER_FIFO) && (HAL_UART_ADAPTER_FIFO > 0u)) |
770 | .txFifoWatermark = 0U, |
771 | .rxFifoWatermark = 0U |
772 | #endif |
773 | }; |
774 | #endif |
775 | #endif |
776 | /* See fsl_debug_console.h for documentation of this function. */ |
777 | status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq) |
778 | { |
779 | serial_manager_config_t serialConfig; |
780 | serial_manager_status_t status = kStatus_SerialManager_Success; |
781 | |
782 | #if (defined(SERIAL_USE_CONFIGURE_STRUCTURE) && (SERIAL_USE_CONFIGURE_STRUCTURE == 0U)) |
783 | #if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U)) |
784 | serial_port_uart_config_t uartConfig = { |
785 | .instance = instance, |
786 | .clockRate = clkSrcFreq, |
787 | .baudRate = baudRate, |
788 | .parityMode = kSerialManager_UartParityDisabled, |
789 | .stopBitCount = kSerialManager_UartOneStopBit, |
790 | #if !defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
791 | #if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U)) |
792 | .mode = kSerialManager_UartBlockMode, |
793 | #endif |
794 | #endif |
795 | .enableRx = 1, |
796 | .enableTx = 1, |
797 | .enableRxRTS = 0U, |
798 | .enableTxCTS = 0U, |
799 | #if (defined(HAL_UART_ADAPTER_FIFO) && (HAL_UART_ADAPTER_FIFO > 0u)) |
800 | .txFifoWatermark = 0U, |
801 | .rxFifoWatermark = 0U |
802 | #endif |
803 | }; |
804 | #endif |
805 | #endif |
806 | |
807 | #if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U)) |
808 | serial_port_usb_cdc_config_t usbCdcConfig = { |
809 | .controllerIndex = (serial_port_usb_cdc_controller_index_t)instance, |
810 | }; |
811 | #endif |
812 | |
813 | #if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U)) |
814 | serial_port_swo_config_t swoConfig = { |
815 | .clockRate = clkSrcFreq, |
816 | .baudRate = baudRate, |
817 | .port = instance, |
818 | .protocol = kSerialManager_SwoProtocolNrz, |
819 | }; |
820 | #endif |
821 | |
822 | #if (defined(SERIAL_PORT_TYPE_VIRTUAL) && (SERIAL_PORT_TYPE_VIRTUAL > 0U)) |
823 | serial_port_virtual_config_t serialPortVirtualConfig = { |
824 | .controllerIndex = (serial_port_virtual_controller_index_t)instance, |
825 | }; |
826 | #endif |
827 | |
828 | serialConfig.type = device; |
829 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
830 | serialConfig.ringBuffer = &s_debugConsoleState.readRingBuffer[0]; |
831 | serialConfig.ringBufferSize = DEBUG_CONSOLE_RECEIVE_BUFFER_LEN; |
832 | serialConfig.blockType = kSerialManager_NonBlocking; |
833 | #else |
834 | serialConfig.blockType = kSerialManager_Blocking; |
835 | #endif |
836 | |
837 | if (kSerialPort_Uart == device) |
838 | { |
839 | #if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U)) |
840 | #if (defined(SERIAL_USE_CONFIGURE_STRUCTURE) && (SERIAL_USE_CONFIGURE_STRUCTURE > 0U)) |
841 | serialConfig.portConfig = (void *)&uartConfig; |
842 | #else |
843 | serialConfig.portConfig = &uartConfig; |
844 | #endif |
845 | #else |
846 | status = kStatus_SerialManager_Error; |
847 | #endif |
848 | } |
849 | else if (kSerialPort_UsbCdc == device) |
850 | { |
851 | #if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U)) |
852 | serialConfig.portConfig = &usbCdcConfig; |
853 | #else |
854 | status = kStatus_SerialManager_Error; |
855 | #endif |
856 | } |
857 | else if (kSerialPort_Swo == device) |
858 | { |
859 | #if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U)) |
860 | serialConfig.portConfig = &swoConfig; |
861 | #else |
862 | status = kStatus_SerialManager_Error; |
863 | #endif |
864 | } |
865 | else if (kSerialPort_Virtual == device) |
866 | { |
867 | #if (defined(SERIAL_PORT_TYPE_VIRTUAL) && (SERIAL_PORT_TYPE_VIRTUAL > 0U)) |
868 | serialConfig.portConfig = &serialPortVirtualConfig; |
869 | #else |
870 | status = kStatus_SerialManager_Error; |
871 | #endif |
872 | } |
873 | else |
874 | { |
875 | status = kStatus_SerialManager_Error; |
876 | } |
877 | |
878 | if (kStatus_SerialManager_Error != status) |
879 | { |
880 | (void)memset(&s_debugConsoleState, 0, sizeof(s_debugConsoleState)); |
881 | |
882 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
883 | s_debugConsoleState.writeRingBuffer.ringBufferSize = DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN; |
884 | #endif |
885 | |
886 | s_debugConsoleState.serialHandle = (serial_handle_t)&s_debugConsoleState.serialHandleBuffer[0]; |
887 | status = SerialManager_Init(s_debugConsoleState.serialHandle, &serialConfig); |
888 | |
889 | assert(kStatus_SerialManager_Success == status); |
890 | |
891 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
892 | #if configSUPPORT_STATIC_ALLOCATION |
893 | DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore, &s_debugConsoleReadSemaphoreStatic); |
894 | #else |
895 | DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
896 | #endif |
897 | #endif |
898 | #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
899 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) && configSUPPORT_STATIC_ALLOCATION |
900 | DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(s_debugConsoleReadWaitSemaphore, &s_debugConsoleReadWaitSemaphoreStatic); |
901 | #else |
902 | DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(s_debugConsoleReadWaitSemaphore); |
903 | #endif |
904 | #endif |
905 | |
906 | { |
907 | status = |
908 | SerialManager_OpenWriteHandle(s_debugConsoleState.serialHandle, |
909 | ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0])); |
910 | assert(kStatus_SerialManager_Success == status); |
911 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
912 | (void)SerialManager_InstallTxCallback( |
913 | ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), |
914 | DbgConsole_SerialManagerTxCallback, &s_debugConsoleState); |
915 | status = SerialManager_OpenWriteHandle( |
916 | s_debugConsoleState.serialHandle, |
917 | ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer2[0])); |
918 | assert(kStatus_SerialManager_Success == status); |
919 | (void)SerialManager_InstallTxCallback( |
920 | ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer2[0]), |
921 | DbgConsole_SerialManagerTx2Callback, &s_debugConsoleState); |
922 | #endif |
923 | } |
924 | |
925 | #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
926 | { |
927 | status = |
928 | SerialManager_OpenReadHandle(s_debugConsoleState.serialHandle, |
929 | ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0])); |
930 | assert(kStatus_SerialManager_Success == status); |
931 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
932 | (void)SerialManager_InstallRxCallback( |
933 | ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), |
934 | DbgConsole_SerialManagerRxCallback, &s_debugConsoleState); |
935 | #endif |
936 | } |
937 | #endif |
938 | |
939 | g_serialHandle = s_debugConsoleState.serialHandle; |
940 | } |
941 | return (status_t)status; |
942 | } |
943 | |
944 | /* See fsl_debug_console.h for documentation of this function. */ |
945 | status_t DbgConsole_EnterLowpower(void) |
946 | { |
947 | serial_manager_status_t status = kStatus_SerialManager_Error; |
948 | if (s_debugConsoleState.serialHandle != NULL) |
949 | { |
950 | status = SerialManager_EnterLowpower(s_debugConsoleState.serialHandle); |
951 | } |
952 | return (status_t)status; |
953 | } |
954 | |
955 | /* See fsl_debug_console.h for documentation of this function. */ |
956 | status_t DbgConsole_ExitLowpower(void) |
957 | { |
958 | serial_manager_status_t status = kStatus_SerialManager_Error; |
959 | |
960 | if (s_debugConsoleState.serialHandle != NULL) |
961 | { |
962 | status = SerialManager_ExitLowpower(s_debugConsoleState.serialHandle); |
963 | } |
964 | return (status_t)status; |
965 | } |
966 | /* See fsl_debug_console.h for documentation of this function. */ |
967 | status_t DbgConsole_Deinit(void) |
968 | { |
969 | { |
970 | if (s_debugConsoleState.serialHandle != NULL) |
971 | { |
972 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
973 | (void)SerialManager_CloseWriteHandle( |
974 | ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer2[0])); |
975 | #endif |
976 | (void)SerialManager_CloseWriteHandle( |
977 | ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0])); |
978 | } |
979 | } |
980 | #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
981 | { |
982 | if (s_debugConsoleState.serialHandle != NULL) |
983 | { |
984 | (void)SerialManager_CloseReadHandle(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0])); |
985 | } |
986 | } |
987 | #endif |
988 | if (NULL != s_debugConsoleState.serialHandle) |
989 | { |
990 | if (kStatus_SerialManager_Success == SerialManager_Deinit(s_debugConsoleState.serialHandle)) |
991 | { |
992 | s_debugConsoleState.serialHandle = NULL; |
993 | g_serialHandle = NULL; |
994 | } |
995 | } |
996 | #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
997 | DEBUG_CONSOLE_DESTROY_BINARY_SEMAPHORE(s_debugConsoleReadWaitSemaphore); |
998 | #endif |
999 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
1000 | DEBUG_CONSOLE_DESTROY_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
1001 | #endif |
1002 | |
1003 | return (status_t)kStatus_Success; |
1004 | } |
1005 | #endif /* ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) */ |
1006 | |
1007 | #if ((SDK_DEBUGCONSOLE > 0U) || \ |
1008 | ((SDK_DEBUGCONSOLE == 0U) && defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \ |
1009 | (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U)))) |
1010 | DEBUG_CONSOLE_FUNCTION_PREFIX status_t DbgConsole_Flush(void) |
1011 | { |
1012 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
1013 | |
1014 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED) |
1015 | |
1016 | if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail) |
1017 | { |
1018 | return (status_t)kStatus_Fail; |
1019 | } |
1020 | |
1021 | #else |
1022 | |
1023 | while (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail) |
1024 | { |
1025 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
1026 | if (0U == IS_RUNNING_IN_ISR()) |
1027 | { |
1028 | if (taskSCHEDULER_RUNNING == xTaskGetSchedulerState()) |
1029 | { |
1030 | vTaskDelay(1); |
1031 | } |
1032 | } |
1033 | else |
1034 | { |
1035 | return (status_t)kStatus_Fail; |
1036 | } |
1037 | #endif |
1038 | } |
1039 | |
1040 | #endif |
1041 | |
1042 | #endif |
1043 | return (status_t)kStatus_Success; |
1044 | } |
1045 | #endif |
1046 | |
1047 | #if SDK_DEBUGCONSOLE |
1048 | /* See fsl_debug_console.h for documentation of this function. */ |
1049 | int DbgConsole_Printf(const char *fmt_s, ...) |
1050 | { |
1051 | va_list ap; |
1052 | int result = 0; |
1053 | |
1054 | va_start(ap, fmt_s); |
1055 | result = DbgConsole_Vprintf(fmt_s, ap); |
1056 | va_end(ap); |
1057 | |
1058 | return result; |
1059 | } |
1060 | |
1061 | /* See fsl_debug_console.h for documentation of this function. */ |
1062 | int DbgConsole_Vprintf(const char *fmt_s, va_list formatStringArg) |
1063 | { |
1064 | int logLength = 0, result = 0; |
1065 | char printBuf[DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN] = {'\0'}; |
1066 | |
1067 | if (NULL != g_serialHandle) |
1068 | { |
1069 | /* format print log first */ |
1070 | logLength = StrFormatPrintf(fmt_s, formatStringArg, printBuf, DbgConsole_PrintCallback); |
1071 | /* print log */ |
1072 | result = DbgConsole_SendDataReliable((uint8_t *)printBuf, (size_t)logLength); |
1073 | } |
1074 | return result; |
1075 | } |
1076 | |
1077 | /* See fsl_debug_console.h for documentation of this function. */ |
1078 | int DbgConsole_Putchar(int ch) |
1079 | { |
1080 | /* print char */ |
1081 | return DbgConsole_SendDataReliable((uint8_t *)&ch, 1U); |
1082 | } |
1083 | |
1084 | /* See fsl_debug_console.h for documentation of this function. */ |
1085 | int DbgConsole_Scanf(char *fmt_s, ...) |
1086 | { |
1087 | va_list ap; |
1088 | int formatResult; |
1089 | char scanfBuf[DEBUG_CONSOLE_SCANF_MAX_LOG_LEN + 1U] = {'\0'}; |
1090 | |
1091 | /* scanf log */ |
1092 | (void)DbgConsole_ReadLine((uint8_t *)scanfBuf, DEBUG_CONSOLE_SCANF_MAX_LOG_LEN); |
1093 | /* get va_list */ |
1094 | va_start(ap, fmt_s); |
1095 | /* format scanf log */ |
1096 | formatResult = StrFormatScanf(scanfBuf, fmt_s, ap); |
1097 | |
1098 | va_end(ap); |
1099 | |
1100 | return formatResult; |
1101 | } |
1102 | |
1103 | /* See fsl_debug_console.h for documentation of this function. */ |
1104 | int DbgConsole_BlockingPrintf(const char *fmt_s, ...) |
1105 | { |
1106 | va_list ap; |
1107 | int result = 0; |
1108 | |
1109 | va_start(ap, fmt_s); |
1110 | result = DbgConsole_BlockingVprintf(fmt_s, ap); |
1111 | va_end(ap); |
1112 | |
1113 | return result; |
1114 | } |
1115 | |
1116 | /* See fsl_debug_console.h for documentation of this function. */ |
1117 | int DbgConsole_BlockingVprintf(const char *fmt_s, va_list formatStringArg) |
1118 | { |
1119 | status_t status; |
1120 | int logLength = 0, result = 0; |
1121 | char printBuf[DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN] = {'\0'}; |
1122 | |
1123 | if (NULL == g_serialHandle) |
1124 | { |
1125 | return 0; |
1126 | } |
1127 | |
1128 | /* format print log first */ |
1129 | logLength = StrFormatPrintf(fmt_s, formatStringArg, printBuf, DbgConsole_PrintCallback); |
1130 | |
1131 | #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
1132 | (void)SerialManager_CancelWriting(((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0])); |
1133 | #endif |
1134 | /* print log */ |
1135 | status = |
1136 | (status_t)SerialManager_WriteBlocking(((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), |
1137 | (uint8_t *)printBuf, (size_t)logLength); |
1138 | result = (((status_t)kStatus_Success == status) ? (int)logLength : -1); |
1139 | |
1140 | return result; |
1141 | } |
1142 | |
1143 | #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING |
1144 | status_t DbgConsole_TryGetchar(char *ch) |
1145 | { |
1146 | #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
1147 | uint32_t length = 0; |
1148 | status_t status = (status_t)kStatus_Fail; |
1149 | |
1150 | assert(ch); |
1151 | |
1152 | if (NULL == g_serialHandle) |
1153 | { |
1154 | return kStatus_Fail; |
1155 | } |
1156 | |
1157 | /* take mutex lock function */ |
1158 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
1159 | DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore); |
1160 | #endif |
1161 | |
1162 | if (kStatus_SerialManager_Success == |
1163 | SerialManager_TryRead(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), (uint8_t *)ch, 1, |
1164 | &length)) |
1165 | { |
1166 | if (length != 0U) |
1167 | { |
1168 | #if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION |
1169 | (void)DbgConsole_EchoCharacter((uint8_t *)ch, true, NULL); |
1170 | #endif |
1171 | status = (status_t)kStatus_Success; |
1172 | } |
1173 | } |
1174 | /* release mutex lock function */ |
1175 | #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
1176 | DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
1177 | #endif |
1178 | return status; |
1179 | #else |
1180 | return (status_t)kStatus_Fail; |
1181 | #endif |
1182 | } |
1183 | #endif |
1184 | |
1185 | /* See fsl_debug_console.h for documentation of this function. */ |
1186 | int DbgConsole_Getchar(void) |
1187 | { |
1188 | int ret = -1; |
1189 | uint8_t ch = 0U; |
1190 | |
1191 | /* Get char */ |
1192 | if (DbgConsole_ReadCharacter(&ch) > 0) |
1193 | { |
1194 | ret = (int)ch; |
1195 | } |
1196 | |
1197 | return ret; |
1198 | } |
1199 | |
1200 | #endif /* SDK_DEBUGCONSOLE */ |
1201 | |
1202 | /*************Code to support toolchain's printf, scanf *******************************/ |
1203 | /* These function __write and __read is used to support IAR toolchain to printf and scanf*/ |
1204 | #if (defined(__ICCARM__)) |
1205 | #if defined(SDK_DEBUGCONSOLE_UART) |
1206 | #pragma weak __write |
1207 | size_t __write(int handle, const unsigned char *buffer, size_t size); |
1208 | size_t __write(int handle, const unsigned char *buffer, size_t size) |
1209 | { |
1210 | size_t ret; |
1211 | if (NULL == buffer) |
1212 | { |
1213 | /* |
1214 | * This means that we should flush internal buffers. Since we don't we just return. |
1215 | * (Remember, "handle" == -1 means that all handles should be flushed.) |
1216 | */ |
1217 | ret = 0U; |
1218 | } |
1219 | else if ((handle != 1) && (handle != 2)) |
1220 | { |
1221 | /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. |
1222 | */ |
1223 | ret = (size_t)-1; |
1224 | } |
1225 | else |
1226 | { |
1227 | /* Send data. */ |
1228 | uint8_t buff[512]; |
1229 | (void)memcpy(buff, buffer, size); |
1230 | (void)DbgConsole_SendDataReliable((uint8_t *)buff, size); |
1231 | |
1232 | ret = size; |
1233 | } |
1234 | return ret; |
1235 | } |
1236 | |
1237 | #pragma weak __read |
1238 | size_t __read(int handle, unsigned char *buffer, size_t size); |
1239 | size_t __read(int handle, unsigned char *buffer, size_t size) |
1240 | { |
1241 | uint8_t ch = 0U; |
1242 | int actualSize = 0; |
1243 | |
1244 | /* This function only reads from "standard in", for all other file handles it returns failure. */ |
1245 | if (0 != handle) |
1246 | { |
1247 | actualSize = -1; |
1248 | } |
1249 | else |
1250 | { |
1251 | /* Receive data.*/ |
1252 | for (; size > 0U; size--) |
1253 | { |
1254 | (void)DbgConsole_ReadCharacter(&ch); |
1255 | if (0U == ch) |
1256 | { |
1257 | break; |
1258 | } |
1259 | |
1260 | *buffer++ = ch; |
1261 | actualSize++; |
1262 | } |
1263 | } |
1264 | return (size_t)actualSize; |
1265 | } |
1266 | #endif /* SDK_DEBUGCONSOLE_UART */ |
1267 | |
1268 | /* support LPC Xpresso with RedLib */ |
1269 | #elif (defined(__REDLIB__)) |
1270 | |
1271 | #if (defined(SDK_DEBUGCONSOLE_UART)) |
1272 | int __attribute__((weak)) __sys_write(int handle, char *buffer, int size) |
1273 | { |
1274 | if (NULL == buffer) |
1275 | { |
1276 | /* return -1 if error. */ |
1277 | return -1; |
1278 | } |
1279 | |
1280 | /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */ |
1281 | if ((handle != 1) && (handle != 2)) |
1282 | { |
1283 | return -1; |
1284 | } |
1285 | |
1286 | /* Send data. */ |
1287 | DbgConsole_SendDataReliable((uint8_t *)buffer, size); |
1288 | |
1289 | return 0; |
1290 | } |
1291 | |
1292 | int __attribute__((weak)) __sys_readc(void) |
1293 | { |
1294 | char tmp; |
1295 | |
1296 | /* Receive data. */ |
1297 | DbgConsole_ReadCharacter((uint8_t *)&tmp); |
1298 | |
1299 | return tmp; |
1300 | } |
1301 | #endif /* SDK_DEBUGCONSOLE_UART */ |
1302 | |
1303 | /* These function fputc and fgetc is used to support KEIL toolchain to printf and scanf*/ |
1304 | #elif defined(__CC_ARM) || defined(__ARMCC_VERSION) |
1305 | #if defined(SDK_DEBUGCONSOLE_UART) |
1306 | #if defined(__CC_ARM) |
1307 | struct __FILE |
1308 | { |
1309 | int handle; |
1310 | /* |
1311 | * Whatever you require here. If the only file you are using is standard output using printf() for debugging, |
1312 | * no file handling is required. |
1313 | */ |
1314 | }; |
1315 | #endif |
1316 | |
1317 | /* FILE is typedef in stdio.h. */ |
1318 | #pragma weak __stdout |
1319 | #pragma weak __stdin |
1320 | FILE __stdout; |
1321 | FILE __stdin; |
1322 | |
1323 | #pragma weak fputc |
1324 | int fputc(int ch, FILE *f) |
1325 | { |
1326 | /* Send data. */ |
1327 | return DbgConsole_SendDataReliable((uint8_t *)(&ch), 1); |
1328 | } |
1329 | |
1330 | #pragma weak fgetc |
1331 | int fgetc(FILE *f) |
1332 | { |
1333 | char ch; |
1334 | |
1335 | /* Receive data. */ |
1336 | DbgConsole_ReadCharacter((uint8_t *)&ch); |
1337 | |
1338 | return ch; |
1339 | } |
1340 | |
1341 | /* |
1342 | * Terminate the program, passing a return code back to the user. |
1343 | * This function may not return. |
1344 | */ |
1345 | void _sys_exit(int returncode) |
1346 | { |
1347 | while (1) |
1348 | { |
1349 | } |
1350 | } |
1351 | |
1352 | /* |
1353 | * Writes a character to the output channel. This function is used |
1354 | * for last-resort error message output. |
1355 | */ |
1356 | void _ttywrch(int ch) |
1357 | { |
1358 | char ench = ch; |
1359 | DbgConsole_SendDataReliable((uint8_t *)(&ench), 1); |
1360 | } |
1361 | |
1362 | char *_sys_command_string(char *cmd, int len) |
1363 | { |
1364 | return (cmd); |
1365 | } |
1366 | #endif /* SDK_DEBUGCONSOLE_UART */ |
1367 | |
1368 | /* These function __write and __read is used to support ARM_GCC, KDS, Atollic toolchains to printf and scanf*/ |
1369 | #elif (defined(__GNUC__)) |
1370 | |
1371 | #if ((defined(__GNUC__) && (!defined(__MCUXPRESSO)) && (defined(SDK_DEBUGCONSOLE_UART))) || \ |
1372 | (defined(__MCUXPRESSO) && (defined(SDK_DEBUGCONSOLE_UART)))) |
1373 | int __attribute__((weak)) _write(int handle, char *buffer, int size); |
1374 | int __attribute__((weak)) _write(int handle, char *buffer, int size) |
1375 | { |
1376 | if (NULL == buffer) |
1377 | { |
1378 | /* return -1 if error. */ |
1379 | return -1; |
1380 | } |
1381 | |
1382 | /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */ |
1383 | if ((handle != 1) && (handle != 2)) |
1384 | { |
1385 | return -1; |
1386 | } |
1387 | |
1388 | /* Send data. */ |
1389 | (void)DbgConsole_SendDataReliable((uint8_t *)buffer, (size_t)size); |
1390 | |
1391 | return size; |
1392 | } |
1393 | |
1394 | int __attribute__((weak)) _read(int handle, char *buffer, int size); |
1395 | int __attribute__((weak)) _read(int handle, char *buffer, int size) |
1396 | { |
1397 | uint8_t ch = 0U; |
1398 | int actualSize = 0; |
1399 | |
1400 | /* This function only reads from "standard in", for all other file handles it returns failure. */ |
1401 | if (handle != 0) |
1402 | { |
1403 | return -1; |
1404 | } |
1405 | |
1406 | /* Receive data. */ |
1407 | for (; size > 0; size--) |
1408 | { |
1409 | if (DbgConsole_ReadCharacter(&ch) < 0) |
1410 | { |
1411 | break; |
1412 | } |
1413 | |
1414 | *buffer++ = (char)ch; |
1415 | actualSize++; |
1416 | |
1417 | if ((ch == 0U) || (ch == (uint8_t)'\n') || (ch == (uint8_t)'\r')) |
1418 | { |
1419 | break; |
1420 | } |
1421 | } |
1422 | |
1423 | return (actualSize > 0) ? actualSize : -1; |
1424 | } |
1425 | #endif |
1426 | |
1427 | #endif /* __ICCARM__ */ |
1428 | |