1. 增加日志打印方法
This commit is contained in:
parent
bbac687ce0
commit
c459363f3a
138
include/HDLog.h
Normal file
138
include/HDLog.h
Normal file
@ -0,0 +1,138 @@
|
||||
|
||||
|
||||
#ifndef __HD_NEW_LOG_H__
|
||||
#define __HD_NEW_LOG_H__
|
||||
|
||||
#include "sys/_intsup.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// 使用宏开关管理日志
|
||||
#ifndef LOG_CLOSE_OUT
|
||||
#define USE_HD_LOG_DEBUG 1
|
||||
#define USE_HD_LOG_ERROR 1
|
||||
#define USE_HD_LOG_DATA 1
|
||||
#endif
|
||||
#define USE_HD_TRACE 0
|
||||
|
||||
// 当前检查栈数量的线程总数
|
||||
#define USE_CHECK_STACK_NUM (1)
|
||||
|
||||
|
||||
// 标准日志输出
|
||||
#define _LogDExtLevel(level, format, ...) HDLogOut(1, level, __FILE__, __func__, __LINE__, format, ##__VA_ARGS__)
|
||||
#define _LogDLevel(level, format, ...) HDLogOut(0, level, __FILE__, __func__, __LINE__, format, ##__VA_ARGS__)
|
||||
|
||||
#if USE_HD_TRACE
|
||||
#define LogTrace() LogD()
|
||||
#else
|
||||
#define LogTrace()
|
||||
#endif
|
||||
|
||||
#if USE_HD_LOG_DEBUG
|
||||
#define LogD(format, ...) _LogDLevel(kLogLevelDebug, format, ##__VA_ARGS__)
|
||||
#define LogDExt(format, ...) _LogDExtLevel(kLogLevelDebug, format, ##__VA_ARGS__)
|
||||
#define LogLine() LogDExt("\r\n")
|
||||
#else
|
||||
#define LogD(...)
|
||||
#define LogDExt(...)
|
||||
#define LogLine()
|
||||
#endif
|
||||
|
||||
#if USE_HD_LOG_ERROR
|
||||
#define LogE(format, ...) _LogDLevel(0, kLogLevelError, __FILE__, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define LogE(...)
|
||||
#endif
|
||||
|
||||
#if USE_HD_LOG_DATA
|
||||
#define LogData(data, len) HDLogData((const uint8_t *)data, len, 1)
|
||||
#define LogFpgaData(data, len, isWrite) do { if (HDLogPrintFpgaHeader((const uint8_t *)data, len, isWrite)) { HDLogHex((const uint8_t *)(data) + 17, (len) - 21, 1, NULL); } } while (0)
|
||||
#define LogHexData(data, len) HDLogHex((const uint8_t *)data, len, 1, NULL)
|
||||
#else
|
||||
#define LogData(data, len)
|
||||
#define LogFpgaData(data, len, isWrite)
|
||||
#define LogHexData(data, len)
|
||||
#endif
|
||||
|
||||
|
||||
enum eLogLevel {
|
||||
kLogLevelSwitch = 0, ///< 日志开关
|
||||
kLogLevelColor, ///< 彩色日志
|
||||
kLogLevelDebug, ///< 常规调试信息
|
||||
kLogLevelError, ///< 错误信息
|
||||
kLogLevelHex, ///< 十六进制日志
|
||||
kLogLevelStack, ///< 打印栈大小信息
|
||||
kLogLevelMax,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 日志初始化
|
||||
*/
|
||||
void HDLogInit(uint32_t (*getTime)());
|
||||
|
||||
/**
|
||||
* @brief 格式打印
|
||||
**/
|
||||
void HDLogOut(uint8_t ext, uint8_t level, const char *fileName, const char *funcName, int line, const char *format, ...);
|
||||
|
||||
/**
|
||||
* @brief 打印FPGA头
|
||||
* @param data FPGA头数据
|
||||
* @param len 数据长度
|
||||
* @param isWrite 是否是写
|
||||
* @return 是fpga数据或者需要打印返回1 否则返回0
|
||||
*/
|
||||
uint8_t HDLogPrintFpgaHeader(const uint8_t *data, int len, uint8_t isWrite);
|
||||
|
||||
/**
|
||||
* @brief 十六进制格式打印数据
|
||||
* @param data 数据
|
||||
* @param len 数据长度
|
||||
* @param checkPrint 是否检查打印开关是否打开
|
||||
* @param offset 打印偏移, 一般传递 NULL 即可
|
||||
**/
|
||||
void HDLogHex(const uint8_t *data, int len, uint8_t checkPrint, uint32_t *offset);
|
||||
|
||||
/**
|
||||
* @brief 无格式以16进制打印数据, 打印16个换行
|
||||
* @param data 数据
|
||||
* @param len 数据长度
|
||||
* @param checkPrint 是否检查打印开关是否打开
|
||||
*/
|
||||
void HDLogData(const uint8_t *data, int len, uint8_t checkPrint);
|
||||
|
||||
|
||||
typedef unsigned long(*HDLogGetTaskType_t)();
|
||||
/**
|
||||
* @brief 设置获取当前任务的方法
|
||||
* @param getTask 获取当前任务, 如果非RTOS, 传递 NULL
|
||||
*/
|
||||
void HDLogDebugSetGetTask(HDLogGetTaskType_t getTask);
|
||||
|
||||
/**
|
||||
* @brief 设置当前任务的栈大小
|
||||
* @param currTask 当前任务, 如果非RTOS, 传递 NULL
|
||||
* @param size 栈大小
|
||||
*/
|
||||
void HDLogDebugInitStackAddr(unsigned long currTask, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief 删除当前任务的栈大小记录
|
||||
* @param currTask 当前任务
|
||||
*/
|
||||
void HDLogDebugDeleteStackAddr(unsigned long currTask);
|
||||
|
||||
/**
|
||||
* @brief 获取当前任务的栈大小
|
||||
* @return 当前栈使用大小
|
||||
*/
|
||||
uint32_t HDLogDebugGetCurrStackSize();
|
||||
|
||||
typedef uint32_t(*HDLogGetStackSizeType_t)(unsigned long currTask);
|
||||
/**
|
||||
* @brief 设置获取当前任务的栈大小方法
|
||||
* @param getStackSize 获取当前任务的栈大小
|
||||
*/
|
||||
void HDLogSetGetCurrStackSizeCall(HDLogGetStackSizeType_t getStackSize);
|
||||
|
||||
#endif // __HD_NEW_LOG_H__
|
||||
349
src/HDLog.c
Normal file
349
src/HDLog.c
Normal file
@ -0,0 +1,349 @@
|
||||
|
||||
|
||||
#include "HDLog.h"
|
||||
#include "HBit.h"
|
||||
#include "HShellLex.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct HDLogStackCheckInfo
|
||||
{
|
||||
uint32_t enable : 1; ///< 是否使用
|
||||
uint32_t stackSize : 31; ///< 栈大小
|
||||
unsigned long stackAddr; ///< 栈开始地址, 可能误差多字节
|
||||
unsigned long taskID; ///< 任务ID
|
||||
} HDLogStackCheckInfo;
|
||||
|
||||
static HShellMatch sLogMatch[] = {
|
||||
HSHELL_MATCH_ITEM(kLogLevelSwitch, "log"),
|
||||
HSHELL_MATCH_ITEM(kLogLevelColor, "logColor"),
|
||||
HSHELL_MATCH_ITEM(kLogLevelDebug, "logDebug"),
|
||||
HSHELL_MATCH_ITEM(kLogLevelError, "logError"),
|
||||
HSHELL_MATCH_ITEM(kLogLevelHex, "logHex"),
|
||||
HSHELL_MATCH_ITEM(kLogLevelStack, "logStack"),
|
||||
};
|
||||
|
||||
static HBIT_DEFINE(sLogItem, kLogLevelMax);
|
||||
static uint32_t (*sGetTime)() = NULL;
|
||||
static HDLogGetTaskType_t sGetCurrTask = NULL;
|
||||
static HDLogGetStackSizeType_t sGetCurrStackSize = NULL;
|
||||
static HDLogStackCheckInfo sStackCheckInfo[USE_CHECK_STACK_NUM];
|
||||
|
||||
|
||||
static void LogShell(HSHELL_FUNC_ARGS)
|
||||
{
|
||||
uint32_t arg1 = 0;
|
||||
// 可以不用检查参数, 如果未输入就默认关闭
|
||||
HSHellToUint32(tokens, tokensLen, 1, &arg1);
|
||||
uint8_t lastStatus = HBitGet(sLogItem, key);
|
||||
HBitSet(sLogItem, key, arg1);
|
||||
HSHELL_PRINTFL("logStatus[%d]->[%d]", lastStatus, HBitGet(sLogItem, key));
|
||||
}
|
||||
|
||||
void HDLogInit(uint32_t (*getTime)())
|
||||
{
|
||||
sGetTime = getTime;
|
||||
HSHellRegister(sLogMatch, sizeof(sLogMatch) / sizeof(HShellMatch), LogShell, 1);
|
||||
HBitSet(sLogItem, kLogLevelSwitch, 1);
|
||||
HBitSet(sLogItem, kLogLevelDebug, 1);
|
||||
HBitSet(sLogItem, kLogLevelError, 1);
|
||||
HBitSet(sLogItem, kLogLevelStack, 1);
|
||||
}
|
||||
|
||||
void HDLogOut(uint8_t ext, uint8_t level, const char *fileName, const char *funcName, int line, const char *format, ...)
|
||||
{
|
||||
if (HBitGet(sLogItem, kLogLevelSwitch) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (HBitGet(sLogItem, level) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
const char *name = strrchr(fileName, '/');
|
||||
if (name)
|
||||
{
|
||||
fileName = name + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 日志颜色
|
||||
#define _LOG_COLOR_RED "\033[1;31m"
|
||||
#define _LOG_COLOR_GREEN "\033[1;32m"
|
||||
#define _LOG_COLOR_YELLOW "\033[1;33m"
|
||||
#define _LOG_COLOR_BLUE "\033[1;34m"
|
||||
#define _LOG_COLOR_PURPLE "\033[1;35m"
|
||||
#define _LOG_COLOR_CYAN "\033[1;36m"
|
||||
#define _LOG_COLOR_END "\033[0m"
|
||||
|
||||
// 日志前缀基础信息, 文件名, 函数名, 行号
|
||||
#define _LOG_BASE_ARGS _BASENAME(__FILE__), __func__, __LINE__
|
||||
#define _LOG_BASE_INFO "[%s:%s:%d]"
|
||||
#define _LOG_BASE_INFO_COLOR "[" _LOG_COLOR_BLUE \
|
||||
"%s:%s:" _LOG_COLOR_PURPLE \
|
||||
"%d" _LOG_COLOR_END \
|
||||
"]"
|
||||
|
||||
uint8_t color = HBitGet(sLogItem, kLogLevelColor);
|
||||
if (ext == 0)
|
||||
{
|
||||
if (sGetTime)
|
||||
{
|
||||
uint32_t ms = sGetTime();
|
||||
printf("[%d:%02d:%02d.%03d]", ms / 1000 / 60 / 60, ms / 1000 / 60 % 60, ms / 1000 % 60, ms % 1000);
|
||||
}
|
||||
|
||||
if (color)
|
||||
{
|
||||
printf(_LOG_BASE_INFO_COLOR, fileName, funcName, line);
|
||||
printf(_LOG_COLOR_CYAN);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(_LOG_BASE_INFO, fileName, funcName, line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (color)
|
||||
{
|
||||
printf(_LOG_COLOR_CYAN);
|
||||
}
|
||||
}
|
||||
|
||||
if (HBitGet(sLogItem, kLogLevelStack))
|
||||
{
|
||||
printf("[0x%04X]", HDLogDebugGetCurrStackSize());
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
|
||||
if (color)
|
||||
{
|
||||
printf(_LOG_COLOR_END);
|
||||
}
|
||||
|
||||
if (ext == 0)
|
||||
{
|
||||
printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t HDLogPrintFpgaHeader(const uint8_t *data, int len, uint8_t isWrite)
|
||||
{
|
||||
if (HBitGet(sLogItem, kLogLevelHex) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len <= 21)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 7; ++i)
|
||||
{
|
||||
if (0x55 != data[i])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (0xd5 != data[7])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t type = data[8];
|
||||
uint8_t phy = (data[9] >> 3) & 0x1F;
|
||||
uint8_t port = data[9];
|
||||
uint8_t recvCardNumber = data[10];
|
||||
uint16_t subFunc = (uint16_t)((data[11] << 8) | data[12]);
|
||||
uint16_t group = (uint16_t)((data[13] << 8) | data[14]);
|
||||
uint16_t effectLen = (uint16_t)((data[15] << 8) | data[16]);
|
||||
if (effectLen < 16)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len < 21 + effectLen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *opt = isWrite ? "write" : "read";
|
||||
printf("%s - type[%02X], phy[%d], port[%d], cardNumber[%d], subFunc[%04X], group[%04X], effectLen[%d]\r\n", opt, type, phy, port, recvCardNumber, subFunc, group, effectLen);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void HDLogHex(const uint8_t *data, int len, uint8_t checkPrint, uint32_t *offset)
|
||||
{
|
||||
if (checkPrint && HBitGet(sLogItem, kLogLevelHex) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (len <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#define PRINT_HEX(...) printf(__VA_ARGS__);
|
||||
|
||||
if (offset == NULL || *offset == 0)
|
||||
{
|
||||
PRINT_HEX(" ");
|
||||
// 16进制打印, 打印15个换行, 开头打印0A-0F 开头样式, 数据列每行00-FF
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
PRINT_HEX("0%X ", i);
|
||||
}
|
||||
|
||||
PRINT_HEX("\r\n");
|
||||
for (int i = 0; i < 17; ++i)
|
||||
{
|
||||
PRINT_HEX("---");
|
||||
;
|
||||
}
|
||||
|
||||
PRINT_HEX("\r\n");
|
||||
}
|
||||
|
||||
int index = offset ? *offset : 0;
|
||||
for (int i = 0; i < len; ++i, ++index)
|
||||
{
|
||||
if (index % 16 == 0)
|
||||
{
|
||||
PRINT_HEX("%X%X| ", index / 256, index / 16 % 16);
|
||||
}
|
||||
|
||||
PRINT_HEX("%02X ", data[i]);
|
||||
if (index % 16 == 15)
|
||||
{
|
||||
PRINT_HEX("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (offset)
|
||||
{
|
||||
*offset = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT_HEX("\r\n");
|
||||
}
|
||||
#undef PRINT_HEX
|
||||
}
|
||||
|
||||
void HDLogData(const uint8_t *data, int len, uint8_t checkPrint)
|
||||
{
|
||||
if (checkPrint && HBitGet(sLogItem, kLogLevelHex) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
printf("%02X ", data[i]);
|
||||
if (i % 16 == 15)
|
||||
{
|
||||
printf("\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int16_t HDLogGetIndex(unsigned long id)
|
||||
{
|
||||
unsigned taskId = id;
|
||||
if (taskId == 0 && sGetCurrTask)
|
||||
{
|
||||
taskId = sGetCurrTask();
|
||||
}
|
||||
|
||||
int16_t index = -1;
|
||||
for (int16_t i = 0; i < USE_CHECK_STACK_NUM; ++i)
|
||||
{
|
||||
if (index == -1 && sStackCheckInfo[i].enable)
|
||||
{
|
||||
index = i;
|
||||
}
|
||||
|
||||
if (sStackCheckInfo[i].enable && sStackCheckInfo[i].taskID == taskId)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void HDLogDebugSetGetTask(HDLogGetTaskType_t getTask)
|
||||
{
|
||||
sGetCurrTask = getTask;
|
||||
}
|
||||
|
||||
void HDLogDebugInitStackAddr(unsigned long currTask, uint32_t size)
|
||||
{
|
||||
void *start = 0;
|
||||
for (int i = 0; i < USE_CHECK_STACK_NUM; ++i)
|
||||
{
|
||||
if (sStackCheckInfo[i].enable)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sStackCheckInfo[i].enable = 1;
|
||||
sStackCheckInfo[i].stackAddr = (unsigned long)&start - sizeof(void *);
|
||||
sStackCheckInfo[i].stackSize = size;
|
||||
sStackCheckInfo[i].taskID = currTask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void HDLogDebugDeleteStackAddr(unsigned long currTask)
|
||||
{
|
||||
int16_t index = HDLogGetIndex(currTask);
|
||||
if (index != -1)
|
||||
{
|
||||
memset(&sStackCheckInfo[index], 0, sizeof(HDLogStackCheckInfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t HDLogDebugGetCurrStackSize()
|
||||
{
|
||||
void *curr = NULL;
|
||||
int16_t index = HDLogGetIndex(NULL);
|
||||
if (index == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t currSize = abs(sStackCheckInfo[index].stackAddr - (unsigned long)&curr);
|
||||
if (sGetCurrStackSize)
|
||||
{
|
||||
currSize = sGetCurrStackSize(sStackCheckInfo[index].taskID);
|
||||
}
|
||||
|
||||
if (sStackCheckInfo[index].stackSize < currSize + 0x100)
|
||||
{
|
||||
printf("The current stack[%d] is insufficient, size[%d], taskId[%lx]\r\n", currSize, sStackCheckInfo[index].stackSize, sStackCheckInfo[index].taskID);
|
||||
}
|
||||
|
||||
return currSize;
|
||||
}
|
||||
|
||||
void HDLogSetGetCurrStackSizeCall(HDLogGetStackSizeType_t getStackSize)
|
||||
{
|
||||
sGetCurrStackSize = getStackSize;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user