173 lines
3.3 KiB
C
173 lines
3.3 KiB
C
/** @file log.c
|
||
@brief 系统日志接口文件
|
||
@details 实现本地磁盘日志和调试器控制台日志输出
|
||
@version 1.0.0
|
||
@author HuangXin
|
||
@date 2012-11-20
|
||
@copyright Synway
|
||
*/
|
||
|
||
#include <linux/slab.h>
|
||
#include <linux/time.h>
|
||
#include <linux/rtc.h>
|
||
#include "log.h"
|
||
|
||
#ifndef NULL
|
||
#define NULL (0)
|
||
#endif
|
||
|
||
#ifndef TRUE
|
||
#define TRUE (1)
|
||
#endif
|
||
|
||
#ifndef FALSE
|
||
#define FALSE (0)
|
||
#endif
|
||
|
||
static int g_iMinLevel = LOG_All;
|
||
|
||
/**
|
||
* @brief Log 调试等级转字符串
|
||
* @param level 调试等级
|
||
* @return 调试等级对应的字符串
|
||
*/
|
||
static const char* LogLevelToStr(LOG_LEVEL level)
|
||
{
|
||
switch(level)
|
||
{
|
||
case LOG_Test:
|
||
return "T";
|
||
|
||
case LOG_Info:
|
||
return "I";
|
||
|
||
case LOG_Debug:
|
||
return "D";
|
||
|
||
case LOG_Warn:
|
||
return "W";
|
||
|
||
case LOG_Error:
|
||
return "E";
|
||
|
||
case LOG_Fatal:
|
||
return "F";
|
||
|
||
case LOG_Unknown:
|
||
return "U";
|
||
|
||
default:
|
||
return "U";
|
||
}
|
||
|
||
return "U";
|
||
}
|
||
|
||
/**
|
||
* @brief 设置调试等级
|
||
* @param level 调试等级
|
||
* @param iEnable 1 打开调试等级, 0 关闭调试等级
|
||
*/
|
||
void HD_EnableLogLevel(LOG_LEVEL level, int iEnable)
|
||
{
|
||
if(iEnable > 0)
|
||
{
|
||
g_iMinLevel |= level;
|
||
}
|
||
else
|
||
{
|
||
g_iMinLevel &= ~(level);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 格式化 Log,添加 Log附加信息
|
||
* @details 在 Log 中加入日期时间,调试等级等附加信息
|
||
* @param cFlag 调试信息开关
|
||
* @param pMsg 调试信息内容
|
||
* @param dt Log 输出的时间
|
||
*/
|
||
static void HD_LinuxPrintf(LOG_LEVEL level, struct tm* dt, const char* pMsg)
|
||
{
|
||
char* pDebugMsg = (char*)kmalloc(strlen(pMsg) + 64, GFP_KERNEL);
|
||
|
||
if(pDebugMsg == NULL)
|
||
{
|
||
printk("Log Malloc Memory Error\n");
|
||
printk("%s", pMsg);
|
||
return;
|
||
}
|
||
|
||
sprintf(pDebugMsg, "[%02d:%02d:%02d:%03d] [%s] %s",
|
||
dt->tm_hour, dt->tm_min, dt->tm_sec, dt->tm_yday,
|
||
LogLevelToStr(level), pMsg);
|
||
|
||
printk(pDebugMsg);
|
||
|
||
kfree(pDebugMsg);
|
||
}
|
||
|
||
/**
|
||
* @brief 输出调试信息
|
||
* @details 根据 \a cFlag 的等级输出调试信息 \a pMsg
|
||
* @param cFlag 调试信息开关
|
||
* @param pMsg 调试信息内容
|
||
*/
|
||
static void HD_PRINTF(LOG_LEVEL level, const char* pMsg)
|
||
{
|
||
struct timeval tv;
|
||
struct tm wtm;
|
||
|
||
do_gettimeofday(&tv);
|
||
|
||
time_to_tm(tv.tv_sec, 0, &wtm);
|
||
wtm.tm_yday = tv.tv_usec / 1000;
|
||
|
||
HD_LinuxPrintf(level, &wtm, pMsg);
|
||
}
|
||
|
||
/**
|
||
* @brief 输出调试信息
|
||
* @param cFlag 调试信息开关
|
||
* @param pMsg 调试信息内容
|
||
*/
|
||
void HD_LOG(LOG_LEVEL level, const char* pMsg, ...)
|
||
{
|
||
__builtin_va_list arg_ptr;
|
||
int iMsgLen = 0;
|
||
char buf[512];
|
||
char* pMsgBuf = NULL;
|
||
|
||
// 检查调试等级
|
||
if(!(g_iMinLevel & level))
|
||
{
|
||
return;
|
||
}
|
||
|
||
memset(buf, 0, sizeof(buf));
|
||
|
||
va_start(arg_ptr, pMsg);
|
||
iMsgLen = __builtin_vsnprintf(buf, sizeof(buf), pMsg, arg_ptr);
|
||
va_end(arg_ptr);
|
||
|
||
if(iMsgLen > sizeof(buf))
|
||
{
|
||
pMsgBuf = (char*)kmalloc(iMsgLen + 1, GFP_KERNEL);
|
||
|
||
if(pMsgBuf == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
va_start(arg_ptr, pMsg);
|
||
iMsgLen = __builtin_vsnprintf(pMsgBuf, iMsgLen + 1, pMsg, arg_ptr);
|
||
va_end(arg_ptr);
|
||
HD_PRINTF(level, pMsgBuf);
|
||
kfree(pMsgBuf);
|
||
}
|
||
else
|
||
{
|
||
HD_PRINTF(level, buf);
|
||
}
|
||
}
|