fix(vd960DBN): PRINT 宏临界区保护 — printf 重入修复 (乱码+HardFault 根因)
现场: LUP 帧后乱码+复位。JSON: sensor 打印被二进制污染、 LUP Rx hex 残留重复 → printf 交叉输出的典型症状。 根因: BLE 协议栈回调(peripheral.c, BB 中断上下文)与主循环 都有 PRINT, 交叉调用 printf → 输出乱码 + newlib 堆/状态破坏 → HardFault (RST=0x10000000 为 HardFault_Handler 内 NVIC_SystemReset)。 修复: - debug.h PRINT 宏: 保存/恢复 MSTATUS 临界区 (__get_MSTATUS/ __disable_irq/printf/__set_MSTATUS), 中断里调用也能正确恢复, 不会嵌套误开中断 - loop_uart_proto: LUP Rx 逐字节打印改缓冲一次性输出 — 逐字节 PRINT 关中断 ~350us/字节屏蔽 UART2 ISR 丢帧
This commit is contained in:
@@ -686,12 +686,16 @@ void lup_process_frame(const uint8_t *pkg, uint16_t len)
|
|||||||
|
|
||||||
if (len < 6) { FAULT_MARKER(MK_LUP_FRAME_OUT); return; }
|
if (len < 6) { FAULT_MARKER(MK_LUP_FRAME_OUT); return; }
|
||||||
|
|
||||||
// Debug: print raw
|
// Debug: print raw (2026-08-13: 缓冲一次性输出 — 逐字节 PRINT 关中断 ~350us/字节
|
||||||
PRINT("LUP Rx:");
|
// 会屏蔽 UART2 ISR 丢帧, 且高频打印放大 printf 重入窗口)
|
||||||
for (i = 0; i < len; i++) {
|
{
|
||||||
PRINT(" %02X", pkg[i]);
|
char _hex[224];
|
||||||
|
int _p = snprintf(_hex, sizeof(_hex), "LUP Rx:");
|
||||||
|
for (i = 0; i < len && _p >= 0 && _p < (int)sizeof(_hex) - 5; i++) {
|
||||||
|
_p += snprintf(_hex + _p, sizeof(_hex) - (size_t)_p, " %02X", pkg[i]);
|
||||||
|
}
|
||||||
|
PRINT("%s\n", _hex);
|
||||||
}
|
}
|
||||||
PRINT("\n");
|
|
||||||
|
|
||||||
// --- Checksum ---
|
// --- Checksum ---
|
||||||
csr = lup_verify_checksum(pkg, len);
|
csr = lup_verify_checksum(pkg, len);
|
||||||
|
|||||||
@@ -46,7 +46,16 @@ void USART_Printf_Init(uint32_t baudrate);
|
|||||||
void SDI_Printf_Enable(void);
|
void SDI_Printf_Enable(void);
|
||||||
|
|
||||||
#if(DEBUG)
|
#if(DEBUG)
|
||||||
#define PRINT(format, ...) printf(format, ##__VA_ARGS__)
|
/* 2026-08-13 printf 重入修复: BLE 协议栈回调(peripheral.c, BB 中断上下文)
|
||||||
|
与主循环都有 PRINT, 交叉调用 printf → 输出乱码 + 堆/状态破坏 → HardFault。
|
||||||
|
临界区用保存/恢复 MSTATUS: 中断里调用也能正确恢复, 不会嵌套误开中断。
|
||||||
|
注意: 高频逐字节 PRINT (如 LUP Rx hex) 会长时间关中断, 应改缓冲一次性输出 */
|
||||||
|
#define PRINT(format, ...) do { \
|
||||||
|
uint32_t _print_ms = __get_MSTATUS(); \
|
||||||
|
__disable_irq(); \
|
||||||
|
printf(format, ##__VA_ARGS__); \
|
||||||
|
__set_MSTATUS(_print_ms); \
|
||||||
|
} while(0)
|
||||||
#else
|
#else
|
||||||
#define PRINT(X...)
|
#define PRINT(X...)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user