/** ****************************************************************************** * @file dbg_trace.c * @author MCD Application Team * @brief This file contains the Interface with BLE Drivers functions. ****************************************************************************** * @attention * *

© Copyright (c) 2019 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "utilities_common.h" #include "stm_queue.h" #include "dbg_trace.h" /* Definition of the function */ #if !defined(__GNUC__) /* SW4STM32 */ size_t __write(int handle, const unsigned char * buf, size_t bufSize); #endif /** @addtogroup TRACE * @{ */ /** @defgroup TRACE_LOG * @brief TRACE Logging functions * @{ */ /* Private typedef -----------------------------------------------------------*/ /** @defgroup TRACE Log private typedef * @{ */ /** * @} */ /* Private defines -----------------------------------------------------------*/ /** @defgroup TRACE Log private defines * @{ */ /** * @} */ /* Private macros ------------------------------------------------------------*/ /** @defgroup TRACE Log private macros * @{ */ /** * @} */ /* Private variables ---------------------------------------------------------*/ /** @defgroup TRACE Log private variables * @{ */ #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 )) #if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0) static queue_t MsgDbgTraceQueue; static uint8_t MsgDbgTraceQueueBuff[DBG_TRACE_MSG_QUEUE_SIZE]; #endif __IO ITStatus DbgTracePeripheralReady = SET; #endif /** * @} */ /* Global variables ----------------------------------------------------------*/ /** @defgroup TRACE Log Global variable * @{ */ /** * @} */ /* Private function prototypes -----------------------------------------------*/ /** @defgroup TRACE Log private function prototypes * @{ */ #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 )) static void DbgTrace_TxCpltCallback(void); #endif /** * @} */ /* Private Functions Definition ------------------------------------------------------*/ /** @defgroup TRACE Log Private function * @{ */ /* Functions Definition ------------------------------------------------------*/ /** @defgroup TRACE Log APIs * @{ */ /** * @brief DbgTraceGetFileName: Return filename string extracted from full path information * @param *fullPath Fullpath string (path + filename) * @retval char* Pointer on filename string */ const char *DbgTraceGetFileName(const char *fullpath) { const char *ret = fullpath; if (strrchr(fullpath, '\\') != NULL) { ret = strrchr(fullpath, '\\') + 1; } else if (strrchr(fullpath, '/') != NULL) { ret = strrchr(fullpath, '/') + 1; } return ret; } /** * @brief DbgTraceBuffer: Output buffer content information to output Stream * @param *pBuffer Pointer on buffer to be output * @param u32Length buffer Size * @paramt strFormat string as expected by "printf" function. Used to desrcibe buffer content information. * @param ... Paremeters to be "formatted" in strFormat string (if any) * @retval None */ void DbgTraceBuffer(const void *pBuffer, uint32_t u32Length, const char *strFormat, ...) { va_list vaArgs; uint32_t u32Index; va_start(vaArgs, strFormat); vprintf(strFormat, vaArgs); va_end(vaArgs); for (u32Index = 0; u32Index < u32Length; u32Index ++) { printf(" %02X", ((const uint8_t *) pBuffer)[u32Index]); } } #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 )) /** * @brief DBG_TRACE USART Tx Transfer completed callback * @param UartHandle: UART handle. * @note Indicate the end of the transmission of a DBG_TRACE trace buffer to DBG_TRACE USART. If queue * contains new trace data to transmit, start a new transmission. * @retval None */ static void DbgTrace_TxCpltCallback(void) { #if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0) uint8_t* buf; uint16_t bufSize; BACKUP_PRIMASK(); DISABLE_IRQ(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ /* Remove element just sent to UART */ CircularQueue_Remove(&MsgDbgTraceQueue,&bufSize); /* Sense if new data to be sent */ buf=CircularQueue_Sense(&MsgDbgTraceQueue,&bufSize); if ( buf != NULL) { RESTORE_PRIMASK(); DbgOutputTraces((uint8_t*)buf, bufSize, DbgTrace_TxCpltCallback); } else { DbgTracePeripheralReady = SET; RESTORE_PRIMASK(); } #else BACKUP_PRIMASK(); DISABLE_IRQ(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ DbgTracePeripheralReady = SET; RESTORE_PRIMASK(); #endif } #endif void DbgTraceInit( void ) { #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 )) DbgOutputInit(); #if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0) CircularQueue_Init(&MsgDbgTraceQueue, MsgDbgTraceQueueBuff, DBG_TRACE_MSG_QUEUE_SIZE, 0, CIRCULAR_QUEUE_SPLIT_IF_WRAPPING_FLAG); #endif #endif return; } #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 )) #if defined(__GNUC__) /* SW4STM32 (GCC) */ /** * @brief _write: override the __write standard lib function to redirect printf to USART. * @param handle output handle (STDIO, STDERR...) * @param buf buffer to write * @param bufsize buffer size * @param ...: arguments to be formatted in format string * @retval none */ size_t _write(int handle, const unsigned char * buf, size_t bufSize) { return ( DbgTraceWrite(handle, buf, bufSize) ); } #else /** * @brief __write: override the _write standard lib function to redirect printf to USART. * @param handle output handle (STDIO, STDERR...) * @param buf buffer to write * @param bufsize buffer size * @param ...: arguments to be formatted in format string * @retval none */ size_t __write(int handle, const unsigned char * buf, size_t bufSize) { return ( DbgTraceWrite(handle, buf, bufSize) ); } #endif /* #if defined(__GNUC__) */ /** * @brief Override the standard lib function to redirect printf to USART. * @param handle output handle (STDIO, STDERR...) * @param buf buffer to write * @param bufsize buffer size * @retval Number of elements written */ size_t DbgTraceWrite(int handle, const unsigned char * buf, size_t bufSize) { size_t chars_written = 0; uint8_t* buffer; BACKUP_PRIMASK(); /* Ignore flushes */ if ( handle == -1 ) { chars_written = ( size_t ) 0; } /* Only allow stdout/stderr output */ else if ( ( handle != 1 ) && ( handle != 2 ) ) { chars_written = ( size_t ) - 1; } /* Parameters OK, call the low-level character output routine */ else if (bufSize != 0) { chars_written = bufSize; /* If queue emepty and TX free, send directly */ /* CS Start */ #if (DBG_TRACE_USE_CIRCULAR_QUEUE != 0) DISABLE_IRQ(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ buffer=CircularQueue_Add(&MsgDbgTraceQueue,(uint8_t*)buf, bufSize,1); if (buffer && DbgTracePeripheralReady) { DbgTracePeripheralReady = RESET; RESTORE_PRIMASK(); DbgOutputTraces((uint8_t*)buffer, bufSize, DbgTrace_TxCpltCallback); } else { RESTORE_PRIMASK(); } #else DISABLE_IRQ(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ DbgTracePeripheralReady = RESET; RESTORE_PRIMASK(); DbgOutputTraces((uint8_t*)buf, bufSize, DbgTrace_TxCpltCallback); while (!DbgTracePeripheralReady); #endif /* CS END */ } return ( chars_written ); } #if defined ( __CC_ARM ) /* Keil */ /* For KEIL re-implement our own version of fputc */ int fputc(int ch, FILE *f) { /* temp char avoids endianness issue */ char tempch = ch; /* Write one character to Debug Circular Queue */ DbgTraceWrite(1U, (const unsigned char *) &tempch, 1); return ch; } #endif /* #if defined ( __CC_ARM ) */ #endif /* #if (( CFG_DEBUG_TRACE_FULL != 0 ) || ( CFG_DEBUG_TRACE_LIGHT != 0 )) */ /** * @} */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/