diff --git a/include/HDLog.h b/include/HDLog.h index c94906e..52b8c8b 100644 --- a/include/HDLog.h +++ b/include/HDLog.h @@ -10,8 +10,9 @@ #define USE_HD_LOG_DEBUG 1 #define USE_HD_LOG_ERROR 1 #define USE_HD_LOG_DATA 1 +#define USE_HD_TRACE 1 +#define USE_HD_FPGA_CHECK 1 #endif -#define USE_HD_TRACE 0 // 当前检查栈数量的线程总数 #define USE_CHECK_STACK_NUM (1) @@ -22,8 +23,10 @@ #define _LogDLevel(level, format, ...) HDLogOut(0, level, __FILE__, __func__, __LINE__, format, ##__VA_ARGS__) #if USE_HD_TRACE -#define LogTrace() LogD() +#define LogTr(format, ...) _LogDLevel(kLogLevelTrace, format, ##__VA_ARGS__) +#define LogTrace() LogTr() #else +#define LogTr(format, ...) #define LogTrace() #endif @@ -45,7 +48,7 @@ #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 LogFpgaData(data, len, isWrite) do { if (HDLogPrintFpgaHeader((const uint8_t *)data, len, isWrite, 1)) { 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) @@ -61,6 +64,7 @@ enum eLogLevel { kLogLevelError, ///< 错误信息 kLogLevelHex, ///< 十六进制日志 kLogLevelStack, ///< 打印栈大小信息 + kLogLevelTrace, ///< trace级别日志 kLogLevelMax, }; @@ -79,9 +83,10 @@ void HDLogOut(uint8_t ext, uint8_t level, const char *fileName, const char *func * @param data FPGA头数据 * @param len 数据长度 * @param isWrite 是否是写 + * @param checkFpga 是否更新检查FPGA数据 * @return 是fpga数据或者需要打印返回1 否则返回0 */ -uint8_t HDLogPrintFpgaHeader(const uint8_t *data, int len, uint8_t isWrite); +uint8_t HDLogPrintFpgaHeader(const uint8_t *data, int len, uint8_t isWrite, uint8_t checkFpga); /** * @brief 十六进制格式打印数据 diff --git a/include/HShellLex.h b/include/HShellLex.h index 7121fa3..87598c0 100644 --- a/include/HShellLex.h +++ b/include/HShellLex.h @@ -46,6 +46,7 @@ typedef uint8_t HShellLenType; ///< 回调参数固定格式 #define HSHELL_FUNC_ARGS HShellLenType key, const HShellCmdToken *tokens, int tokensLen +#define HSHELL_FUNC_ARGS_DATA key, tokens, tokensLen ///< 命令行参数, 需要使用上面的宏的同名参数 #define HSHELL_ARGS_GET_UINT(index, result) \ @@ -59,7 +60,7 @@ typedef struct __attribute__ ((__packed__)) HShellCmdToken } HShellCmdToken; // 匹配映射表初始化每项的辅助宏 -#define HSHELL_MATCH_ITEM(token, str) {token, sizeof(str) - 1, (const uint8_t *)str} +#define HSHELL_MATCH_ITEM(token, str) {(token), sizeof(str) - 1, (const uint8_t *)str} ///< 匹配映射表 typedef struct __attribute__ ((__packed__)) HShellMatch diff --git a/src/HDLog.c b/src/HDLog.c index 042e1d0..4efb956 100644 --- a/src/HDLog.c +++ b/src/HDLog.c @@ -6,7 +6,6 @@ #include #include #include -#include #include typedef struct HDLogStackCheckInfo @@ -17,6 +16,24 @@ typedef struct HDLogStackCheckInfo unsigned long taskID; ///< 任务ID } HDLogStackCheckInfo; +#if USE_HD_FPGA_CHECK +enum eFpgaSendType { + kFpgaSendTypeControl = 0x01, ///< 控制段 + kFpgaSendTypeSend = 0x02, ///< 发送段 + kFpgaSendTypeFeedBack = 0x03, ///< 反馈段 +}; +typedef struct HDLogFpgaCheckInfo +{ + uint32_t sendCount; ///< 发送次数 + uint32_t recvCount; ///< 接收次数 + uint32_t sendError; ///< 发送错误次数 + uint32_t recvError; ///< 接收错误次数 + uint32_t sendTypeCount[3]; ///< 发送类型次数 + uint32_t readTypeCount[3]; ///< 接收类型次数 +} HDLogFpgaCheckInfo; +#define CHECK_FPGA_INFO_ID (100) +#endif + static HShellMatch sLogMatch[] = { HSHELL_MATCH_ITEM(kLogLevelSwitch, "log"), HSHELL_MATCH_ITEM(kLogLevelColor, "logColor"), @@ -24,6 +41,10 @@ static HShellMatch sLogMatch[] = { HSHELL_MATCH_ITEM(kLogLevelError, "logError"), HSHELL_MATCH_ITEM(kLogLevelHex, "logHex"), HSHELL_MATCH_ITEM(kLogLevelStack, "logStack"), +#if USE_HD_FPGA_CHECK + HSHELL_MATCH_ITEM(CHECK_FPGA_INFO_ID, "checkFpga"), + HSHELL_MATCH_ITEM(CHECK_FPGA_INFO_ID + 1, "clearCheckFpga"), +#endif }; static HBIT_DEFINE(sLogItem, kLogLevelMax); @@ -32,12 +53,55 @@ static HDLogGetTaskType_t sGetCurrTask = NULL; static HDLogGetStackSizeType_t sGetCurrStackSize = NULL; static HDLogStackCheckInfo sStackCheckInfo[USE_CHECK_STACK_NUM]; +#if USE_HD_FPGA_CHECK +static HDLogFpgaCheckInfo sFpgaCheckInfo; +#define FPGA_TYPE_INDEX(index, maxValue) ((index) > (maxValue) ? (maxValue) : (index)) +static uint32_t *GetFpgaType(uint8_t type, uint8_t isWrite) +{ + if (isWrite) + { + // 异常段返回最后一个记录 + if (type != kFpgaSendTypeControl && type != kFpgaSendTypeSend) + { + return &sFpgaCheckInfo.sendTypeCount[2]; + } + + return &sFpgaCheckInfo.sendTypeCount[type - 1]; + } + + switch (type) { + case kFpgaSendTypeControl: + return &sFpgaCheckInfo.readTypeCount[0]; + case kFpgaSendTypeFeedBack: + return &sFpgaCheckInfo.readTypeCount[1]; + default: + break; + } + + return &sFpgaCheckInfo.readTypeCount[2]; +} +#endif + static void LogShell(HSHELL_FUNC_ARGS) { uint32_t arg1 = 0; // 可以不用检查参数, 如果未输入就默认关闭 HSHellToUint32(tokens, tokensLen, 1, &arg1); +#if USE_HD_FPGA_CHECK + switch (key) + { + case CHECK_FPGA_INFO_ID: + HSHELL_PRINTFL("sendCount[%u], recvCount[%u], sendError[%u], recvError[%u]", sFpgaCheckInfo.sendCount, sFpgaCheckInfo.recvCount, sFpgaCheckInfo.sendError, sFpgaCheckInfo.recvError); + HSHELL_PRINTFL("Send Control Type[%u], Send Type[%u], error Type[%u]", *GetFpgaType(kFpgaSendTypeControl, 1), *GetFpgaType(kFpgaSendTypeSend, 1), *GetFpgaType(100, 1)); + HSHELL_PRINTFL("Read Control Type[%u], FeedBack Type[%u], error Type[%u]", *GetFpgaType(kFpgaSendTypeControl, 0), *GetFpgaType(kFpgaSendTypeFeedBack, 0), *GetFpgaType(100, 0)); + return ; + case (CHECK_FPGA_INFO_ID + 1): + memset(&sFpgaCheckInfo, 0, sizeof(sFpgaCheckInfo)); + return ; + } +#endif + uint8_t lastStatus = HBitGet(sLogItem, key); HBitSet(sLogItem, key, arg1); HSHELL_PRINTFL("logStatus[%d]->[%d]", lastStatus, HBitGet(sLogItem, key)); @@ -50,6 +114,7 @@ void HDLogInit(uint32_t (*getTime)()) HBitSet(sLogItem, kLogLevelSwitch, 1); HBitSet(sLogItem, kLogLevelDebug, 1); HBitSet(sLogItem, kLogLevelError, 1); + HBitSet(sLogItem, kLogLevelHex, 0); HBitSet(sLogItem, kLogLevelStack, 1); } @@ -138,33 +203,65 @@ void HDLogOut(uint8_t ext, uint8_t level, const char *fileName, const char *func } } -uint8_t HDLogPrintFpgaHeader(const uint8_t *data, int len, uint8_t isWrite) +static uint8_t HDLogFpgaError(const uint8_t *data, int len, uint8_t isWrite, uint8_t checkFpga) +{ + if (checkFpga == 0) + { + return 0; + } + +#if USE_HD_FPGA_CHECK + if (isWrite) + { + ++sFpgaCheckInfo.sendError; + } + else + { + ++sFpgaCheckInfo.recvError; + } +#endif + + const char *opt = isWrite ? "write" : "read"; + printf("%s fpga error, len[%d]\r\n", opt, len); + HDLogHex((const uint8_t *)(data), len, 1, NULL); + + return 1; +} + +uint8_t HDLogPrintFpgaHeader(const uint8_t *data, int len, uint8_t isWrite, uint8_t checkFpga) { if (HBitGet(sLogItem, kLogLevelHex) == 0) { return 0; } + // 记录打印时间 + if (sGetTime) + { + uint32_t ms = sGetTime(); + printf("[%d:%02d:%02d.%03d]\r\n", ms / 1000 / 60 / 60, ms / 1000 / 60 % 60, ms / 1000 % 60, ms % 1000); + } + if (len <= 21) { - return 0; + return HDLogFpgaError(data, len, isWrite, checkFpga); } for (uint8_t i = 0; i < 7; ++i) { if (0x55 != data[i]) { - return 0; + return HDLogFpgaError(data, len, isWrite, checkFpga); } } if (0xd5 != data[7]) { - return 0; + return HDLogFpgaError(data, len, isWrite, checkFpga); } uint8_t type = data[8]; - uint8_t phy = (data[9] >> 3) & 0x1F; + uint8_t sendCard = (data[9] >> 3) & 0x1F; uint8_t port = data[9]; uint8_t recvCardNumber = data[10]; uint16_t subFunc = (uint16_t)((data[11] << 8) | data[12]); @@ -172,16 +269,33 @@ uint8_t HDLogPrintFpgaHeader(const uint8_t *data, int len, uint8_t isWrite) uint16_t effectLen = (uint16_t)((data[15] << 8) | data[16]); if (effectLen < 16) { - return 0; + return HDLogFpgaError(data, len, isWrite, checkFpga); } if (len < 21 + effectLen) { - return 0; + return HDLogFpgaError(data, len, isWrite, checkFpga); } + uint32_t count = 0; + uint32_t typeCount = 0; +#if USE_HD_FPGA_CHECK + ++(*GetFpgaType(type, isWrite)); + if (isWrite) + { + ++sFpgaCheckInfo.sendCount; + count = sFpgaCheckInfo.sendCount; + } + else + { + ++sFpgaCheckInfo.recvCount; + count = sFpgaCheckInfo.recvCount; + } + typeCount = *GetFpgaType(type, isWrite); +#endif + 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); + printf("%s[%u], typeCount[%u] - type[%02X], sendCard[%d], netPort[%d], cardNumber[%d], subFunc[%04X], group[%04X], effectLen[%d]\r\n", opt, count, typeCount, type, sendCard, port, recvCardNumber, subFunc, group, effectLen); return 1; } @@ -329,7 +443,7 @@ uint32_t HDLogDebugGetCurrStackSize() return 0; } - uint32_t currSize = abs(sStackCheckInfo[index].stackAddr - (unsigned long)&curr); + uint32_t currSize = sStackCheckInfo[index].stackAddr - (unsigned long)&curr; if (sGetCurrStackSize) { currSize = sGetCurrStackSize(sStackCheckInfo[index].taskID);