现场: 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 丢帧
68 lines
2.0 KiB
C
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
|