Files
DCU_APP/README.md
T
cbb dc91883f1e refactor(device): 重构SPI命令处理为模块化架构
- 将原有的 monolithic app_spi_command.cpp 拆分为多个专门的命令处理器文件
- 新增 spi_command_handler.h 定义命令处理器接口和上下文结构
- 新增 app_spi_command_defs.h 提取公共协议常量定义
- 新增多个具体命令处理器实现文件:
  - app_spi_cmd_boot_request.cpp (进入Bootloader命令)
  - app_spi_cmd_ota_wait.cpp (OTA等待响应命令)
  - app_spi_cmd_ping.cpp (APP心跳ping命令)
  - app_spi_cmd_can_bridge.cpp (SPI到CAN桥接命令)

- 修改 app_spi_command.cpp 仅负责SPI链路管理和命令路由逻辑
- 更新配置文件添加新源文件到项目编译列表
- 调整全局实例为对象实例(AppSpiCommandBus),移除静态方法依赖
- 更新README文档说明新的SPI命令总线拆分架构
- 微调版本号(patch: 0 -> 1, build: 2 -> 0)
2026-06-23 01:49:33 +08:00

551 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GD32E508_DCU_APP README
本 README 用来介绍 `/workzone/ROBOT_V2/DCU/DCU_APP/GD32E508_DCU_APP` 目录下各个代码文件的作用、分层关系和阅读顺序。
---
## 1. 项目概览
这是一个基于 **GD32E508** 的 DCU 应用工程,当前代码已经整理为:
- **应用入口层**:`main.cpp` / `main.h`
- **系统层(sys)**:负责初始化、节拍、任务调度、任务执行
- **设备层(device)**:负责 ADC、CANFD、Timer、串口、温度采样封装,以及 SPI 命令总线与命令处理器拆分
- **RTE / Device 层**:芯片启动文件、链接脚本、厂商外设驱动
当前整体执行逻辑是:
1. `main.cpp` 调用 `app_init()` 完成硬件初始化
2. `task_runner_init()` 初始化任务运行时数据
3. `Timer` 周期中断驱动 `task_manager` 置位任务标志
4. 主循环中 `task_runner_run_pending()` 读取并执行任务
5. `ADC / CANFD / temp_sensor / usart0` 等模块提供具体功能
---
## 2. 推荐阅读顺序
如果第一次接手这个工程,建议按这个顺序看:
1. `main.cpp`
2. `main.h`
3. `sys/initial.*`
4. `sys/task_manager.*`
5. `sys/task_runner.*`
6. `device/Timer.*`
7. `device/ADC.*`
8. `device/temp_sensor.*`
9. `device/CANFD.*`
10. `device/usart0.*`
11. `sys/systick.*`
12. `RTE/Device/GD32E508VE/*`
这样能先看清主流程,再逐层下钻。
---
## 3. 应用层代码文件说明
### 3.1 根目录文件
#### `main.cpp`
**作用:**
- 应用主入口
- 调用系统初始化
- 启动任务运行时
- 进入主循环执行待处理任务
**当前职责很轻:**
- 不直接处理 ADC
- 不直接处理 CANFD
- 不直接实现业务任务逻辑
这是当前工程的“总入口 + 调度外壳”。
---
#### `main.h`
**作用:**
- 全局基础头文件
- 引入 `RTE_Components.h` 和芯片头文件
- 定义系统任务枚举 `system_task_t`
- 定义调度器状态结构 `task_scheduler_t`
- 声明全局调度器实例 `g_scheduler`
**这里的核心内容:**
- 任务类型定义
- 调度节拍状态定义
可以把它理解为“任务系统公共协议头”。
---
## 4. 系统层 `sys/` 文件说明
### `sys/initial.h`
**作用:**
- 声明应用初始化函数 `app_init()`
这是初始化入口的头文件。
---
### `sys/initial.cpp`
**作用:**
- 实现 `app_init()`
- 负责按顺序初始化各基础模块
**当前初始化内容包括:**
- SysTick
- USART0 GPIO
- USART0 串口
- 温度采样模块
- CANFD 模块
- 任务调度器
- 用户定时器
这是系统启动时的“初始化编排器”。
---
### `sys/systick.h`
**作用:**
- 声明系统毫秒节拍相关接口
**当前提供:**
- `systick_config_ms()`
- `delay_ms()`
---
### `sys/systick.cpp`
**作用:**
- 实现 SysTick 中断处理
- 维护毫秒计数器
- 提供毫秒级阻塞延时
**当前功能:**
- `SysTick_Handler()`:系统滴答中断
- `delay_ms()`:基于滴答计数的阻塞延时
- `systick_config_ms()`:配置 1ms 节拍
这是系统时间基准模块。
---
### `sys/task_manager.h`
**作用:**
- 声明任务调度器接口
**当前提供:**
- `task_manager_init()`
- `task_manager_tick_100us()`
- `task_manager_take_pending()`
- `task_manager_set()`
---
### `sys/task_manager.cpp`
**作用:**
- 维护全局任务标志位和节拍计数
- 根据 100us 节拍分发不同周期任务
**当前任务节拍划分:**
- 500us:采样 VREF 原始值
- 1ms:采样温度原始值 + 计算工程值
- CAN RX 中断:置位接收解析任务,主循环按预算尽快消费
- 10ms:保留系统 10ms 节拍计数
- 100ms:CAN 发送准备 + CAN 发送 + 状态灯任务
- 1s:心跳任务 + 诊断打印任务
这是“什么时候执行任务”的核心模块。
---
### `sys/task_runner.h`
**作用:**
- 声明任务执行器接口
**当前提供:**
- `task_runner_init()`
- `task_runner_run_pending()`
---
### `sys/task_runner.cpp`
**作用:**
- 真正执行任务逻辑
- 保存应用运行时缓存
- 将任务位映射到具体函数
**当前内部任务包括:**
- ADC 原始采样任务
- ADC 工程值计算任务
- CAN RX 轮询任务
- CAN RX 解析任务
- CAN TX 准备任务
- CAN TX 发送任务
- 状态灯任务(占位)
- 心跳任务(占位)
- 诊断打印任务
**当前内部运行时缓存:**
- 最近一次温度采样结果
- 最近一次 VREF 原始值
- 最近一次温度原始值
- 最近一次接收 CAN 帧 ID / 长度 / 数据
这是“执行什么任务”的核心模块。
---
## 5. 设备层 `device/` 文件说明
### SPI 命令总线拆分说明
- `device/spi_command_handler.h`:SPI 命令处理器抽象与上下文结构。
- `device/app_spi_command_defs.h`:APP 运行期 SPI 协议公共常量。
- `device/app_spi_command.cpp`:当前仅负责 SPI 链路和命令路由。
- `device/app_spi_cmd_boot_request.cpp`:进入 Bootloader 的 SPI 命令处理器。
- `device/app_spi_cmd_ota_wait.cpp`:OTA 相关命令的 WAIT 响应处理器。
- `device/app_spi_cmd_ping.cpp`:APP Ping 命令处理器。
- `device/app_spi_cmd_can_bridge.cpp`:SPI→CAN 桥接命令处理器。
- 新增 SPI 业务时优先新增 `device/app_spi_cmd_*.cpp`,而不是继续膨胀 `app_spi_command.cpp`。
### `device/adc.h`
**作用:**
- 定义 ADC 采样结果结构 `adc_sample_t`
- 声明 ADC 硬件初始化、采样、换算接口
**主要接口:**
- `adc_hw_init()`
- `adc_single_read()`
- `adc_read_vref_raw()`
- `adc_read_temp_raw()`
- `adc_calculate_vdda()`
- `adc_calculate_temperature()`
- `adc_collect_sample()`
---
### `device/ADC.cpp`
**作用:**
- 实现内部温度/VREF 的 ADC 采样流程
- 提供原始值读取与工程值换算
**当前能力:**
- 初始化 ADC0
- 读取内部参考电压
- 读取内部温度通道
- 根据参考电压估算 VDDA
- 根据内部温度特性曲线估算温度
- 输出完整采样结构
这是 ADC 采样核心模块。
---
### `device/temp_sensor.h`
**作用:**
- 对温度采样模块做轻量封装
- 将 `adc_sample_t` 别名为 `temp_sensor_data_t`
**主要接口:**
- `temp_sensor_init()`
- `temp_sensor_sample()`
---
### `device/temp_sensor.cpp`
**作用:**
- 基于 ADC 模块提供温度采样初始化和采样包装
**本质上:**
- `temp_sensor_init()` → 调用 `adc_hw_init()`
- `temp_sensor_sample()` → 调用 `adc_collect_sample()`
这是一个轻量适配层,让上层按“温度传感器模块”来理解,而不直接依赖 ADC 细节。
---
### `device/usart0.h`
**作用:**
- 声明 USART0 串口相关接口
**当前提供:**
- `usart0_gpio_config()`
- `usart0_config()`
- `fputc()`
---
### `device/usart0.cpp`
**作用:**
- 配置 USART0 的 GPIO 和串口参数
- 重定向 `printf` 到 USART0
**主要用途:**
- 启动信息输出
- 运行时诊断打印
这是当前工程的串口调试输出模块。
---
### `device/Timer.h`
**作用:**
- 声明用户任务定时器初始化接口
**当前提供:**
- `user_timer_init()`
---
### `device/Timer.cpp`
**作用:**
- 配置 TIMER2
- 配置 TIMER2 中断
- 在中断里驱动任务系统节拍
**当前逻辑:**
- `user_timer_init()` 完成 TIMER2 配置与 NVIC 配置
- `TIMER2_IRQHandler()` 在每次更新中断中调用 `task_manager_tick_100us()`
这是任务节拍的硬件入口模块。
---
### `device/canfd.h`
**作用:**
- 定义 CANFD 模块对外接口
- 定义诊断结构 `canfd_diag_t`
- 定义状态发送载荷结构 `canfd_status_payload_t`
**主要接口:**
- `canfd_init()`
- `canfd_poll()`
- `canfd_prepare_status()`
- `canfd_send_prepared()`
- `canfd_has_rx_frame()`
- `canfd_consume_rx_frame()`
- `canfd_get_diag()`
---
### `device/CANFD.cpp`
**作用:**
- 初始化 CANFD 工作模式
- RX0 中断批量搬空硬件 FIFO0
- 按通道缓存接收帧
- 构建状态发送帧
- 发送准备好的 FD 帧
- 维护 CANFD 诊断统计信息
**内部拆分特点:**
- RX 和 TX 已拆成两段式
- 接收侧:`rx interrupt -> queue -> consume`
- 发送侧:`prepare -> send`
**当前内部缓存:**
- `s_rxQueues`:三路接收环形缓冲
- `s_txQueues`:三路待发送环形缓冲
- `g_can_diag`:收发与错误统计
这是当前最重要的通信模块之一。
---
## 6. RTE / Device 层文件说明
下面这些文件主要属于:
- 芯片启动代码
- 链接脚本
- 厂商标准外设驱动
- 自动生成的运行环境文件
**原则:**
- 这些文件通常不是业务逻辑主战场
- 不建议随意直接修改
- 如果一定要改,最好确认是可持续维护的变更
---
### `RTE/_Debug_GD32E508VE/RTE_Components.h`
**作用:**
- 自动生成的组件配置头文件
- 指定当前工程启用哪些外设组件
- 定义 `CMSIS_device_header`
这是编译入口层配置文件之一。
---
### `RTE/Device/GD32E508VE/startup_gd32e50x_cl.s`
**作用:**
- 启动汇编文件
- 定义中断向量表
- 复位入口
- 弱符号中断处理默认实现
这是 MCU 上电启动时最底层的入口。
---
### `RTE/Device/GD32E508VE/system_gd32e50x.c`
**作用:**
- 系统时钟配置与系统变量维护
- 提供 `SystemCoreClock` 相关支持
这是 CMSIS 系统层实现文件。
---
### `RTE/Device/GD32E508VE/ac6_linker_script.sct.src`
**作用:**
- AC6 工具链链接脚本模板
- 控制代码段、数据段、栈、堆等布局
---
### `RTE/Device/GD32E508VE/regions_GD32E508VE.h`
**作用:**
- 链接内存区域定义头文件
- 配合链接脚本使用
---
## 7. 厂商外设驱动源文件
以下文件属于厂商标准外设驱动,主要为 `gd32e50x_xxx.c`:
### `gd32e50x_adc.c`
**作用:** ADC 外设驱动实现。
### `gd32e50x_can.c`
**作用:** CAN / CANFD 相关底层驱动实现。
**说明:** 当前项目的 CANFD 能力依赖这个文件中的 GD32E508 分支实现。
### `gd32e50x_crc.c`
**作用:** CRC 外设驱动实现。
### `gd32e50x_dbg.c`
**作用:** 调试控制相关外设驱动实现。
### `gd32e50x_dma.c`
**作用:** DMA 外设驱动实现。
### `gd32e50x_exti.c`
**作用:** 外部中断控制驱动实现。
### `gd32e50x_fmc.c`
**作用:** Flash / FMC 相关驱动实现。
### `gd32e50x_gpio.c`
**作用:** GPIO 外设驱动实现。
### `gd32e50x_misc.c`
**作用:** 中断优先级 / 杂项系统控制驱动实现。
### `gd32e50x_pmu.c`
**作用:** 电源管理单元驱动实现。
### `gd32e50x_rcu.c`
**作用:** 时钟控制单元驱动实现。
### `gd32e50x_spi.c`
**作用:** SPI 外设驱动实现。
### `gd32e50x_usart.c`
**作用:** USART 外设驱动实现。
---
## 8. `.base@版本号` 文件说明
例如:
- `gd32e50x_can.c.base@1.0.0`
- `gd32e50x_adc.c.base@1.5.0`
- `startup_gd32e50x_cl.s.base@1.5.0`
这些文件通常表示:
- 原始基线版本
- 或工具生成时附带的参考副本
**建议:**
- 默认不要动
- 真要比对升级差异时再看
---
## 9. 当前应用层模块关系图(逻辑上)
```text
main.cpp
├─ sys/initial.cpp
│ ├─ sys/systick.cpp
│ ├─ device/usart0.cpp
│ ├─ device/temp_sensor.cpp
│ │ └─ device/ADC.cpp
│ ├─ device/CANFD.cpp
│ ├─ sys/task_manager.cpp
│ └─ device/Timer.cpp
│ └─ TIMER2_IRQHandler -> task_manager_tick_100us()
│
└─ sys/task_runner.cpp
├─ device/ADC.cpp
├─ device/CANFD.cpp
└─ sys/task_manager.cpp
```
---
## 10. 当前代码特点总结
### 已完成的结构化工作
- 应用层 `.c` 已整理为 `.cpp`
- `main` 已瘦身
- 任务管理与任务执行已分离
- CANFD 收发流程已拆成两段式
- CANFD 接收已切换为中断事件驱动和环形缓冲
- ADC / 温度 / 定时器 / 串口 已模块化
### 当前仍可继续演进的方向
- 将 `task_runner.cpp` 再拆成 `task_adc.cpp / task_can.cpp / task_diag.cpp`
- 将协议帧定义抽到单独文件中
- 完善状态灯任务与心跳任务
---
## 11. 维护建议
### 建议优先修改的位置
如果是改业务逻辑,优先看:
- `sys/task_runner.cpp`
- `device/CANFD.cpp`
- `device/ADC.cpp`
- `sys/task_manager.cpp`
### 不建议随便改的位置
除非你明确知道在干什么,否则不要轻易改:
- `RTE/Device/GD32E508VE/startup_gd32e50x_cl.s`
- `RTE/Device/GD32E508VE/system_gd32e50x.c`
- `RTE/Device/GD32E508VE/gd32e50x_*.c`
- 链接脚本相关文件
---
## 12. 后续建议
如果准备继续把这个项目做成更长期可维护的结构,下一步最值的动作是:
1. 增加 `protocol/` 或 `frames/` 目录,专门放 CANFD 帧定义
2. 将 `task_runner.cpp` 按任务领域继续拆文件
3. 给应用层全部源码统一补齐函数级注释和参数说明
4. 根据目标总线速率进一步细化 CANFD nominal/data timing 参数
---
如果后面代码结构继续变化,记得同步更新本 README,避免它变成过期文档。