Subversion Repositories Projects

Rev

Rev 131 | Rev 230 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
40 dhylands 1
/****************************************************************************
2
*
3
*   Copyright (c) 2006 Dave Hylands     <dhylands@gmail.com>
4
*
5
*   This program is free software; you can redistribute it and/or modify
6
*   it under the terms of the GNU General Public License version 2 as
7
*   published by the Free Software Foundation.
8
*
9
*   Alternatively, this software may be distributed under the terms of BSD
10
*   license.
11
*
12
*   See README and COPYING for more details.
13
*
14
****************************************************************************/
15
/**
16
*
17
*   @file   Log.cpp
18
*
19
*   @brief  This file contains the implementation of the logging functions.
20
*
21
****************************************************************************/
22
 
23
// ---- Include Files -------------------------------------------------------
24
 
25
#include "Log.h"
26
 
27
#if CFG_LOG_USE_STDIO
28
#   include <stdio.h>
29
#else
30
#   include "Str.h"
31
#endif
32
 
33
// ---- Public Variables ----------------------------------------------------
34
// ---- Private Constants and Types -----------------------------------------
35
 
36
#if defined( AVR )
37
 
38
#undef  Log
39
#undef  LogError
213 dhylands 40
#undef  LogAssertFailed
40 dhylands 41
#undef  vLog
42
 
131 dhylands 43
#define Log             Log_P
44
#define LogError        LogError_P
45
#define LogAssertFailed LogAssertFailed_P
46
#define vLog            vLog_P
47
#define LogBuf          LogBuf_P
40 dhylands 48
 
213 dhylands 49
//#define char            prog_char
40 dhylands 50
 
51
#else
52
 
53
#define PSTR(str)   str
54
 
55
int gQuiet = 0;
56
 
57
#endif
58
 
213 dhylands 59
int gVerbose = 0;
60
int gDebug = 0;
61
 
40 dhylands 62
#if CFG_LOG_TO_BUFFER
63
 
64
volatile    LOG_Buffer_t    LOG_gBuffer;
65
 
66
#endif
125 dhylands 67
#if CFG_LOG_ALLOW_DEFERRED_NL
68
int         gDeferredNewline = 0;
69
#endif
40 dhylands 70
 
71
// ---- Private Variables ---------------------------------------------------
72
 
73
#if CFG_LOG_USE_STDIO
74
 
75
FILE   *gLogFs = NULL;
76
 
77
#endif
78
 
79
// ---- Private Function Prototypes -----------------------------------------
80
 
81
// ---- Functions -----------------------------------------------------------
82
 
83
/**
84
 * @addtogroup Log
85
 * @{
86
 */
87
 
88
#if !defined( AVR )
89
 
90
void DefaultLogFunc( int logLevel, const char *fmt, va_list args )
91
{
92
    FILE    *fs;
93
 
94
    if ( gQuiet && ( logLevel == LOG_LEVEL_NORMAL ))
95
    {
96
        return;
97
    }
98
 
99
    if ( gLogFs == NULL )
100
    {
101
        fs = stderr;
102
    }
103
    else
104
    {
105
        fs = gLogFs;
106
    }
107
 
108
    if ( logLevel == LOG_LEVEL_ERROR )
109
    {
110
        fprintf( fs, "ERROR: " );
111
    }
131 dhylands 112
    else
113
    if ( logLevel == LOG_LEVEL_ASSERT )
114
    {
115
        fprintf( fs, "ASSERT: " );
116
    }
40 dhylands 117
    vfprintf( fs, fmt, args );
118
    fflush( fs );
119
 
120
} // DefaultLogFunc
121
 
122
static LogFunc_t    gLogFunc = DefaultLogFunc;
123
 
124
void SetLogFunc( LogFunc_t logFunc )
125
{
126
 
127
    gLogFunc = logFunc;
128
 
129
} // SetLogFunc
130
 
131
#endif
132
 
133
//***************************************************************************
134
/**
135
*   Sets the logging stream
136
*/
137
 
138
#if CFG_LOG_USE_STDIO
139
void LogInit( FILE *logFs )
140
{
141
    gLogFs = logFs;
142
 
143
} // LogInit
144
 
145
#else
146
 
147
static int LogToUartFunc( void *outParm, int ch )
148
{
70 dhylands 149
    CFG_LOG_PUT_CHAR_FUNC( ch );
40 dhylands 150
 
151
    return 1;
152
}
153
#endif
154
 
155
//***************************************************************************
156
/**
157
*   Logs a string using printf like semantics
158
*/
159
 
160
void Log
161
(
162
    const char *fmt,    ///< printf style format specifier
163
    ...                 ///< variable list of arguments
164
)
165
{
166
    va_list args;
167
 
168
    va_start( args, fmt );
169
    vLog( fmt, args );
170
    va_end( args );
171
}
172
 
173
//***************************************************************************
174
/**
175
*   Logs a string using printf like semantics
176
*/
177
 
178
void vLog
179
(
180
    const char *fmt,    ///< printf style format specified
181
    va_list     args    ///< variable list of arguments
182
)
183
{
184
    // For now we call printf directly. A better way would be to install
185
    // a callback which does the real work
186
 
125 dhylands 187
#if CFG_LOG_ALLOW_DEFERRED_NL
188
    if ( gDeferredNewline && ( *fmt != '\r' ))
189
    {
190
        gDeferredNewline = 0;
191
        Log( "\r\n" );
192
    }
193
#endif
194
 
40 dhylands 195
#if defined( AVR )
196
#   if CFG_LOG_USE_STDIO
197
    if ( gLogFs != NULL )
198
    {
199
        vfprintf_P( gLogFs, fmt, args );
200
    }
201
#   else
202
    vStrXPrintf_P( LogToUartFunc, NULL, fmt, args );
203
#   endif
204
#else
205
    if ( gLogFunc != NULL )
206
    {
207
        gLogFunc( LOG_LEVEL_NORMAL, fmt, args );
208
    }
209
#endif
210
}
211
 
212
#if !defined( AVR )
213
 
214
//***************************************************************************
215
/**
131 dhylands 216
*   Generic logging function
217
*/
218
 
219
void vLogFunc
220
(
221
    int         logLevel,   ///< Type of log
222
    const char *fmt,        ///< printf style format specified
223
    va_list     args        ///< variable list of arguments
224
)
225
{
226
    if ( gLogFunc != NULL )
227
    {
228
        gLogFunc( logLevel, fmt, args );
229
    }
230
 
231
} // vLogFunc
232
 
233
//***************************************************************************
234
/**
235
*   Generic logging function
236
*/
237
 
238
void LogFunc
239
(
240
    int         logLevel,   ///< Type of log
241
    const char *fmt,        ///< printf style format specified
242
    ...                     ///< variable list of arguments
243
)
244
{
245
    va_list args;
246
 
247
    va_start( args, fmt );
248
    vLogFunc( logLevel, fmt, args );
249
    va_end( args );
250
 
251
} // LogFunc
252
 
253
//***************************************************************************
254
/**
40 dhylands 255
*   Logs an error.
256
*/
257
 
258
void vLogError
259
(
260
    const char *fmt,    ///< printf style format specified
261
    va_list     args    ///< variable list of arguments
262
)
263
{
131 dhylands 264
    vLogFunc( LOG_LEVEL_ERROR, fmt, args );
40 dhylands 265
 
131 dhylands 266
} // vLogError
267
 
40 dhylands 268
#endif
269
 
270
/***************************************************************************/
271
/**
272
*   Logs an error
273
*/
274
 
275
void LogError
276
(
277
    const char *fmt,    ///< printf style format specifier
278
    ...                 ///< variable list of arguments
279
)
280
{
281
    va_list args;
282
 
283
#if defined( AVR )
284
    Log_P( PSTR( "ERROR: " ));
285
 
286
    va_start( args, fmt );
287
    vLog( fmt, args );
288
    va_end( args );
289
#else
290
    va_start( args, fmt );
131 dhylands 291
    vLogFunc( LOG_LEVEL_ERROR, fmt, args );
40 dhylands 292
    va_end( args );
293
#endif
294
 
295
} // LogError
296
 
297
/***************************************************************************/
298
/**
131 dhylands 299
*   Logs an assertion failure
300
*/
301
 
302
void LogAssertFailed
303
(
304
    const char *expr,
305
    const char *fileName,
306
    unsigned    lineNum,
307
    const char *function
308
)
309
{
310
#if defined( AVR )
311
    Log_P( PSTR( "ASSERT failed: " ));
312
    Log_P( fileName );
313
    Log_P( PSTR( ": %d: " ), lineNum );
314
    Log_P( function );
315
    Log_P( PSTR( " Assertion '" ));
316
    Log_P( expr );
213 dhylands 317
    Log_P( PSTR( "' failed.\n" ));
131 dhylands 318
#else
319
    LogFunc( LOG_LEVEL_ASSERT, "%s: %d: %s Assertion '%s' failed.\n",
320
             fileName, lineNum, function, expr );
321
#endif
322
 
323
} // LogAssertFailed
324
 
325
/***************************************************************************/
326
/**
40 dhylands 327
*   Logs an entry to the log buffer
328
*/
329
 
330
#if CFG_LOG_TO_BUFFER
331
 
332
void LogBuf( const char *fmt, uint8_t arg1, uint8_t arg2 LOG_EXTRA_PARAMS_DECL )
333
{
334
#if defined( AVR )
335
    uint8_t sreg = SREG;
336
    cli();
337
#endif
338
 
339
    if ( CBUF_IsFull( LOG_gBuffer ))
340
    {
341
        volatile LOG_Entry_t *entry = CBUF_GetLastEntryPtr( LOG_gBuffer );
342
 
343
        entry->fmt = PSTR( "*** Lost Messages ***\n" );
344
    }
345
    else
346
    {
347
        volatile LOG_Entry_t *entry = CBUF_GetPushEntryPtr( LOG_gBuffer );
348
 
349
        entry->fmt    = fmt;
350
        entry->param1 = arg1;
351
        entry->param2 = arg2;
352
 
353
#if CFG_LOG_EXTRA_PARAMS
354
        entry->param3 = arg3;
355
        entry->param4 = arg4;
356
#endif
357
 
358
        CBUF_AdvancePushIdx( LOG_gBuffer );
359
    }
360
 
361
#if defined( AVR )
362
    SREG = sreg;
363
#endif
364
 
365
} // LogBuf
366
 
367
#endif  // CFG_LOG_TO_BUFFER
368
 
369
/***************************************************************************/
370
/**
371
*   Dumps any unlogged entries from the log buffer
372
*/
373
 
374
#if CFG_LOG_TO_BUFFER
375
 
376
void LogBufDump( void )
377
{
378
    while ( !CBUF_IsEmpty( LOG_gBuffer ))
379
    {
380
        volatile LOG_Entry_t *entry = CBUF_GetPopEntryPtr( LOG_gBuffer );
381
 
382
#if CFG_LOG_EXTRA_PARAMS
383
        Log( entry->fmt, entry->param1, entry->param2, entry->param3, entry->param4 );
384
#else
385
        Log( entry->fmt, entry->param1, entry->param2 );
386
#endif
387
 
388
        CBUF_AdvancePopIdx( LOG_gBuffer );
389
    }
390
 
391
} // LogBufDump
392
 
393
#endif  // CFG_LOG_TO_BUFFER
394
 
395
/** @} */
396