| /* |
| * This is a modified version of the file printf.c, which was distributed |
| * by Motorola as part of the M5407C3BOOT.zip package used to initialize |
| * the M5407C3 evaluation board. |
| * |
| * Copyright: |
| * 1999-2000 MOTOROLA, INC. All Rights Reserved. |
| * You are hereby granted a copyright license to use, modify, and |
| * distribute the SOFTWARE so long as this entire notice is |
| * retained without alteration in any modified and/or redistributed |
| * versions, and that such modified versions are clearly identified |
| * as such. No licenses are granted by implication, estoppel or |
| * otherwise under any patents or trademarks of Motorola, Inc. This |
| * software is provided on an "AS IS" basis and without warranty. |
| * |
| * To the maximum extent permitted by applicable law, MOTOROLA |
| * DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING |
| * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR |
| * PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE |
| * SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY |
| * ACCOMPANYING WRITTEN MATERIALS. |
| * |
| * To the maximum extent permitted by applicable law, IN NO EVENT |
| * SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING |
| * WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS |
| * INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY |
| * LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. |
| * |
| * Motorola assumes no responsibility for the maintenance and support |
| * of this software |
| |
| * Copyright (c) 2015, Freescale Semiconductor, Inc. |
| * Copyright 2016-2019 NXP |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| #include <stdarg.h> |
| #include <stdlib.h> |
| #if defined(__CC_ARM) || defined(__ARMCC_VERSION) |
| #include <stdio.h> |
| #endif |
| |
| #ifdef FSL_RTOS_FREE_RTOS |
| #include "FreeRTOS.h" |
| #include "semphr.h" |
| #include "task.h" |
| #endif |
| |
| #include "fsl_debug_console_conf.h" |
| #include "fsl_str.h" |
| |
| #include "fsl_common.h" |
| #include "serial_manager.h" |
| |
| #include "fsl_debug_console.h" |
| |
| /******************************************************************************* |
| * Definitions |
| ******************************************************************************/ |
| #ifndef NDEBUG |
| #if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U)) |
| #undef assert |
| #define assert(n) |
| #endif |
| #endif |
| |
| #if SDK_DEBUGCONSOLE |
| #define DEBUG_CONSOLE_FUNCTION_PREFIX |
| #else |
| #define DEBUG_CONSOLE_FUNCTION_PREFIX static |
| #endif |
| |
| /*! @brief character backspace ASCII value */ |
| #define DEBUG_CONSOLE_BACKSPACE 127U |
| |
| /* lock definition */ |
| #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
| |
| static SemaphoreHandle_t s_debugConsoleReadSemaphore; |
| #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
| static SemaphoreHandle_t s_debugConsoleReadWaitSemaphore; |
| #endif |
| |
| #elif (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) |
| |
| #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
| static volatile uint8_t s_debugConsoleReadWaitSemaphore; |
| #endif |
| |
| #else |
| |
| #endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */ |
| |
| /*! @brief get current runing environment is ISR or not */ |
| #ifdef __CA7_REV |
| #define IS_RUNNING_IN_ISR() SystemGetIRQNestingLevel() |
| #else |
| #define IS_RUNNING_IN_ISR() __get_IPSR() |
| #endif /* __CA7_REV */ |
| |
| /* semaphore definition */ |
| #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
| |
| /* mutex semaphore */ |
| /* clang-format off */ |
| #define DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(mutex) ((mutex) = xSemaphoreCreateMutex()) |
| #define DEBUG_CONSOLE_DESTROY_MUTEX_SEMAPHORE(mutex) \ |
| do \ |
| { \ |
| if(NULL != mutex) \ |
| { \ |
| vSemaphoreDelete(mutex); \ |
| mutex = NULL; \ |
| } \ |
| } while(0) |
| |
| #define DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(mutex) \ |
| { \ |
| if (IS_RUNNING_IN_ISR() == 0U) \ |
| { \ |
| (void)xSemaphoreGive(mutex); \ |
| } \ |
| } |
| |
| #define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) \ |
| { \ |
| if (IS_RUNNING_IN_ISR() == 0U) \ |
| { \ |
| (void)xSemaphoreTake(mutex, portMAX_DELAY); \ |
| } \ |
| } |
| |
| #define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) \ |
| { \ |
| if (IS_RUNNING_IN_ISR() == 0U) \ |
| { \ |
| result = xSemaphoreTake(mutex, 0U); \ |
| } \ |
| else \ |
| { \ |
| result = 1U; \ |
| } \ |
| } |
| |
| /* Binary semaphore */ |
| #define DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(binary) ((binary) = xSemaphoreCreateBinary()) |
| #define DEBUG_CONSOLE_DESTROY_BINARY_SEMAPHORE(binary) \ |
| do \ |
| { \ |
| if(NULL != binary) \ |
| { \ |
| vSemaphoreDelete(binary); \ |
| binary = NULL; \ |
| } \ |
| } while(0) |
| #define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) ((void)xSemaphoreTake(binary, portMAX_DELAY)) |
| #define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) ((void)xSemaphoreGiveFromISR(binary, NULL)) |
| |
| #elif (DEBUG_CONSOLE_SYNCHRONIZATION_BM == DEBUG_CONSOLE_SYNCHRONIZATION_MODE) |
| |
| #define DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(mutex) |
| #define DEBUG_CONSOLE_DESTROY_MUTEX_SEMAPHORE(mutex) |
| #define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) |
| #define DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(mutex) |
| #define DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) (result = 1U) |
| |
| #define DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(binary) |
| #define DEBUG_CONSOLE_DESTROY_BINARY_SEMAPHORE(binary) |
| #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING |
| #define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) \ |
| { \ |
| while (!binary) \ |
| { \ |
| } \ |
| binary = false; \ |
| } |
| #define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) (binary = true) |
| #else |
| #define DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) |
| #define DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) |
| #endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
| /* clang-format on */ |
| |
| /* add other implementation here |
| *such as : |
| * #elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DDEBUG_CONSOLE_SYNCHRONIZATION_xxx) |
| */ |
| |
| #else |
| |
| #error RTOS type is not defined by DEBUG_CONSOLE_SYNCHRONIZATION_MODE. |
| |
| #endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */ |
| |
| #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING |
| /* receive state structure */ |
| typedef struct _debug_console_write_ring_buffer |
| { |
| uint32_t ringBufferSize; |
| volatile uint32_t ringHead; |
| volatile uint32_t ringTail; |
| uint8_t ringBuffer[DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN]; |
| } debug_console_write_ring_buffer_t; |
| #endif |
| |
| typedef struct _debug_console_state_struct |
| { |
| SERIAL_MANAGER_HANDLE_DEFINE(serialHandleBuffer); |
| serial_handle_t serialHandle; /*!< serial manager handle */ |
| #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING |
| debug_console_write_ring_buffer_t writeRingBuffer; |
| uint8_t readRingBuffer[DEBUG_CONSOLE_RECEIVE_BUFFER_LEN]; |
| #endif |
| SERIAL_MANAGER_WRITE_HANDLE_DEFINE(serialWriteHandleBuffer); |
| SERIAL_MANAGER_READ_HANDLE_DEFINE(serialReadHandleBuffer); |
| } debug_console_state_struct_t; |
| |
| /******************************************************************************* |
| * Variables |
| ******************************************************************************/ |
| |
| /*! @brief Debug console state information. */ |
| #if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE > 0)) |
| AT_NONCACHEABLE_SECTION(static debug_console_state_struct_t s_debugConsoleState); |
| #else |
| static debug_console_state_struct_t s_debugConsoleState; |
| #endif |
| serial_handle_t g_serialHandle; /*!< serial manager handle */ |
| |
| /******************************************************************************* |
| * Prototypes |
| ******************************************************************************/ |
| /*! |
| * @brief This is a printf call back function which is used to relocate the log to buffer |
| * or print the log immediately when the local buffer is full. |
| * |
| * @param[in] buf Buffer to store log. |
| * @param[in] indicator Buffer index. |
| * @param[in] val Target character to store. |
| * @param[in] len length of the character |
| * |
| */ |
| #if SDK_DEBUGCONSOLE |
| static void DbgConsole_PrintCallback(char *buf, int32_t *indicator, char dbgVal, int len); |
| #endif |
| |
| status_t DbgConsole_ReadOneCharacter(uint8_t *ch); |
| int DbgConsole_SendData(uint8_t *ch, size_t size); |
| int DbgConsole_SendDataReliable(uint8_t *ch, size_t size); |
| int DbgConsole_ReadLine(uint8_t *buf, size_t size); |
| int DbgConsole_ReadCharacter(uint8_t *ch); |
| |
| #if ((SDK_DEBUGCONSOLE == 0U) && defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \ |
| (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U))) |
| DEBUG_CONSOLE_FUNCTION_PREFIX status_t DbgConsole_Flush(void); |
| #endif |
| /******************************************************************************* |
| * Code |
| ******************************************************************************/ |
| |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| |
| static void DbgConsole_SerialManagerTxCallback(void *callbackParam, |
| serial_manager_callback_message_t *message, |
| serial_manager_status_t status) |
| { |
| debug_console_state_struct_t *ioState; |
| uint32_t sendDataLength; |
| |
| if ((NULL == callbackParam) || (NULL == message)) |
| { |
| return; |
| } |
| |
| ioState = (debug_console_state_struct_t *)callbackParam; |
| |
| ioState->writeRingBuffer.ringTail += message->length; |
| if (ioState->writeRingBuffer.ringTail >= ioState->writeRingBuffer.ringBufferSize) |
| { |
| ioState->writeRingBuffer.ringTail = 0U; |
| } |
| |
| if (kStatus_SerialManager_Success == status) |
| { |
| if (ioState->writeRingBuffer.ringTail != ioState->writeRingBuffer.ringHead) |
| { |
| if (ioState->writeRingBuffer.ringHead > ioState->writeRingBuffer.ringTail) |
| { |
| sendDataLength = ioState->writeRingBuffer.ringHead - ioState->writeRingBuffer.ringTail; |
| } |
| else |
| { |
| sendDataLength = ioState->writeRingBuffer.ringBufferSize - ioState->writeRingBuffer.ringTail; |
| } |
| |
| (void)SerialManager_WriteNonBlocking( |
| ((serial_write_handle_t)&ioState->serialWriteHandleBuffer[0]), |
| &ioState->writeRingBuffer.ringBuffer[ioState->writeRingBuffer.ringTail], sendDataLength); |
| } |
| } |
| else if (kStatus_SerialManager_Canceled == status) |
| { |
| ioState->writeRingBuffer.ringTail = 0U; |
| ioState->writeRingBuffer.ringHead = 0U; |
| } |
| else |
| { |
| /*MISRA rule 16.4*/ |
| } |
| } |
| |
| #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
| |
| static void DbgConsole_SerialManagerRxCallback(void *callbackParam, |
| serial_manager_callback_message_t *message, |
| serial_manager_status_t status) |
| { |
| if ((NULL == callbackParam) || (NULL == message)) |
| { |
| return; |
| } |
| |
| if (kStatus_SerialManager_Notify == status) |
| { |
| } |
| else if (kStatus_SerialManager_Success == status) |
| { |
| /* release s_debugConsoleReadWaitSemaphore from RX callback */ |
| DEBUG_CONSOLE_GIVE_BINARY_SEMAPHORE_FROM_ISR(s_debugConsoleReadWaitSemaphore); |
| } |
| else |
| { |
| /*MISRA rule 16.4*/ |
| } |
| } |
| #endif |
| |
| #endif |
| |
| status_t DbgConsole_ReadOneCharacter(uint8_t *ch) |
| { |
| #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
| |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \ |
| (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED) |
| return (status_t)kStatus_Fail; |
| #else /*defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == \ |
| DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED)*/ |
| serial_manager_status_t status = kStatus_SerialManager_Error; |
| |
| /* recieve one char every time */ |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| status = |
| SerialManager_ReadNonBlocking(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), ch, 1); |
| #else /*defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)*/ |
| status = SerialManager_ReadBlocking(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), ch, 1); |
| #endif /*defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING)*/ |
| if (kStatus_SerialManager_Success != status) |
| { |
| status = (serial_manager_status_t)kStatus_Fail; |
| } |
| else |
| { |
| /* wait s_debugConsoleReadWaitSemaphore from RX callback */ |
| DEBUG_CONSOLE_TAKE_BINARY_SEMAPHORE_BLOCKING(s_debugConsoleReadWaitSemaphore); |
| status = (serial_manager_status_t)kStatus_Success; |
| } |
| return (status_t)status; |
| #endif /*defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == \ |
| DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED)*/ |
| |
| #else /*(defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))*/ |
| |
| return (status_t)kStatus_Fail; |
| |
| #endif /*(defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U))*/ |
| } |
| |
| #if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION |
| static status_t DbgConsole_EchoCharacter(uint8_t *ch, bool isGetChar, int *index) |
| { |
| /* Due to scanf take \n and \r as end of string,should not echo */ |
| if (((*ch != (uint8_t)'\r') && (*ch != (uint8_t)'\n')) || (isGetChar)) |
| { |
| /* recieve one char every time */ |
| if (1 != DbgConsole_SendDataReliable(ch, 1U)) |
| { |
| return (status_t)kStatus_Fail; |
| } |
| } |
| |
| if ((!isGetChar) && (index != NULL)) |
| { |
| if (DEBUG_CONSOLE_BACKSPACE == *ch) |
| { |
| if ((*index >= 2)) |
| { |
| *index -= 2; |
| } |
| else |
| { |
| *index = 0; |
| } |
| } |
| } |
| |
| return (status_t)kStatus_Success; |
| } |
| #endif |
| |
| int DbgConsole_SendData(uint8_t *ch, size_t size) |
| { |
| status_t status; |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| uint32_t sendDataLength; |
| int txBusy = 0; |
| #endif |
| assert(NULL != ch); |
| assert(0U != size); |
| |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| uint32_t regPrimask = DisableGlobalIRQ(); |
| if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail) |
| { |
| txBusy = 1; |
| sendDataLength = |
| (s_debugConsoleState.writeRingBuffer.ringHead + s_debugConsoleState.writeRingBuffer.ringBufferSize - |
| s_debugConsoleState.writeRingBuffer.ringTail) % |
| s_debugConsoleState.writeRingBuffer.ringBufferSize; |
| } |
| else |
| { |
| sendDataLength = 0U; |
| } |
| sendDataLength = s_debugConsoleState.writeRingBuffer.ringBufferSize - sendDataLength - 1; |
| if (sendDataLength < size) |
| { |
| EnableGlobalIRQ(regPrimask); |
| return -1; |
| } |
| for (int i = 0; i < (int)size; i++) |
| { |
| s_debugConsoleState.writeRingBuffer.ringBuffer[s_debugConsoleState.writeRingBuffer.ringHead++] = ch[i]; |
| if (s_debugConsoleState.writeRingBuffer.ringHead >= s_debugConsoleState.writeRingBuffer.ringBufferSize) |
| { |
| s_debugConsoleState.writeRingBuffer.ringHead = 0U; |
| } |
| } |
| |
| status = (status_t)kStatus_SerialManager_Success; |
| |
| if (txBusy == 0) |
| { |
| if (s_debugConsoleState.writeRingBuffer.ringHead > s_debugConsoleState.writeRingBuffer.ringTail) |
| { |
| sendDataLength = |
| s_debugConsoleState.writeRingBuffer.ringHead - s_debugConsoleState.writeRingBuffer.ringTail; |
| } |
| else |
| { |
| sendDataLength = |
| s_debugConsoleState.writeRingBuffer.ringBufferSize - s_debugConsoleState.writeRingBuffer.ringTail; |
| } |
| |
| status = (status_t)SerialManager_WriteNonBlocking( |
| ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), |
| &s_debugConsoleState.writeRingBuffer.ringBuffer[s_debugConsoleState.writeRingBuffer.ringTail], |
| sendDataLength); |
| } |
| EnableGlobalIRQ(regPrimask); |
| #else |
| status = (status_t)SerialManager_WriteBlocking( |
| ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), ch, size); |
| #endif |
| return (((status_t)kStatus_Success == status) ? (int)size : -1); |
| } |
| |
| int DbgConsole_SendDataReliable(uint8_t *ch, size_t size) |
| { |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| #if (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U)) |
| serial_manager_status_t status = kStatus_SerialManager_Error; |
| uint32_t sendDataLength; |
| uint32_t totalLength = size; |
| int sentLength; |
| #endif /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */ |
| #else /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
| serial_manager_status_t status; |
| #endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
| |
| assert(NULL != ch); |
| assert(0U != size); |
| |
| if (NULL == g_serialHandle) |
| { |
| return 0; |
| } |
| |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| |
| #if (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U)) |
| do |
| { |
| uint32_t regPrimask = DisableGlobalIRQ(); |
| if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail) |
| { |
| sendDataLength = |
| (s_debugConsoleState.writeRingBuffer.ringHead + s_debugConsoleState.writeRingBuffer.ringBufferSize - |
| s_debugConsoleState.writeRingBuffer.ringTail) % |
| s_debugConsoleState.writeRingBuffer.ringBufferSize; |
| } |
| else |
| { |
| sendDataLength = 0U; |
| } |
| sendDataLength = s_debugConsoleState.writeRingBuffer.ringBufferSize - sendDataLength - 1U; |
| |
| if (sendDataLength > 0U) |
| { |
| if (sendDataLength > totalLength) |
| { |
| sendDataLength = totalLength; |
| } |
| |
| sentLength = DbgConsole_SendData(&ch[size - totalLength], sendDataLength); |
| if (sentLength > 0) |
| { |
| totalLength = totalLength - (uint32_t)sentLength; |
| } |
| } |
| EnableGlobalIRQ(regPrimask); |
| |
| if (totalLength != 0U) |
| { |
| status = (serial_manager_status_t)DbgConsole_Flush(); |
| if (kStatus_SerialManager_Success != status) |
| { |
| break; |
| } |
| } |
| } while (totalLength != 0U); |
| return ((int)size - (int)totalLength); |
| #else /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */ |
| return DbgConsole_SendData(ch, size); |
| #endif /* DEBUG_CONSOLE_TX_RELIABLE_ENABLE */ |
| |
| #else /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
| status = |
| SerialManager_WriteBlocking(((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), ch, size); |
| return ((kStatus_SerialManager_Success == status) ? (int)size : -1); |
| #endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ |
| } |
| |
| int DbgConsole_ReadLine(uint8_t *buf, size_t size) |
| { |
| int i = 0; |
| |
| assert(buf != NULL); |
| |
| if (NULL == g_serialHandle) |
| { |
| return -1; |
| } |
| |
| /* take mutex lock function */ |
| DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore); |
| |
| do |
| { |
| /* recieve one char every time */ |
| if ((status_t)kStatus_Success != DbgConsole_ReadOneCharacter(&buf[i])) |
| { |
| /* release mutex lock function */ |
| DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
| i = -1; |
| break; |
| } |
| #if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION |
| (void)DbgConsole_EchoCharacter(&buf[i], false, &i); |
| #endif |
| /* analysis data */ |
| if (((uint8_t)'\r' == buf[i]) || ((uint8_t)'\n' == buf[i])) |
| { |
| /* End of Line. */ |
| if (0 == i) |
| { |
| buf[i] = (uint8_t)'\0'; |
| continue; |
| } |
| else |
| { |
| break; |
| } |
| } |
| i++; |
| } while (i < (int)size); |
| |
| /* get char should not add '\0'*/ |
| if (i == (int)size) |
| { |
| buf[i] = (uint8_t)'\0'; |
| } |
| else |
| { |
| buf[i + 1] = (uint8_t)'\0'; |
| } |
| |
| /* release mutex lock function */ |
| DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
| |
| return i; |
| } |
| |
| int DbgConsole_ReadCharacter(uint8_t *ch) |
| { |
| int ret; |
| |
| assert(ch); |
| |
| if (NULL == g_serialHandle) |
| { |
| return -1; |
| } |
| |
| /* take mutex lock function */ |
| DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore); |
| /* read one character */ |
| if ((status_t)kStatus_Success == DbgConsole_ReadOneCharacter(ch)) |
| { |
| ret = 1; |
| #if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION |
| (void)DbgConsole_EchoCharacter(ch, true, NULL); |
| #endif |
| } |
| else |
| { |
| ret = -1; |
| } |
| |
| /* release mutex lock function */ |
| DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
| |
| return ret; |
| } |
| |
| #if SDK_DEBUGCONSOLE |
| static void DbgConsole_PrintCallback(char *buf, int32_t *indicator, char dbgVal, int len) |
| { |
| int i = 0; |
| |
| for (i = 0; i < len; i++) |
| { |
| if (((uint32_t)*indicator + 1UL) >= DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN) |
| { |
| (void)DbgConsole_SendDataReliable((uint8_t *)buf, (uint32_t)(*indicator)); |
| *indicator = 0; |
| } |
| |
| buf[*indicator] = dbgVal; |
| (*indicator)++; |
| } |
| } |
| #endif |
| |
| /*************Code for DbgConsole Init, Deinit, Printf, Scanf *******************************/ |
| |
| #if ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) |
| /* See fsl_debug_console.h for documentation of this function. */ |
| status_t DbgConsole_Init(uint8_t instance, uint32_t baudRate, serial_port_type_t device, uint32_t clkSrcFreq) |
| { |
| serial_manager_config_t serialConfig; |
| serial_manager_status_t status = kStatus_SerialManager_Success; |
| |
| #if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U)) |
| serial_port_uart_config_t uartConfig = { |
| .instance = instance, |
| .clockRate = clkSrcFreq, |
| .baudRate = baudRate, |
| .parityMode = kSerialManager_UartParityDisabled, |
| .stopBitCount = kSerialManager_UartOneStopBit, |
| .enableRx = 1, |
| .enableTx = 1, |
| }; |
| #endif |
| |
| #if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U)) |
| serial_port_usb_cdc_config_t usbCdcConfig = { |
| .controllerIndex = (serial_port_usb_cdc_controller_index_t)instance, |
| }; |
| #endif |
| |
| #if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U)) |
| serial_port_swo_config_t swoConfig = { |
| .clockRate = clkSrcFreq, |
| .baudRate = baudRate, |
| .port = instance, |
| .protocol = kSerialManager_SwoProtocolNrz, |
| }; |
| #endif |
| |
| #if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U)) |
| serial_port_usb_cdc_virtual_config_t usbCdcVirtualConfig = { |
| .controllerIndex = (serial_port_usb_cdc_virtual_controller_index_t)instance, |
| }; |
| #endif |
| |
| serialConfig.type = device; |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| serialConfig.ringBuffer = &s_debugConsoleState.readRingBuffer[0]; |
| serialConfig.ringBufferSize = DEBUG_CONSOLE_RECEIVE_BUFFER_LEN; |
| #endif |
| |
| if (kSerialPort_Uart == device) |
| { |
| #if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U)) |
| serialConfig.portConfig = &uartConfig; |
| #else |
| status = kStatus_SerialManager_Error; |
| #endif |
| } |
| else if (kSerialPort_UsbCdc == device) |
| { |
| #if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U)) |
| serialConfig.portConfig = &usbCdcConfig; |
| #else |
| status = kStatus_SerialManager_Error; |
| #endif |
| } |
| else if (kSerialPort_Swo == device) |
| { |
| #if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U)) |
| serialConfig.portConfig = &swoConfig; |
| #else |
| status = kStatus_SerialManager_Error; |
| #endif |
| } |
| else if (kSerialPort_UsbCdcVirtual == device) |
| { |
| #if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U)) |
| serialConfig.portConfig = &usbCdcVirtualConfig; |
| #else |
| status = kStatus_SerialManager_Error; |
| #endif |
| } |
| else |
| { |
| status = kStatus_SerialManager_Error; |
| } |
| |
| if (kStatus_SerialManager_Error != status) |
| { |
| (void)memset(&s_debugConsoleState, 0, sizeof(s_debugConsoleState)); |
| |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| s_debugConsoleState.writeRingBuffer.ringBufferSize = DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN; |
| #endif |
| |
| s_debugConsoleState.serialHandle = (serial_handle_t)&s_debugConsoleState.serialHandleBuffer[0]; |
| status = SerialManager_Init(s_debugConsoleState.serialHandle, &serialConfig); |
| |
| assert(kStatus_SerialManager_Success == status); |
| |
| DEBUG_CONSOLE_CREATE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
| #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
| DEBUG_CONSOLE_CREATE_BINARY_SEMAPHORE(s_debugConsoleReadWaitSemaphore); |
| #endif |
| |
| { |
| status = |
| SerialManager_OpenWriteHandle(s_debugConsoleState.serialHandle, |
| ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0])); |
| assert(kStatus_SerialManager_Success == status); |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| (void)SerialManager_InstallTxCallback( |
| ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), |
| DbgConsole_SerialManagerTxCallback, &s_debugConsoleState); |
| #endif |
| } |
| |
| #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
| { |
| status = |
| SerialManager_OpenReadHandle(s_debugConsoleState.serialHandle, |
| ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0])); |
| assert(kStatus_SerialManager_Success == status); |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| (void)SerialManager_InstallRxCallback( |
| ((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), |
| DbgConsole_SerialManagerRxCallback, &s_debugConsoleState); |
| #endif |
| } |
| #endif |
| |
| g_serialHandle = s_debugConsoleState.serialHandle; |
| } |
| return (status_t)status; |
| } |
| |
| /* See fsl_debug_console.h for documentation of this function. */ |
| status_t DbgConsole_Deinit(void) |
| { |
| { |
| if (s_debugConsoleState.serialHandle != NULL) |
| { |
| (void)SerialManager_CloseWriteHandle( |
| ((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0])); |
| } |
| } |
| #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
| { |
| if (s_debugConsoleState.serialHandle != NULL) |
| { |
| (void)SerialManager_CloseReadHandle(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0])); |
| } |
| } |
| #endif |
| if (NULL != s_debugConsoleState.serialHandle) |
| { |
| if (kStatus_SerialManager_Success == SerialManager_Deinit(s_debugConsoleState.serialHandle)) |
| { |
| s_debugConsoleState.serialHandle = NULL; |
| g_serialHandle = NULL; |
| } |
| } |
| #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
| DEBUG_CONSOLE_DESTROY_BINARY_SEMAPHORE(s_debugConsoleReadWaitSemaphore); |
| #endif |
| DEBUG_CONSOLE_DESTROY_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
| |
| return (status_t)kStatus_Success; |
| } |
| #endif /* ((SDK_DEBUGCONSOLE == DEBUGCONSOLE_REDIRECT_TO_SDK) || defined(SDK_DEBUGCONSOLE_UART)) */ |
| |
| #if ((SDK_DEBUGCONSOLE > 0U) || \ |
| ((SDK_DEBUGCONSOLE == 0U) && defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) && \ |
| (defined(DEBUG_CONSOLE_TX_RELIABLE_ENABLE) && (DEBUG_CONSOLE_TX_RELIABLE_ENABLE > 0U)))) |
| DEBUG_CONSOLE_FUNCTION_PREFIX status_t DbgConsole_Flush(void) |
| { |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| |
| #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) && defined(OSA_USED) |
| |
| if (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail) |
| { |
| return (status_t)kStatus_Fail; |
| } |
| |
| #else |
| |
| while (s_debugConsoleState.writeRingBuffer.ringHead != s_debugConsoleState.writeRingBuffer.ringTail) |
| { |
| #if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) |
| if (0U == IS_RUNNING_IN_ISR()) |
| { |
| if (taskSCHEDULER_RUNNING == xTaskGetSchedulerState()) |
| { |
| vTaskDelay(1); |
| } |
| } |
| else |
| { |
| return (status_t)kStatus_Fail; |
| } |
| #endif |
| } |
| |
| #endif |
| |
| #endif |
| return (status_t)kStatus_Success; |
| } |
| #endif |
| |
| #if SDK_DEBUGCONSOLE |
| /* See fsl_debug_console.h for documentation of this function. */ |
| int DbgConsole_Printf(const char *formatString, ...) |
| { |
| va_list ap; |
| int logLength = 0, dbgResult = 0; |
| char printBuf[DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN] = {'\0'}; |
| |
| if (NULL != g_serialHandle) |
| { |
| va_start(ap, formatString); |
| /* format print log first */ |
| logLength = StrFormatPrintf(formatString, ap, printBuf, DbgConsole_PrintCallback); |
| /* print log */ |
| dbgResult = DbgConsole_SendDataReliable((uint8_t *)printBuf, (size_t)logLength); |
| |
| va_end(ap); |
| } |
| return dbgResult; |
| } |
| |
| /* See fsl_debug_console.h for documentation of this function. */ |
| int DbgConsole_Putchar(int ch) |
| { |
| /* print char */ |
| return DbgConsole_SendDataReliable((uint8_t *)&ch, 1U); |
| } |
| |
| /* See fsl_debug_console.h for documentation of this function. */ |
| int DbgConsole_Scanf(char *formatString, ...) |
| { |
| va_list ap; |
| int formatResult; |
| char scanfBuf[DEBUG_CONSOLE_SCANF_MAX_LOG_LEN + 1U] = {'\0'}; |
| |
| /* scanf log */ |
| (void)DbgConsole_ReadLine((uint8_t *)scanfBuf, DEBUG_CONSOLE_SCANF_MAX_LOG_LEN); |
| /* get va_list */ |
| va_start(ap, formatString); |
| /* format scanf log */ |
| formatResult = StrFormatScanf(scanfBuf, formatString, ap); |
| |
| va_end(ap); |
| |
| return formatResult; |
| } |
| /* See fsl_debug_console.h for documentation of this function. */ |
| int DbgConsole_BlockingPrintf(const char *formatString, ...) |
| { |
| va_list ap; |
| status_t status; |
| int logLength = 0, dbgResult = 0; |
| char printBuf[DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN] = {'\0'}; |
| |
| if (NULL == g_serialHandle) |
| { |
| return 0; |
| } |
| |
| va_start(ap, formatString); |
| /* format print log first */ |
| logLength = StrFormatPrintf(formatString, ap, printBuf, DbgConsole_PrintCallback); |
| |
| #if defined(DEBUG_CONSOLE_TRANSFER_NON_BLOCKING) |
| SerialManager_CancelWriting(((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0])); |
| #endif |
| /* print log */ |
| status = |
| (status_t)SerialManager_WriteBlocking(((serial_write_handle_t)&s_debugConsoleState.serialWriteHandleBuffer[0]), |
| (uint8_t *)printBuf, (size_t)logLength); |
| dbgResult = (((status_t)kStatus_Success == status) ? (int)logLength : -1); |
| va_end(ap); |
| |
| return dbgResult; |
| } |
| |
| #ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING |
| status_t DbgConsole_TryGetchar(char *ch) |
| { |
| #if (defined(DEBUG_CONSOLE_RX_ENABLE) && (DEBUG_CONSOLE_RX_ENABLE > 0U)) |
| uint32_t length = 0; |
| status_t status = (status_t)kStatus_Fail; |
| |
| assert(ch); |
| |
| if (NULL == g_serialHandle) |
| { |
| return kStatus_Fail; |
| } |
| |
| /* take mutex lock function */ |
| DEBUG_CONSOLE_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_debugConsoleReadSemaphore); |
| |
| if (kStatus_SerialManager_Success == |
| SerialManager_TryRead(((serial_read_handle_t)&s_debugConsoleState.serialReadHandleBuffer[0]), (uint8_t *)ch, 1, |
| &length)) |
| { |
| if (length != 0U) |
| { |
| #if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION |
| (void)DbgConsole_EchoCharacter((uint8_t *)ch, true, NULL); |
| #endif |
| status = (status_t)kStatus_Success; |
| } |
| } |
| /* release mutex lock function */ |
| DEBUG_CONSOLE_GIVE_MUTEX_SEMAPHORE(s_debugConsoleReadSemaphore); |
| return status; |
| #else |
| return (status_t)kStatus_Fail; |
| #endif |
| } |
| #endif |
| |
| /* See fsl_debug_console.h for documentation of this function. */ |
| int DbgConsole_Getchar(void) |
| { |
| uint8_t ch = 0U; |
| |
| /* Get char */ |
| (void)DbgConsole_ReadCharacter(&ch); |
| |
| return (int)ch; |
| } |
| |
| #endif /* SDK_DEBUGCONSOLE */ |
| |
| /*************Code to support toolchain's printf, scanf *******************************/ |
| /* These function __write and __read is used to support IAR toolchain to printf and scanf*/ |
| #if (defined(__ICCARM__)) |
| #if defined(SDK_DEBUGCONSOLE_UART) |
| #pragma weak __write |
| size_t __write(int handle, const unsigned char *buffer, size_t size); |
| size_t __write(int handle, const unsigned char *buffer, size_t size) |
| { |
| size_t ret; |
| if (0 == buffer) |
| { |
| /* |
| * This means that we should flush internal buffers. Since we don't we just return. |
| * (Remember, "handle" == -1 means that all handles should be flushed.) |
| */ |
| ret = 0U; |
| } |
| else if ((handle != 1) && (handle != 2)) |
| { |
| /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. |
| */ |
| ret = (uint32_t)0xff; |
| } |
| else |
| { |
| /* Send data. */ |
| uint8_t buff[512]; |
| (void)memcpy(buff, buffer, size); |
| (void)DbgConsole_SendDataReliable((uint8_t *)buff, size); |
| |
| ret = size; |
| } |
| return ret; |
| } |
| |
| #pragma weak __read |
| size_t __read(int handle, unsigned char *buffer, size_t size); |
| size_t __read(int handle, unsigned char *buffer, size_t size) |
| { |
| uint8_t ch = 0U; |
| int actualSize = 0; |
| |
| /* This function only reads from "standard in", for all other file handles it returns failure. */ |
| if (0 != handle) |
| { |
| actualSize = -1; |
| } |
| else |
| { |
| /* Receive data.*/ |
| for (; size > 0U; size--) |
| { |
| (void)DbgConsole_ReadCharacter(&ch); |
| if (0U == ch) |
| { |
| break; |
| } |
| |
| *buffer++ = ch; |
| actualSize++; |
| } |
| } |
| return (size_t)actualSize; |
| } |
| #endif /* SDK_DEBUGCONSOLE_UART */ |
| |
| /* support LPC Xpresso with RedLib */ |
| #elif (defined(__REDLIB__)) |
| |
| #if (defined(SDK_DEBUGCONSOLE_UART)) |
| int __attribute__((weak)) __sys_write(int handle, char *buffer, int size) |
| { |
| if (buffer == 0) |
| { |
| /* return -1 if error. */ |
| return -1; |
| } |
| |
| /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */ |
| if ((handle != 1) && (handle != 2)) |
| { |
| return -1; |
| } |
| |
| /* Send data. */ |
| DbgConsole_SendDataReliable((uint8_t *)buffer, size); |
| |
| return 0; |
| } |
| |
| int __attribute__((weak)) __sys_readc(void) |
| { |
| char tmp; |
| |
| /* Receive data. */ |
| DbgConsole_ReadCharacter((uint8_t *)&tmp); |
| |
| return tmp; |
| } |
| #endif |
| |
| /* These function fputc and fgetc is used to support KEIL toolchain to printf and scanf*/ |
| #elif defined(__CC_ARM) || defined(__ARMCC_VERSION) |
| #if defined(SDK_DEBUGCONSOLE_UART) |
| #if defined(__CC_ARM) |
| struct __FILE |
| { |
| int handle; |
| /* |
| * Whatever you require here. If the only file you are using is standard output using printf() for debugging, |
| * no file handling is required. |
| */ |
| }; |
| #endif |
| |
| /* FILE is typedef in stdio.h. */ |
| #pragma weak __stdout |
| #pragma weak __stdin |
| FILE __stdout; |
| FILE __stdin; |
| |
| #pragma weak fputc |
| int fputc(int ch, FILE *f) |
| { |
| /* Send data. */ |
| return DbgConsole_SendDataReliable((uint8_t *)(&ch), 1); |
| } |
| |
| #pragma weak fgetc |
| int fgetc(FILE *f) |
| { |
| char ch; |
| |
| /* Receive data. */ |
| DbgConsole_ReadCharacter((uint8_t *)&ch); |
| |
| return ch; |
| } |
| |
| /* |
| * Terminate the program, passing a return code back to the user. |
| * This function may not return. |
| */ |
| void _sys_exit(int returncode) |
| { |
| while (1) |
| { |
| } |
| } |
| |
| /* |
| * Writes a character to the output channel. This function is used |
| * for last-resort error message output. |
| */ |
| void _ttywrch(int ch) |
| { |
| char ench = ch; |
| DbgConsole_SendDataReliable((uint8_t *)(&ench), 1); |
| } |
| |
| char *_sys_command_string(char *cmd, int len) |
| { |
| return (cmd); |
| } |
| #endif /* SDK_DEBUGCONSOLE_UART */ |
| |
| /* These function __write and __read is used to support ARM_GCC, KDS, Atollic toolchains to printf and scanf*/ |
| #elif (defined(__GNUC__)) |
| |
| #if ((defined(__GNUC__) && (!defined(__MCUXPRESSO)) && (defined(SDK_DEBUGCONSOLE_UART))) || \ |
| (defined(__MCUXPRESSO) && (defined(SDK_DEBUGCONSOLE_UART)))) |
| int __attribute__((weak)) _write(int handle, char *buffer, int size); |
| int __attribute__((weak)) _write(int handle, char *buffer, int size) |
| { |
| if (buffer == NULL) |
| { |
| /* return -1 if error. */ |
| return -1; |
| } |
| |
| /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */ |
| if ((handle != 1) && (handle != 2)) |
| { |
| return -1; |
| } |
| |
| /* Send data. */ |
| (void)DbgConsole_SendDataReliable((uint8_t *)buffer, (size_t)size); |
| |
| return size; |
| } |
| |
| int __attribute__((weak)) _read(int handle, char *buffer, int size); |
| int __attribute__((weak)) _read(int handle, char *buffer, int size) |
| { |
| uint8_t ch = 0U; |
| int actualSize = 0; |
| |
| /* This function only reads from "standard in", for all other file handles it returns failure. */ |
| if (handle != 0) |
| { |
| return -1; |
| } |
| |
| /* Receive data. */ |
| for (; size > 0; size--) |
| { |
| if (DbgConsole_ReadCharacter(&ch) < 0) |
| { |
| break; |
| } |
| |
| *buffer++ = (char)ch; |
| actualSize++; |
| |
| if ((ch == 0U) || (ch == (uint8_t)'\n') || (ch == (uint8_t)'\r')) |
| { |
| break; |
| } |
| } |
| |
| return (actualSize > 0) ? actualSize : -1; |
| } |
| #endif |
| |
| #endif /* __ICCARM__ */ |