嵌入式–实现通用日志
嵌入式设备中的业务层,一般都采用输出日志来作为调试手段。这里作为参考提供给新手们,希望对你们有所帮助。结合shell、command能实现很棒的调试手段。
头文件 debug.h
#ifndef __DEBUG__H__
#define __DEBUG__H__
#include <stdint.h>
#define USE_DEBUG // 调试开关
#define USE_ASSERT // 断言开关
#define LOG_CRT 0 // 严重错误
#define LOG_ERR 1 // 错误
#define LOG_WRN 2 // 警告
#define LOG_INF 3 // 消息
#define LOG_DBG 4 // 调试
#define LOG_DEFAULT LOG_WRN // 默认日志输出级别
void Debug_Print(uint8_t level, const char* filename, int line, const char* fmt, ...);
void Debug_SetLevel(uint8_t level);
uint8_t Debug_GetLevel(void);
void Assert_Handler(const char* filename, int line);
#ifdef USE_DEBUG
#define LOG_I(fmt, ...) Debug_Print(LOG_INF, __FILE__,__LINE__, fmt, ##__VA_ARGS__)
#define LOG_D(fmt, ...) Debug_Print(LOG_DBG, __FILE__,__LINE__, fmt, ##__VA_ARGS__)
#define LOG_W(fmt, ...) Debug_Print(LOG_WRN, __FILE__,__LINE__, fmt, ##__VA_ARGS__)
#define LOG_E(fmt, ...) Debug_Print(LOG_ERR, __FILE__,__LINE__, fmt, ##__VA_ARGS__)
#define LOG_C(fmt, ...) Debug_Print(LOG_CRT, __FILE__,__LINE__, fmt, ##__VA_ARGS__)
#define LOG_DATA(tmp,size) do{ \
int i = 0; \
printf("%s:\r\n", #tmp);\
for(i=0;i<size;i++) \
{ \
printf("%02x ", tmp[i]); \
if((i != 0) && (i % 16 == 0)) \
printf("\r\n"); \
} \
printf("\r\n"); \
}while(0)
#else
#define LOG_I(fmt, ...)
#define LOG_D(fmt, ...)
#define LOG_W(fmt, ...)
#define LOG_E(fmt, ...)
#define LOG_C(fmt, ...)
#define LOG_DATA(tmp,size)
#endif
#ifdef USE_ASSERT
#define ASSERT(e) ((e) ?(void)0 : Assert_Handler((uint8_t *)__FILE__, (int)__LINE__))
#else
#define ASSERT(e)
#endif
#define ERROR() Assert_Handler((const char *)__FILE__, (int)__LINE__)
#endif // __DEBUG__H__
源文件 debug.c
#include <stdarg.h>
#include <stdio.h>
#include "debug.h"
static uint8_t g_Debug_Level = LOG_DEFAULT;
void Debug_SetLevel(uint8_t level)
{
if(level > LOG_DBG)
{
return;
}
g_Debug_Level = level;
}
uint8_t Debug_GetLevel(void)
{
return g_Debug_Level;
}
void Debug_Print(uint8_t level, const char* filename, int line, const char* fmt, ...)
{
if(level > g_Debug_Level)
{
return;
}
switch(level)
{
case LOG_CRT:
printf("[%s,%d] CRIT:",filename, line);
break;
case LOG_ERR:
printf("[%s,%d] ERROR:",filename, line);
break;
case LOG_WRN:
printf("[%s,%d] WARN:",filename, line);
break;
case LOG_INF:
printf("[%s,%d] INFO:",filename, line);
break;
case LOG_DBG:
printf("[%s,%d] DEBUG:",filename, line);
break;
default: printf("[%s,%d] NONE:",filename, line);
break;
}
va_list valist;
va_start(valist,fmt);
vprintf(fmt,valist);
va_end(valist);
}
void Assert_Handler(const char* filename, int line)
{
Debug_Print(LOG_ERR, filename, line, "badcode\r\n");
while(1)
{
;
}
}