344 lines
11 KiB
C
344 lines
11 KiB
C
/*****************************************************************************/
|
|
/* FILENAME : Log.c */
|
|
/* */
|
|
/* DESCRIPTION : Generic Uart Logger Library */
|
|
/* */
|
|
/* NOTES : Copyright Sathish Kumar P. All rights reserved. */
|
|
/* */
|
|
/* AUTHOR : Sathish Kumar */
|
|
/* sathishembeddedgeek@gmail.com */
|
|
/* */
|
|
/* START DATE : 3rd May 2021 */
|
|
/* */
|
|
/* VERSION DATE WHO DETAIL */
|
|
/* 00.00.01 03MAY21 Sathish Kumar initial version */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
//TODO: Logging using Uart DMA or interrupt
|
|
|
|
/*****************************************************************************/
|
|
/* I N C L U D E S */
|
|
/*****************************************************************************/
|
|
#include "Log.h"
|
|
#include <stdarg.h>
|
|
|
|
#if(LOG_USE_BUFFERING == 1)
|
|
#include <CircularQ.h>
|
|
#endif
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* D E F I N I N T I O N S */
|
|
/*****************************************************************************/
|
|
|
|
#if (LOG_USE_PRETTY_PRINT)
|
|
|
|
/* Pretty prints */
|
|
#define PREFIX "\033["
|
|
#define SUFFIX "\033[0m"
|
|
/* color */
|
|
#define RED ";31m"
|
|
#define GREEN ";32m"
|
|
#define YELLOW ";33m"
|
|
#define BLUE ";34m"
|
|
#define MAGENTA ";35m"
|
|
#define CYAN ";36m"
|
|
#define WHITE ";37m"
|
|
/* Effect */
|
|
#define NORMAL "0"
|
|
#define BOLD "1"
|
|
|
|
#else
|
|
/* Pretty prints */
|
|
#define PREFIX
|
|
#define SUFFIX
|
|
|
|
/* color */
|
|
#define RED
|
|
#define GREEN
|
|
#define YELLOW
|
|
#define BLUE
|
|
#define MAGENTA
|
|
#define CYAN
|
|
#define WHITE
|
|
|
|
/* Effect */
|
|
#define NORMAL
|
|
#define BOLD
|
|
#endif
|
|
|
|
#define FORMAT_COLOR(STR, COLOR) PREFIX COLOR STR SUFFIX
|
|
|
|
/*****************************************************************************/
|
|
/* CONSTANTS & VARIABLES */
|
|
/*****************************************************************************/
|
|
#if(LOG_USE_BUFFERING == 1)
|
|
static queue_param_t LogMsgQ;
|
|
static uint8_t LogBuff[LOG_MSG_QUEUE_SIZE];
|
|
#endif
|
|
|
|
static char local_buf[LOG_LOCAL_BUF_SIZE];
|
|
__IO ITStatus TracePeripheralReady = SET;
|
|
|
|
const uint8_t *log_type[]=
|
|
{
|
|
(uint8_t*)FORMAT_COLOR("[DEBUG]", WHITE),
|
|
(uint8_t*)FORMAT_COLOR("[INFO]", GREEN),
|
|
(uint8_t*)FORMAT_COLOR("[WARN]", YELLOW),
|
|
(uint8_t*)FORMAT_COLOR("[ERROR]", RED),
|
|
(uint8_t*)FORMAT_COLOR("[FATAL]", RED),
|
|
(uint8_t*)FORMAT_COLOR("[ALL]", CYAN),
|
|
};
|
|
|
|
|
|
static LogLevel_t cur_log_lvl = LOG_INFO;
|
|
static uint8_t log_enabled = 0;
|
|
|
|
//static uint32_t log_uart_baudrate = 921600;
|
|
|
|
/*****************************************************************************/
|
|
/* F U N C T I O N S */
|
|
/*****************************************************************************/
|
|
/* Call back function for Tx Complete */
|
|
void Log_UartTxCpltCallback(void);
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
uint8_t Log_Init()
|
|
{
|
|
uint8_t ret_val=0;
|
|
|
|
//TODO: Logging using Uart DMA or interrupt
|
|
/* Enable low level Uart settings for logging */
|
|
//UartRegisterTxCb(Log_UartTxCpltCallback);
|
|
|
|
#if(LOG_USE_BUFFERING == 1)
|
|
/* Q initialization */
|
|
circular_queue_init(&LogMsgQ, LogBuff, LOG_MSG_QUEUE_SIZE);
|
|
#endif
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
void Log_Task(uint32_t call_rate)
|
|
{
|
|
(void)call_rate; /* unused warning removal */
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
void Log_Enable(uint8_t enable)
|
|
{
|
|
if((uint8_t)1 == enable)
|
|
{
|
|
//TODO: Logging using Uart DMA or interrupt
|
|
//Uart_ReInit();
|
|
log_enabled = 1;
|
|
}
|
|
else
|
|
{
|
|
log_enabled = 0;
|
|
TracePeripheralReady = SET;
|
|
#if(LOG_USE_BUFFERING == 1)
|
|
/* Clears the buffers and elements */
|
|
circular_queue_init(&LogMsgQ, LogBuff, LOG_MSG_QUEUE_SIZE);
|
|
#endif
|
|
|
|
//TODO: Logging using Uart DMA or interrupt
|
|
//Uart_DeInit();
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
uint8_t Log_GetEnabledStatus(void)
|
|
{
|
|
return log_enabled;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
uint8_t Log_IsPendingTx(void)
|
|
{
|
|
uint8_t ret_val = true;
|
|
|
|
CRITICAL_SECTION_BEGIN();
|
|
#if(LOG_USE_BUFFERING == 1)
|
|
if((TracePeripheralReady == SET)&&(circular_queue_sense(&LogMsgQ) == -1))
|
|
#else
|
|
if(TracePeripheralReady == SET)
|
|
#endif
|
|
{
|
|
ret_val = false;
|
|
}
|
|
CRITICAL_SECTION_END();
|
|
return ret_val;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
void Log_LowPowerMode(uint8_t enable)
|
|
{
|
|
/* Only when logging is enabled */
|
|
if((uint8_t)1 == log_enabled)
|
|
{
|
|
if((uint8_t)1 == enable)
|
|
{
|
|
#if(LOG_USE_BUFFERING == 1)
|
|
/* Clears the buffers and elements */
|
|
circular_queue_init(&LogMsgQ, LogBuff, LOG_MSG_QUEUE_SIZE);
|
|
#endif
|
|
//TODO: Logging using Uart DMA or interrupt
|
|
//Uart_DeInit();
|
|
}
|
|
else
|
|
{
|
|
//TODO: Logging using Uart DMA or interrupt
|
|
//Uart_ReInit();
|
|
}
|
|
}
|
|
}
|
|
|
|
///*****************************************************************************/
|
|
///* see header file for description. */
|
|
///*****************************************************************************/
|
|
//void Log_SetUartBaudrate(uint32_t new_baudrate)
|
|
//{
|
|
// if(0 == UartSetBaudrate(new_baudrate))
|
|
// {
|
|
// log_uart_baudrate = new_baudrate;
|
|
// }
|
|
//}
|
|
//
|
|
///*****************************************************************************/
|
|
///* see header file for description. */
|
|
///*****************************************************************************/
|
|
//uitn32_t Log_GetUartBaudrate()
|
|
//{
|
|
// return log_uart_baudrate;
|
|
//}
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
void Log_SetLogLvl(LogLevel_t new_log_lvl)
|
|
{
|
|
if(new_log_lvl < LOG_MAX)
|
|
{
|
|
cur_log_lvl = new_log_lvl;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
LogLevel_t Log_GetLogLvl(void)
|
|
{
|
|
return cur_log_lvl;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
void Log_TString(LogLevel_t log_lvl,const char *str, ...)
|
|
{
|
|
if((cur_log_lvl <= log_lvl)&&(1 == log_enabled))
|
|
{
|
|
va_list arg;
|
|
int indx=0;
|
|
indx = snprintf (&local_buf[0], LOG_LOCAL_BUF_SIZE, "%s\t: ", (char*)log_type[log_lvl]);
|
|
va_start (arg, str);
|
|
indx = vsnprintf (&local_buf[indx], (LOG_LOCAL_BUF_SIZE-(size_t)indx), str, arg);
|
|
va_end (arg);
|
|
strncat(local_buf,"\r\n",3);
|
|
|
|
Log_UartSend((uint8_t *)local_buf,(uint16_t)strlen(local_buf));
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
void Log_UartSend(uint8_t *buf,uint16_t bufLen)
|
|
{
|
|
#if(LOG_USE_BUFFERING == 0)
|
|
Log_WriteToHWUart(buf,bufLen);
|
|
#else
|
|
int status;
|
|
|
|
CRITICAL_SECTION_BEGIN();
|
|
status = circular_queue_add(&LogMsgQ,buf, bufLen);
|
|
|
|
if((status==0) && (TracePeripheralReady==SET))
|
|
{
|
|
uint8_t* buffer;
|
|
uint16_t bufSize;
|
|
TracePeripheralReady = RESET;
|
|
circular_queue_get(&LogMsgQ,&buffer,&bufSize);
|
|
CRITICAL_SECTION_END();
|
|
Log_WriteToHWUart_NonBlocking(buffer, bufSize);
|
|
//TODO: Logging using Uart DMA or interrupt. Remove after implemention
|
|
// Log_UartTxCpltCallback();
|
|
}
|
|
else
|
|
{
|
|
CRITICAL_SECTION_END();
|
|
}
|
|
|
|
if(status!=0)
|
|
{
|
|
//TODO: log queue is full
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* see header file for description. */
|
|
/*****************************************************************************/
|
|
void Log_UartTxCompleteCallback(void)
|
|
{
|
|
#if(LOG_USE_BUFFERING == 1)
|
|
/* buffer transmission complete*/
|
|
int status;
|
|
uint8_t* buffer;
|
|
uint16_t bufSize;
|
|
|
|
//TODO: Logging using Uart DMA or interrupt
|
|
CRITICAL_SECTION_BEGIN(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
|
|
|
|
/* Remove element just sent to UART */
|
|
circular_queue_remove(&LogMsgQ);
|
|
|
|
/* Sense if new data to be sent */
|
|
status=circular_queue_sense(&LogMsgQ);
|
|
|
|
if (status == 0)
|
|
{
|
|
circular_queue_get(&LogMsgQ,&buffer,&bufSize);
|
|
CRITICAL_SECTION_END();
|
|
|
|
//TODO: Logging using Uart DMA or interrupt. Remove after implemention
|
|
Log_WriteToHWUart_NonBlocking(buffer, bufSize);
|
|
}
|
|
else
|
|
{
|
|
TracePeripheralReady = SET;
|
|
CRITICAL_SECTION_END();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* E N D O F F I L E */
|
|
/*****************************************************************************/
|