- 添加s_lastLoggedError数组跟踪各通道最后记录的错误计数 - 实现错误计数变化时才触发告警,避免重复打印 - 扩展错误日志信息,包含TEC、REC和总线状态详细信息 - 修复P0/P1页面携带相同统计数据时的重复打印问题 perf(ota): 移除冗余的OTA协调器状态检查方法 - 删除isGd32BusyState、isEsp32BusyState等未使用的状态判断方法 - 移除esp32FinalizeErrCategory错误分类函数 - 清理相关的头文件声明,减少代码冗余 refactor(relay): 移除未使用的中继状态获取方法 - 删除getRelaySeq、getRelayTotalPackets状态查询接口 - 移除getGd32Version版本获取方法 - 清理StateLockGuard中的isLocked方法
4.3 KiB
4.3 KiB
实施计划:DCU 初始化时通过 PC9 复位 ESP32
背景确认
- 目标仓库:
G:/Robot_v2/DCU/DCU_APP/GD32E508_DCU_APP(GD32 侧 DCU 固件)。 - PC9 当前在 DCU_APP 中未被使用,不会与 USART0/CAN/SPI/EXMC 等冲突。
- ESP32 EN/RESET 为低电平复位、高电平释放;你给出的 50ms 低电平保持后释放逻辑正确。
- 项目风格:配置集中在
sys/config.h,外设封装为device/*.h中的 C++ class,延迟统一用SysTickTimer::delayMs(),GPIO 清 0 用gpio_bit_reset()。
修改点
1. sys/config.h:增加 ESP32 复位引脚配置
在 SPI Ready 配置附近新增:
/** @brief ESP32 硬件复位控制端口(PC9 接 ESP32 EN/RESET)。 */
constexpr uint32_t CONFIG_ESP32_RESET_PORT = GPIOC;
/** @brief ESP32 硬件复位控制引脚。 */
constexpr uint32_t CONFIG_ESP32_RESET_PIN = GPIO_PIN_9;
/** @brief ESP32 复位低电平保持时间,单位 ms。 */
constexpr uint32_t CONFIG_ESP32_RESET_HOLD_MS = 50U;
2. 新增 device/esp32_reset.h
按现有 device/watchdog.h 风格编写:
#ifndef DEVICE_ESP32_RESET_H
#define DEVICE_ESP32_RESET_H
#include <stdint.h>
class Esp32Reset {
public:
/** @brief 初始化 PC9 为推挽输出,先拉低 50ms 再释放 ESP32。 */
static void init();
/** @brief 主动拉低 ESP32 RESET(进入复位)。 */
static void assertReset();
/** @brief 释放 ESP32 RESET(高电平,ESP32 启动)。 */
static void releaseReset();
};
#endif /* DEVICE_ESP32_RESET_H */
3. 新增 device/esp32_reset.cpp
按现有 device/watchdog.cpp 风格编写:
#include "device/esp32_reset.h"
#include "sys/config.h"
#include "sys/systick.h"
#include "main.h"
void Esp32Reset::init()
{
/* 1. 使能 GPIOC 时钟 */
rcu_periph_clock_enable(RCU_GPIOC);
/* 2. 先把输出数据寄存器清零,确保配置成输出时就是低电平 */
gpio_bit_reset(CONFIG_ESP32_RESET_PORT, CONFIG_ESP32_RESET_PIN);
/* 3. 配置 PC9 为推挽输出 */
gpio_init(CONFIG_ESP32_RESET_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, CONFIG_ESP32_RESET_PIN);
/* 4. 保持复位 50ms,等电源和其他 IO 稳定 */
SysTickTimer::delayMs(CONFIG_ESP32_RESET_HOLD_MS);
/* 5. 释放 ESP32 */
gpio_bit_set(CONFIG_ESP32_RESET_PORT, CONFIG_ESP32_RESET_PIN);
}
void Esp32Reset::assertReset()
{
gpio_bit_reset(CONFIG_ESP32_RESET_PORT, CONFIG_ESP32_RESET_PIN);
}
void Esp32Reset::releaseReset()
{
gpio_bit_set(CONFIG_ESP32_RESET_PORT, CONFIG_ESP32_RESET_PIN);
}
4. sys/initial.cpp:在初始化序列中加入 ESP32 复位
- 新增
#include "device/esp32_reset.h"。 - 在
SysTickTimer::initMs()之后、Usart0::configurePins()之前调用Esp32Reset::init(),原因:- 需要 SysTick 才能做 50ms 延迟;
- 尽早释放 ESP32,让它在 DCU 继续初始化 USART/CAN/SPI 期间完成自身启动,等 SPI 命令总线初始化时 ESP32 已经可用。
修改后顺序:
nvic_priority_group_set(...);
SysTickTimer::initMs();
Esp32Reset::init(); // 新增
Usart0::configurePins();
Usart0::init();
...
5. GD32E508_DCU_APP.cproject.yml:把新文件加入构建
在 groups → device 中增加:
- file: ./device/esp32_reset.h
- file: ./device/esp32_reset.cpp
代码适配说明
- 你原代码中的
GPIO_BC(GPIOA) = GPIO_PIN_9等价于gpio_bit_reset(...),项目里统一用后一个 API。 delay_ms(50)替换为SysTickTimer::delayMs(CONFIG_ESP32_RESET_HOLD_MS),与项目中其他复位/ADC 稳定延迟一致。- 端口从
GPIOA/PA9改为GPIOC/PC9的CONFIG_*常量,便于后续硬件变更。
验证
- 重新生成并编译 CMSIS csolution 工程(
cbuild DCU_APP.csolution.yml或 Keil Studio),确认新文件被编译、无重复定义、无未定义符号。 - 若编译失败,根据错误输出修正头文件包含或 cproject.yml 路径。
风险/注意事项
Esp32Reset::init()调用时 SysTick 已就绪,因此 50ms 阻塞等待是安全的(此时中断已使能但尚未初始化其他外设)。- 若后续需要在运行期再次复位 ESP32,可直接调用
Esp32Reset::assertReset()+SysTickTimer::delayMs(...)+Esp32Reset::releaseReset()。 - 本次修改不改变 PA9 的 USART0_TX 功能,调试串口保持正常。