栈整改不抬栈:删旧档迁移、FIL静态化、日志行缓冲按模块收紧、钩子脱离HAL,defaultTask链5312→2776B
This commit is contained in:
@@ -24,7 +24,12 @@
|
||||
|
||||
/*
|
||||
* 调试输出配置
|
||||
* 深调用链模块(ch395f_spi_fault_set 等出现在 netTask/ftpTask/timeSyncTask
|
||||
* 最坏链尾部):日志行缓冲收到 128 B(默认 192)。本模块最长行
|
||||
* "HAL_SPI_TransmitReceive_DMA FAIL: %d, SPI_State=%d, SPI_Error=0x%lX, DMA_State=%d"
|
||||
* 渲染后 ≈ 102 B(含时间戳 21 + 标签)< 128 → 不截断
|
||||
*/
|
||||
#define DBG_LINE_BUF_MAX 128U
|
||||
#define DBG_TAG "[CH395]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
|
||||
/*
|
||||
* 调试输出配置
|
||||
* 深调用链模块(NAND 驱动在 FTL 之下):日志行缓冲收到 128 B(默认 192)。
|
||||
* 本模块最长行 "ID mismatch: expected MID=0x.. DID=0x.., got MID=0x.. DID=0x.."
|
||||
* 渲染后 ≈ 103 B(含时间戳 21 + 标签)< 128 → 不截断
|
||||
*/
|
||||
#define DBG_LINE_BUF_MAX 128U
|
||||
#define DBG_TAG "[NAND]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
#define FTL_FATFS_OFFSET 0U
|
||||
|
||||
/* 调试输出配置 */
|
||||
/* 深调用链模块(FatFS → 本 FTL → dhara → NAND 是 defaultTask 最坏链的主干):
|
||||
* 日志行缓冲收到 128 B(默认 192)。本模块最长行 "[2026-10-10 08:00:00][ERR][NAND_FTL]
|
||||
* Cache flush failed: LPN=4294967295 err=-2147483648" ≈ 84 B < 128 → 不截断。
|
||||
* 核算 scripts/stack_report.py,见 docs/内存管理/RAM使用分析与优化方案.md */
|
||||
#define DBG_LINE_BUF_MAX 128U
|
||||
#define DBG_TAG "[NAND_FTL]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
|
||||
@@ -25,7 +25,11 @@
|
||||
|
||||
/*
|
||||
* 调试输出配置
|
||||
* 深调用链模块(net_bind/net_send/net_poll 是 netTask/ftpTask/timeSyncTask
|
||||
* 最坏链的主干):日志行缓冲收到 128 B(默认 192)。本模块最长行渲染后
|
||||
* ≈ 100 B(含时间戳 21 + 标签)< 128 → 不截断
|
||||
*/
|
||||
#define DBG_LINE_BUF_MAX 128U
|
||||
#define DBG_TAG "[NET]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Drivers/BSP/NETCFG/ — 网络配置
|
||||
|
||||
> 网络参数的**加载 / 保存 / 旧档迁移**(IP、掩码、网关等)。
|
||||
> 网络参数的**加载 / 保存**(IP、掩码、网关等)。
|
||||
> 本模块是**网络配置的持久化层**,与 `App/cfg/cfg_file.c`(配置引擎)配合工作。
|
||||
|
||||
## 文件一览
|
||||
@@ -8,12 +8,17 @@
|
||||
| 文件 | 作用 |
|
||||
|---|---|
|
||||
| `net_cfg.c/h` | 网络配置加载(`net_cfg_load`)/ 保存(`net_cfg_save_run`)+ RAM 副本管理 |
|
||||
| `net_cfg_legacy.c/h` | **旧版配置档迁移**(首启时把旧格式转换为当前格式) |
|
||||
|
||||
> **已删除(2026-10-10)**:`net_cfg_legacy.c/h`——旧二进制档 `/cfg/netcfg.bin` 的"首启自动迁移"。
|
||||
> 现口径:旧档若存在则被**忽略**(不读、不删、不迁移),配置直接回落工厂默认(`/config.ini`
|
||||
> `[network]` 段)。删除理由:该一次性路径把整条配置写链(`net_cfg_save → cfg_file_save →
|
||||
> cfg_store_write_atomic → f_rename → FatFS → dhara FTL`)挂进启动期调用图,使 defaultTask 的
|
||||
> armlink 静态最坏栈链 +600 B,而本仓库不存在携带旧档的设备。
|
||||
|
||||
## 工作流
|
||||
|
||||
```
|
||||
defaultTask:net_cfg_load(含旧档迁移)→ 置 STORAGE_READY
|
||||
defaultTask:net_cfg_load → 置 STORAGE_READY
|
||||
↓ (网络配置在屏障前已加载)
|
||||
netTask:只读 RAM 副本 → net_stack_bring_up(不在 netTask 里读盘)
|
||||
↓
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* 模块名称:Network Configuration Core (配置核心)
|
||||
* 模块功能:RAM 配置副本 + 工厂默认 + 加载/保存编排 + 实际 MAC 影子 +
|
||||
* IPv4 字符串转换;存储经 cfg_file 通用配置文件引擎(INI [network]
|
||||
* 段:ip/mask/gw/mac);旧版 NCFG 二进制格式归 net_cfg_legacy
|
||||
* (首启一次性迁移)
|
||||
* 段:ip/mask/gw/mac)
|
||||
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-09-10
|
||||
@@ -12,6 +11,12 @@
|
||||
* v1.1 2026-09-14 王建锋 存储迁移至 cfg_file 引擎(INI);旧 NCFG 代码移至 net_cfg_legacy
|
||||
* v1.2 2026-09-15 王建锋 保存改跨任务交接(request/state/run + 通知回调);
|
||||
* 引擎属主 = defaultTask(P1-3 竞态修复)
|
||||
* v1.3 2026-10-10 王建锋 **删除旧档 NCFG 迁移**(net_cfg_legacy 整体移除):该兼容
|
||||
* 路径把整条配置写链(net_cfg_save → cfg_file_save →
|
||||
* cfg_store_write_atomic → f_rename → FTL)挂进启动期调用图,
|
||||
* 使 defaultTask 静态最坏链 +600 B;本仓库无携带
|
||||
* /cfg/netcfg.bin 的设备,故按"不保留旧档兼容"处置。
|
||||
* 旧档若存在 → 被忽略(不读、不删、不迁移),配置回落工厂默认
|
||||
*/
|
||||
|
||||
/* 头文件包含区 */
|
||||
@@ -23,10 +28,11 @@
|
||||
|
||||
#include "net_cfg.h"
|
||||
|
||||
#include "net_cfg_legacy.h"
|
||||
|
||||
#include "cfg_file.h"
|
||||
|
||||
/* 深调用链模块(net_cfg_load/save 在 defaultTask 启动链与保存链上):
|
||||
* 日志行缓冲收到 128 B(默认 192),本模块最长行渲染后 < 128 → 不截断 */
|
||||
#define DBG_LINE_BUF_MAX 128U
|
||||
#define DBG_TAG "[NET_CFG]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
@@ -140,9 +146,8 @@ static bool s_mac_is_zero(const uint8_t *p_mac) {
|
||||
int net_cfg_load(void) {
|
||||
s_net_register();
|
||||
|
||||
/* 首启先迁旧档 NCFG(有效 → 旧值物化进新文件);新文件已存在则跳过 */
|
||||
(void)net_cfg_legacy_migrate();
|
||||
|
||||
/* 旧档 NCFG 迁移已于 2026-10-10 删除(net_cfg_legacy 移除;理由见文件头 v1.3)。
|
||||
* 若卷上仍残留 /cfg/netcfg.bin:不读、不删、不迁移 → 配置回落工厂默认 */
|
||||
if (cfg_file_load() != 0) {
|
||||
/* 严重错误:引擎已将 RAM 副本复位工厂默认,行为仍安全 */
|
||||
DBG_ERROR("load: cfg_file_load FAIL");
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
* = 不覆盖芯片内置 MAC。cfg_file 引擎为静态单任务设计,调用收敛于
|
||||
* 单一属主任务(MCU = defaultTask:就绪屏障前加载 / 保存执行 / 2s
|
||||
* poll;模拟器 = 主循环);UI 保存只投递请求,netTask 只读 RAM 副本
|
||||
* 函数说明:旧版 NCFG 二进制格式(magic+ver+CRC-16+18B 字段)归 net_cfg_legacy,
|
||||
* 首启一次性迁移进通用配置文件
|
||||
* 函数说明:旧版 NCFG 二进制格式(magic+ver+CRC-16+18B 字段)的迁移路径
|
||||
* (net_cfg_legacy)**已于 2026-10-10 删除** → 旧档 /cfg/netcfg.bin
|
||||
* 不再读取/迁移,携带旧档的设备升级后回落工厂默认(理由见 net_cfg.c v1.3)
|
||||
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-09-10
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* 模块名称:net_cfg_legacy
|
||||
* 模块功能:旧版 NCFG 二进制配置一次性迁移——读遗留文件 → 校验 magic/ver/CRC →
|
||||
* 填网络配置 RAM 副本 → 经 cfg_file 引擎生成新文件(带旧值)→ 删旧文件
|
||||
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用;平台路径经 cfg_file_store 后端)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-09-14
|
||||
* 修改记录:
|
||||
* v1.0 2026-09-14 王建锋 创建初始版本(P3:net_cfg 引擎化,旧格式代码迁入)
|
||||
*/
|
||||
|
||||
/* 头文件包含区 */
|
||||
#include <string.h>
|
||||
|
||||
#include "net_cfg_legacy.h"
|
||||
|
||||
#include "net_cfg.h"
|
||||
|
||||
#include "cfg_file.h"
|
||||
|
||||
#include "cfg_file_store.h"
|
||||
|
||||
#define DBG_TAG "[NET_CFG]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
/* 常量定义区 */
|
||||
|
||||
#define NET_CFG_MAGIC 0x4647434Eu /* 'NCFG'(文件字节序 N,C,G,F;小端装载) */
|
||||
#define NET_CFG_VER 1u /* 磁盘格式版本 */
|
||||
|
||||
/* 旧磁盘格式(两端布局一致:u32 4 对齐;字段区 18B 连续,CRC 覆盖之) */
|
||||
typedef struct {
|
||||
uint32_t magic; /* NET_CFG_MAGIC */
|
||||
uint16_t ver; /* 格式版本 */
|
||||
uint16_t crc; /* CRC-16/MODBUS(覆盖 ip..mac 共 18B) */
|
||||
uint8_t ip[4];
|
||||
uint8_t mask[4];
|
||||
uint8_t gw[4];
|
||||
uint8_t mac[6];
|
||||
} net_cfg_blob_t;
|
||||
|
||||
/* 静态函数声明区 */
|
||||
static uint16_t s_crc16_modbus(const uint8_t *p_data, size_t len);
|
||||
|
||||
/* 函数定义区 */
|
||||
|
||||
/*
|
||||
* 函数功能:CRC-16/MODBUS(无查表逐位算法)
|
||||
* 入口参数:p_data - 数据指针 const uint8_t *
|
||||
* len - 数据长度 size_t
|
||||
* 返回值:CRC-16 值 uint16_t
|
||||
* 限定条件:p_data 非空(len 可为 0,返回初始值 0xFFFF)
|
||||
* 函数说明:文件私有(数据量 ≤32B,性能无关)
|
||||
*/
|
||||
static uint16_t s_crc16_modbus(const uint8_t *p_data, size_t len) {
|
||||
uint16_t crc = 0xFFFFu;
|
||||
|
||||
for (size_t i = 0u; i < len; i++) {
|
||||
crc = (uint16_t)(crc ^ (uint16_t)p_data[i]);
|
||||
for (int b = 0; b < 8; b++) {
|
||||
if (crc & 0x0001u) {
|
||||
crc = (uint16_t)((crc >> 1) ^ 0xA001u);
|
||||
}
|
||||
else {
|
||||
crc = (uint16_t)(crc >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:旧 NCFG 二进制配置一次性迁移到通用配置文件
|
||||
* 入口参数:无
|
||||
* 返回值:0 - 迁移成功,或无旧文件/新文件已存在(正常);-1 - 迁移失败 int
|
||||
* 限定条件:调用方须已注册 [network] 段(net_cfg_load 内部完成)
|
||||
* 函数说明:见 net_cfg_legacy.h 同名函数说明
|
||||
*/
|
||||
int net_cfg_legacy_migrate(void) {
|
||||
net_cfg_blob_t blob;
|
||||
uint8_t buf[32];
|
||||
size_t nread = 0u;
|
||||
cfg_file_stat_t st;
|
||||
net_cfg_t tmp;
|
||||
const char *p_legacy;
|
||||
|
||||
/* 新文件已存在 = 已迁移过(或已有配置):跳过 */
|
||||
if (cfg_store_stat(cfg_store_config_path(), &st) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_legacy = cfg_store_legacy_path();
|
||||
if (cfg_store_read(p_legacy, buf, sizeof(buf), &nread) != 0
|
||||
|| nread != sizeof(net_cfg_blob_t)) {
|
||||
DBG_INFO("legacy: no legacy file, skip");
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)memcpy(&blob, buf, sizeof(blob));
|
||||
if (blob.magic != NET_CFG_MAGIC || blob.ver != NET_CFG_VER
|
||||
|| s_crc16_modbus(blob.ip, 18u) != blob.crc) {
|
||||
DBG_INFO("legacy: blob invalid (magic/ver/crc), file kept for inspection");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 填 RAM 副本(net_cfg_get 只读,经 net_cfg_set 可写接口整体回灌)
|
||||
* → 经引擎物化旧值到新文件(此时新文件必缺失 → 生成模板带旧值) */
|
||||
(void)memcpy(&tmp, net_cfg_get(), sizeof(tmp));
|
||||
(void)memcpy(tmp.ip, blob.ip, 4u);
|
||||
(void)memcpy(tmp.mask, blob.mask, 4u);
|
||||
(void)memcpy(tmp.gw, blob.gw, 4u);
|
||||
(void)memcpy(tmp.mac, blob.mac, 6u);
|
||||
net_cfg_set(&tmp);
|
||||
|
||||
if (net_cfg_save() != 0) {
|
||||
DBG_ERROR("legacy: migrate save FAIL");
|
||||
return -1;
|
||||
}
|
||||
(void)cfg_store_remove(p_legacy);
|
||||
|
||||
DBG_INFO("legacy: migrated to config file (ip=%u.%u.%u.%u)",
|
||||
(unsigned)blob.ip[0], (unsigned)blob.ip[1],
|
||||
(unsigned)blob.ip[2], (unsigned)blob.ip[3]);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 模块名称:net_cfg_legacy
|
||||
* 模块功能:旧版 NCFG 二进制配置一次性迁移到通用配置文件(net_cfg 旧磁盘格式
|
||||
* 的拥有者:magic 'NCFG' + ver + CRC-16/MODBUS + 18B 字段)
|
||||
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用;平台路径经 cfg_file_store 后端)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-09-14
|
||||
* 修改记录:
|
||||
* v1.0 2026-09-14 王建锋 创建初始版本(P3:net_cfg 引擎化,旧格式代码迁入)
|
||||
*/
|
||||
|
||||
#ifndef NET_CFG_LEGACY_H
|
||||
#define NET_CFG_LEGACY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 函数功能:旧 NCFG 二进制配置(28B)一次性迁移到通用配置文件
|
||||
* 入口参数:无
|
||||
* 返回值:0 - 迁移成功,或无旧文件/新文件已存在(正常);
|
||||
* -1 - 迁移失败(新文件未生成) int
|
||||
* 限定条件:调用方须已注册 [network] 段(net_cfg_load 内部完成)
|
||||
* 函数说明:新文件已存在 → 跳过(已迁移过);旧文件有效 → 填网络配置 RAM
|
||||
* 副本 → 经引擎生成新文件(带旧值)→ 删旧文件;旧文件缺失/无效 →
|
||||
* 不动旧文件(留人工检查),新文件按工厂默认生成
|
||||
*/
|
||||
int net_cfg_legacy_migrate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_CFG_LEGACY_H */
|
||||
@@ -13,7 +13,7 @@
|
||||
| `SD2506/` | SD2506 RTC | I2C | 实时时钟驱动 | `docs/问题记录/SD2506_Trap_Records.md` |
|
||||
| `RS485/` | RS-485 半双工 | UART5 | 收发方向控制(DE 引脚)+ 时序 | — |
|
||||
| `NET/` | BSD Socket 网络抽象层 | — | Socket API + select + 轻量 FTP 服务器 | `docs/网络/`(含 `Net层阻塞模型架构设计.md`) |
|
||||
| `NETCFG/` | 网络配置 | — | `/config.ini` 网络段的加载/保存 + 旧档迁移 | `docs/子系统设计/网络配置说明.md` |
|
||||
| `NETCFG/` | 网络配置 | — | `/config.ini` 网络段的加载/保存(旧 NCFG 档已删除,2026-10-10) | `docs/子系统设计/网络配置说明.md` |
|
||||
| `UI/` | LVGL UI 组件 | — | 菜单/内容页/组件/中文字体 | `docs/UI设计/` |
|
||||
|
||||
## 根级文件
|
||||
|
||||
+60
-23
@@ -42,12 +42,49 @@ extern "C" {
|
||||
*/
|
||||
#ifdef DBG_ENABLE
|
||||
|
||||
/*
|
||||
* 行缓冲上限(栈预算旋钮,2026-10-10 加)
|
||||
* 默认 = 控制台单行上限 DBG_CON_LINE_MAX(192)。
|
||||
* ⚠ 本数组是**在每个日志调用点的栈帧里内联**的,会进 armlink 最坏调用链:
|
||||
* 实测存储/配置那条链上 9 个帧各含 192 B 行缓冲 + 32 B 时间戳缓冲
|
||||
* → defaultTask 静态最坏链 5312 B 里约 1.5 KB 纯粹是日志行缓冲。
|
||||
* 故**深调用链模块**(存储 FTL/NAND、配置引擎、网络驱动、时间同步)应在
|
||||
* 包含本文件前显式收紧,例如 `#define DBG_LINE_BUF_MAX 128U`;
|
||||
* 取值须 ≥ 该模块最长日志行(含时间戳 20 + 标签 + 正文),否则该行被截断。
|
||||
* 核算:scripts/stack_report.py(改前/改后各跑一次)
|
||||
*/
|
||||
#ifndef DBG_LINE_BUF_MAX
|
||||
#define DBG_LINE_BUF_MAX DBG_CON_LINE_MAX
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 时间戳文本缓冲上限:sys_clock_get_str() 恒写 "----/--/-- --:--:--" 或
|
||||
* "%04d-%02d-%02d %02d:%02d:%02d" = 19 字符 + '\0' → 24 足够(原 32 是随手取整,
|
||||
* 每个日志调用点白占 8 B 栈)
|
||||
*/
|
||||
#define DBG_TS_BUF_MAX 24U
|
||||
|
||||
/*
|
||||
* 有界格式化 + 交单写者控制台(行缓冲由调用方提供,便于与时间戳缓冲共用数组)
|
||||
*/
|
||||
#define DBG_EMIT(p_line, ...) do { \
|
||||
int __con_n = snprintf((p_line), DBG_LINE_BUF_MAX, __VA_ARGS__); \
|
||||
if (__con_n > 0) { \
|
||||
unsigned __con_len = (__con_n >= (int)DBG_LINE_BUF_MAX) \
|
||||
? (unsigned)(DBG_LINE_BUF_MAX - 1u) : (unsigned)__con_n; \
|
||||
(void)dbg_console_write_line((p_line), __con_len); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* 可重定向的打印函数,用户可在编译选项或 net_config.h 中预定义
|
||||
* #define DBG_PRINT(...) my_printf(__VA_ARGS__)
|
||||
* ⚠ 2026-10-10 起:带时间戳的 DBG_ERROR/DBG_INFO/DBG_DEBUG 走 **DBG_EMIT**
|
||||
* (与行缓冲共用一个数组,省一帧栈);要整体改道请重定义 `DBG_EMIT(p_line, ...)`
|
||||
* ——它是所有日志的唯一落地点。只定义 DBG_PRINT 仅影响不带时间戳的 DBG_PRINT。
|
||||
*
|
||||
* 默认走单写者控制台(App/log/console_log.c):
|
||||
* DBG_PRINT 在调用点用库 snprintf 有界格式化整行,再一次性交给 dbg_console_write_line
|
||||
* DBG_EMIT 在调用点用库 snprintf 有界格式化整行,再一次性交给 dbg_console_write_line
|
||||
* 入环形缓冲,由 defaultTask 唯一发送——
|
||||
* ① 行与行不会字符级交错(旧 printf→fputc 每字符一次 HAL_UART_Transmit 会交错);
|
||||
* ② 进 UART 的缓冲恒为控制台内部缓冲,调用方脏指针到不了 UART
|
||||
@@ -55,13 +92,8 @@ extern "C" {
|
||||
*/
|
||||
#ifndef DBG_PRINT
|
||||
#define DBG_PRINT(...) do { \
|
||||
char __con_line[DBG_CON_LINE_MAX]; \
|
||||
int __con_n = snprintf(__con_line, sizeof(__con_line), __VA_ARGS__); \
|
||||
if (__con_n > 0) { \
|
||||
unsigned __con_len = (__con_n >= (int)sizeof(__con_line)) \
|
||||
? (unsigned)(sizeof(__con_line) - 1u) : (unsigned)__con_n; \
|
||||
(void)dbg_console_write_line(__con_line, __con_len); \
|
||||
} \
|
||||
char __con_line[DBG_LINE_BUF_MAX]; \
|
||||
DBG_EMIT(__con_line, __VA_ARGS__); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
@@ -75,29 +107,34 @@ extern "C" {
|
||||
|
||||
#ifdef APP_TIMESTAMP_ENABLE
|
||||
/*
|
||||
* 时间戳输出宏 — 在日志行首追加 [YYYY-MM-DD HH:MM:SS] 格式的系统墙钟时间
|
||||
* sys_clock_get_str() 线程安全(内部使用 DWT US 计数,无锁)
|
||||
* 兼容宏:单独取时间戳文本(当前无调用者;缓冲为复合字面量,仅在本表达式内有效)
|
||||
*/
|
||||
#define DBG_TS() sys_clock_get_str((char[32]){0}, 32)
|
||||
#define DBG_TS() sys_clock_get_str((char[DBG_TS_BUF_MAX]){0}, DBG_TS_BUF_MAX)
|
||||
|
||||
/*
|
||||
* DBG_ERROR / DBG_INFO / DBG_DEBUG(带时间戳版)
|
||||
* 时间戳缓冲与行缓冲**共用一个数组**(每个调用点省一帧 24 B 栈):行文本占前
|
||||
* DBG_LINE_BUF_MAX 字节,时间戳文本切片自其后。snprintf 的全部实参先于其执行
|
||||
* 求值完毕,故"先写时间戳切片、再格式化行首"不冲突。
|
||||
*/
|
||||
/*
|
||||
* DBG_ERROR - 错误输出,受 DBG_ENABLE + APP_TIMESTAMP_ENABLE 控制
|
||||
*/
|
||||
#define DBG_ERROR(fmt, ...) do { \
|
||||
char __ts_buf[32]; \
|
||||
(void)__ts_buf; \
|
||||
DBG_PRINT("[%s]" "[ERR]" DBG_TAG " " fmt "\r\n", \
|
||||
sys_clock_get_str(__ts_buf, sizeof(__ts_buf)), ##__VA_ARGS__); \
|
||||
char __con_line[DBG_LINE_BUF_MAX + DBG_TS_BUF_MAX]; \
|
||||
DBG_EMIT(__con_line, "[%s]" "[ERR]" DBG_TAG " " fmt "\r\n", \
|
||||
sys_clock_get_str(__con_line + DBG_LINE_BUF_MAX, DBG_TS_BUF_MAX), \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* DBG_INFO - 信息输出,受 DBG_ENABLE + APP_TIMESTAMP_ENABLE 控制
|
||||
*/
|
||||
#define DBG_INFO(fmt, ...) do { \
|
||||
char __ts_buf[32]; \
|
||||
(void)__ts_buf; \
|
||||
DBG_PRINT("[%s]" DBG_TAG " " fmt "\r\n", \
|
||||
sys_clock_get_str(__ts_buf, sizeof(__ts_buf)), ##__VA_ARGS__); \
|
||||
char __con_line[DBG_LINE_BUF_MAX + DBG_TS_BUF_MAX]; \
|
||||
DBG_EMIT(__con_line, "[%s]" DBG_TAG " " fmt "\r\n", \
|
||||
sys_clock_get_str(__con_line + DBG_LINE_BUF_MAX, DBG_TS_BUF_MAX), \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
@@ -105,10 +142,10 @@ extern "C" {
|
||||
*/
|
||||
#ifdef DBG_DEBUG_ENABLE
|
||||
#define DBG_DEBUG(fmt, ...) do { \
|
||||
char __ts_buf[32]; \
|
||||
(void)__ts_buf; \
|
||||
DBG_PRINT("[%s]" DBG_TAG "(%s:%d) " fmt "\r\n", \
|
||||
sys_clock_get_str(__ts_buf, sizeof(__ts_buf)), __func__, __LINE__, ##__VA_ARGS__); \
|
||||
char __con_line[DBG_LINE_BUF_MAX + DBG_TS_BUF_MAX]; \
|
||||
DBG_EMIT(__con_line, "[%s]" DBG_TAG "(%s:%d) " fmt "\r\n", \
|
||||
sys_clock_get_str(__con_line + DBG_LINE_BUF_MAX, DBG_TS_BUF_MAX), \
|
||||
__func__, __LINE__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DBG_DEBUG(fmt, ...)
|
||||
|
||||
Reference in New Issue
Block a user