Files
GD32E50X_BOOT/.trae/specs/prune-boot-dead-code/spec.md
T

157 lines
10 KiB
Markdown
Raw Normal View History

# 清理 BOOT 旧版本兼容代码与已废弃代码 Spec
## Why
BOOT 工程经过多轮迭代后,源码中沉淀了大量「兼容旧协议」「占位预留」「历史遗留字段」「死代码」与
开发期备份文件。这些内容已经没有调用方,但仍然占用编译产物体积、增加阅读成本,并容易在后续维护中
被误以为是「仍然有效」的实现而引入新 bug。
本变更的目标是**逐函数扫描 BOOT 自有源码**(不含 `RTE/Device` 厂商库),**安全去除**所有可以
确认无调用方的旧版本兼容代码与已废弃代码,**做到不漏不错**:不漏掉一处死代码,不错删一处仍在使用
的代码。
## What Changes
### 一、历史遗留字段
- 删除 `OTAHandler::ota_stateota_time` 字段([OTA.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/OTA.h) 第 49 行,注释明确「历史遗留字段,当前实现未实际使用」)。
### 二、OTA 兼容旧接口
- 删除 `OTAHandler::handleOTAMessage(u32 id, u8 *data, u8 len)` 声明与实现
([OTA.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/OTA.h#L153)、
[OTA.cpp](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/OTA.cpp#L1071))。
该函数注释为「兼容旧接口:按 CAN ID 处理 OTA 消息」,全工程无调用方,所有链路均直接走
`handleLinkMessage()`。
### 三、CAN 兼容旧 ACK 接口
- 删除 `CAN_transmiter::sendDATA_ACK(u32 packet_num, bool if_success)` 声明与实现
([Can.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/Can.h#L127)、
[Can.cpp](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/Can.cpp#L348))。
注释明确「packet_num 当前实现未使用」,全工程无调用方。
- 删除 `CAN_transmiter::sendDATA_ACK(u32 packet_num, u8 *data)` 声明与实现
([Can.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/Can.h#L135)、
[Can.cpp](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/Can.cpp#L313))。
注释「兼容旧协议格式:前两字节固定为 0xBA 0xC0」,全工程无调用方。
### 四、CAN DMA 占位接口
- 删除 `void can_dma_init(void)` 声明与实现
([Can.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/Can.h#L42)、
[Can.cpp](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/Can.cpp#L61))。
函数体为空,注释「当前实现未启用 DMA,该函数作为保留占位接口」。
- 同步移除 `canfd_config()` 中对 `can_dma_init()` 的调用
([Can.cpp:80](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/Can.cpp#L80))。
### 五、BootPlatform 预留占位接口
- 删除 `BootPlatform::getResetCause()` 与 C 包装 `get_reset_cause()`
([initial.h:52/81](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.h#L52)、
[initial.cpp:76/86](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.cpp#L76))。
函数体仅 `return 0`,注释「预留:如需区分...可在此补齐」,无调用方。
- 删除 `BootPlatform::initUnusedPins()` 与 C 包装 `unused_pin_init()`
([initial.h:53/88](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.h#L53)、
[initial.cpp:93/108](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.cpp#L93))。
函数体仅开 GPIOA/B/C 时钟,注释「预留:如果需要降低悬空功耗...」,无调用方。
- 删除 `BootPlatform::printSystemClockInfo()` 与 C 包装 `print_system_clock_info()`
([initial.h:54/97](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.h#L54)、
[initial.cpp:115/124](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.cpp#L115))。
函数体为空,注释「预留:可在此打印...」,无调用方。
- 删除 `BootPlatform::scanAppFlashContent(int, u32)` 与 C 包装 `scanAppFlashContent()`
([initial.h:55/133](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.h#L55)、
[initial.cpp:133/146](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.cpp#L133))。
函数体仅 `(void)print_content; (void)page_count;`,注释「预留:调试用...」,无调用方。
### 六、SpiOta 保留空壳 ISR
- 调研 `SpiOta::onSpiInterrupt()` 的 IRQ 向量绑定情况
([SpiOta.cpp:902](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/SpiOta.cpp#L902),
注释「RX 已改 DMA,保留空壳兼容旧 IRQ 向量」)。
- 若 `SPI0_IRQHandler` 未挂载或 NVIC 未使能:删除 `onSpiInterrupt()` 与对应 IRQ Handler。
- 若 IRQ 仍启用且仅用于清残留 ERR/RBNE 标志:保留 `onSpiInterrupt()` 实现,但同步更新
函数注释,去掉「兼容旧 IRQ 向量」字样,明确其当前职责。
- **该任务为调研驱动,不预先设定删除方向**。
### 七、开发期备份文件
- 删除 `SpiOta.cpp.bak_20260528`
(`g:\Robot_v2\DCU\GD32E50X_BOOT\GD32E50X_BOOT\device\SpiOta.cpp.bak_20260528`)。
- 删除 `SpiOta.cpp.bak_20260529_txdebug`
(`g:\Robot_v2\DCU\GD32E50X_BOOT\GD32E50X_BOOT\device\SpiOta.cpp.bak_20260529_txdebug`)。
- 评估 `RTE/_Debug_GD32E508VE/RTE_Components(CBB-003的冲突副本1_2026-05-06 00-26-28).h`
的去留:该文件名带「冲突副本」,明显为 IDE 合并冲突产物;若 `RTE_Components.h` 已存在
正式版本,则删除冲突副本。
### 八、C 风格包装层审计(仅审计,不强制删除)
- 全工程审计以下 C 包装是否有调用方,仅删除确认无调用方的:
- `USART0_init`、`get_reset_cause`、`unused_pin_init`、`print_system_clock_info`、
`enter_deep_sleep`、`check_sleep`、`scanAppFlashContent`、`systick_config`、
`delay_1ms/us/s`、`delay_decrement`、`system_soft_reset`、`spi_ota_*` 全套。
- 凡是仅在自身 `.cpp` 内被同类 static 方法走一遍转发的,且全工程无其他调用方的,予以删除。
- 凡是有调用方(哪怕一处)的,**保留不动**,并在任务记录中说明保留原因。
- 注:第七项删除 BootPlatform 相关包装时已顺带删除其对应 C 包装,无需重复处理。
## Impact
- **受影响代码**:
- [GD32E50X_BOOT/sys/OTA.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/OTA.h)、
[GD32E50X_BOOT/sys/OTA.cpp](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/OTA.cpp)
- [GD32E50X_BOOT/device/Can.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/Can.h)、
[GD32E50X_BOOT/device/Can.cpp](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/Can.cpp)
- [GD32E50X_BOOT/device/SpiOta.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/SpiOta.h)、
[GD32E50X_BOOT/device/SpiOta.cpp](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/device/SpiOta.cpp)
- [GD32E50X_BOOT/sys/initial.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.h)、
[GD32E50X_BOOT/sys/initial.cpp](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/initial.cpp)
- [GD32E50X_BOOT/sys/systick.h](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/systick.h)、
[GD32E50X_BOOT/sys/systick.cpp](file:///g:/Robot_v2/DCU/GD32E50X_BOOT/GD32E50X_BOOT/sys/systick.cpp)
- 删除备份文件:`SpiOta.cpp.bak_*`、`RTE_Components(...冲突副本...).h`
- **不受影响**:`RTE/Device/*` 厂商库文件(不在本 spec 范围内);OTA 业务逻辑、握手协议、
Flash 写入策略、SPI/CAN 收发主流程、睡眠唤醒流程。
- **风险评估**:所有删除目标均经 Grep 全工程确认无调用方;C 包装层审计任务保留「有调用方即保留」
的兜底规则;SPI0 ISR 任务为调研驱动,不预设删除。
- **回归影响**:编译产物体积略减;行为零变化。
## ADDED Requirements
### Requirement: 逐函数扫描确认无调用方
本 spec 涉及的每一处删除目标,SHALL 在执行删除前以 Grep/搜索方式确认其在
`g:\Robot_v2\DCU\GD32E50X_BOOT\GD32E50X_BOOT` 全工程范围内没有任何调用方。删除时 SHALL 同步
删除其声明(`.h`)与实现(`.cpp`),避免悬空声明。
#### Scenario: 删除前确认无调用方
- **WHEN** 执行者准备删除某函数/字段
- **THEN** 使用 Grep 在 `GD32E50X_BOOT` 目录全量搜索该符号
- **AND** 仅当搜索结果只包含其自身的「声明 + 实现」时,方可删除
- **AND** 若搜索结果中出现任何第三方引用,SHALL 中止删除并在任务记录中说明保留原因
### Requirement: 保持现有行为零变化
本 spec 是纯清理重构,SHALL NOT 改变任何保留代码的外部行为、协议、Flash 布局、外设初始化顺序与
中断响应路径。
#### Scenario: 清理后行为不变
- **WHEN** 清理完成并重新编译
- **THEN** BOOT 启动流程、OTA 握手、SPI/CAN 收发、Flash 写入、睡眠/唤醒、应用跳转等所有路径
SHALL 与清理前完全等价
- **AND** 编译 SHALL 通过,无新增 warning/error
## MODIFIED Requirements
### Requirement: 注释一致性
删除「兼容旧」「历史遗留」「预留占位」相关代码后,剩余文件中所有引用这些已删符号的注释、
Doxygen 文档 SHALL 同步更新或删除,避免出现「指向不存在的符号」的注释。
#### Scenario: 注释同步
- **WHEN** 某符号被删除
- **THEN** 全工程搜索该符号名
- **AND** 所有引用该符号的注释、文档 SHALL 一并删除或改写
## REMOVED Requirements
### Requirement: 旧版本 CAN ACK 协议兼容
**Reason**: `sendDATA_ACK` 两个重载为旧协议(0xBA 0xC0 头 + 4 字节业务数据 / 简化 0x0001 ACK)
保留的兼容接口,全工程无调用方,新协议统一走 `send_ack_frame` + `ota_can_sender`。
**Migration**: 无需迁移,调用方已不存在。
### Requirement: 按 CAN ID 分发 OTA 消息
**Reason**: `OTAHandler::handleOTAMessage()` 为旧的「按 CAN ID 分发」入口,所有实际链路
(CAN/SPI)已统一改走 `handleLinkMessage()`,无任何调用方。
**Migration**: 无需迁移,调用方已不存在。
### Requirement: CAN DMA 初始化占位
**Reason**: `can_dma_init()` 是空函数占位,CAN 接收路径直接从 FIFO 取数。
**Migration**: 无需迁移,函数体本就为空。