/**************************************************************************** * * Copyright (c) 2006 Dave Hylands <dhylands@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. * ****************************************************************************/ /** * * @file Log.cpp * * @brief This file contains the implementation of the logging functions. * ****************************************************************************/ // ---- Include Files ------------------------------------------------------- #include "Log.h" #if CFG_LOG_USE_STDIO # include <stdio.h> #else # include "Str.h" # include "UART.h" #endif // ---- Public Variables ---------------------------------------------------- // ---- Private Constants and Types ----------------------------------------- #if defined( AVR ) #undef Log #undef LogError #undef vLog #define Log Log_P #define LogError LogError_P #define vLog vLog_P #define LogBuf LogBuf_P #define char prog_char #else #define PSTR(str) str int gVerbose = 0; int gDebug = 0; int gQuiet = 0; #endif #if CFG_LOG_TO_BUFFER volatile LOG_Buffer_t LOG_gBuffer; #endif // ---- Private Variables --------------------------------------------------- #if CFG_LOG_USE_STDIO FILE *gLogFs = NULL; #endif // ---- Private Function Prototypes ----------------------------------------- // ---- Functions ----------------------------------------------------------- /** * @addtogroup Log * @{ */ #if !defined( AVR ) void DefaultLogFunc( int logLevel, const char *fmt, va_list args ) { FILE *fs; if ( gQuiet && ( logLevel == LOG_LEVEL_NORMAL )) { return; } if ( gLogFs == NULL ) { fs = stderr; } else { fs = gLogFs; } if ( logLevel == LOG_LEVEL_ERROR ) { fprintf( fs, "ERROR: " ); } vfprintf( fs, fmt, args ); fflush( fs ); } // DefaultLogFunc static LogFunc_t gLogFunc = DefaultLogFunc; void SetLogFunc( LogFunc_t logFunc ) { gLogFunc = logFunc; } // SetLogFunc #endif //*************************************************************************** /** * Sets the logging stream */ #if CFG_LOG_USE_STDIO void LogInit( FILE *logFs ) { gLogFs = logFs; } // LogInit #else static int LogToUartFunc( void *outParm, int ch ) { UART0_PutChar( ch ); return 1; } #endif //*************************************************************************** /** * Logs a string using printf like semantics */ void Log ( const char *fmt, ///< printf style format specifier ... ///< variable list of arguments ) { va_list args; va_start( args, fmt ); vLog( fmt, args ); va_end( args ); } //*************************************************************************** /** * Logs a string using printf like semantics */ void vLog ( const char *fmt, ///< printf style format specified va_list args ///< variable list of arguments ) { // For now we call printf directly. A better way would be to install // a callback which does the real work #if defined( AVR ) # if CFG_LOG_USE_STDIO if ( gLogFs != NULL ) { vfprintf_P( gLogFs, fmt, args ); } # else vStrXPrintf_P( LogToUartFunc, NULL, fmt, args ); # endif #else if ( gLogFunc != NULL ) { gLogFunc( LOG_LEVEL_NORMAL, fmt, args ); } #endif } #if !defined( AVR ) //*************************************************************************** /** * Logs an error. */ void vLogError ( const char *fmt, ///< printf style format specified va_list args ///< variable list of arguments ) { if ( gLogFunc != NULL ) { gLogFunc( LOG_LEVEL_ERROR, fmt, args ); } } #endif /***************************************************************************/ /** * Logs an error */ void LogError ( const char *fmt, ///< printf style format specifier ... ///< variable list of arguments ) { va_list args; #if defined( AVR ) //Log( "ERROR: " ); //Log_P( PSTR( "ERROR: " )); va_start( args, fmt ); vLog( fmt, args ); va_end( args ); #else va_start( args, fmt ); vLogError( fmt, args ); va_end( args ); #endif } // LogError /***************************************************************************/ /** * Logs an entry to the log buffer */ #if CFG_LOG_TO_BUFFER void LogBuf( const char *fmt, uint8_t arg1, uint8_t arg2 LOG_EXTRA_PARAMS_DECL ) { #if defined( AVR ) uint8_t sreg = SREG; cli(); #endif if ( CBUF_IsFull( LOG_gBuffer )) { volatile LOG_Entry_t *entry = CBUF_GetLastEntryPtr( LOG_gBuffer ); entry->fmt = PSTR( "*** Lost Messages ***\n" ); } else { volatile LOG_Entry_t *entry = CBUF_GetPushEntryPtr( LOG_gBuffer ); entry->fmt = fmt; entry->param1 = arg1; entry->param2 = arg2; #if CFG_LOG_EXTRA_PARAMS entry->param3 = arg3; entry->param4 = arg4; #endif CBUF_AdvancePushIdx( LOG_gBuffer ); } #if defined( AVR ) SREG = sreg; #endif } // LogBuf #endif // CFG_LOG_TO_BUFFER /***************************************************************************/ /** * Dumps any unlogged entries from the log buffer */ #if CFG_LOG_TO_BUFFER void LogBufDump( void ) { while ( !CBUF_IsEmpty( LOG_gBuffer )) { volatile LOG_Entry_t *entry = CBUF_GetPopEntryPtr( LOG_gBuffer ); #if CFG_LOG_EXTRA_PARAMS Log( entry->fmt, entry->param1, entry->param2, entry->param3, entry->param4 ); #else Log( entry->fmt, entry->param1, entry->param2 ); #endif CBUF_AdvancePopIdx( LOG_gBuffer ); } } // LogBufDump #endif // CFG_LOG_TO_BUFFER /** @} */