Files
vd_960/vd960DBN/SRC/Debug/debug.h
T
wangfq ee3ade6f00 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 丢帧
2026-08-13 16:06:35 +08:00

68 lines
2.0 KiB
C

/********************************** (C) COPYRIGHT *******************************
* File Name : debug.h
* Author : WCH
* Version : V1.0.0
* Date : 2023/10/24
* Description : This file contains all the functions prototypes for UART
* Printf , Delay functions.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#ifndef __DEBUG_H
#define __DEBUG_H
#include "stdio.h"
#include "ch32v20x.h"
#ifdef __cplusplus
extern "C" {
#endif
/* UART Printf Definition */
#define DEBUG_UART1 1
#define DEBUG_UART2 2
#define DEBUG_UART3 3
/* DEBUG UATR Definition */
#ifndef DEBUG
#define DEBUG DEBUG_UART1
#endif
/* SDI Printf Definition */
#define SDI_PR_CLOSE 0
#define SDI_PR_OPEN 1
#ifndef SDI_PRINT
#define SDI_PRINT SDI_PR_CLOSE
#endif
void Delay_Init(void);
void Delay_Us(uint32_t n);
void Delay_Ms(uint32_t n);
void USART_Printf_Init(uint32_t baudrate);
void SDI_Printf_Enable(void);
#if(DEBUG)
/* 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
#define PRINT(X...)
#endif
#ifdef __cplusplus
}
#endif
#endif