Files
DCU_APP/.trae/specs/add-ethercat-lan9252-realtime/checklist.md
T
cbb 1612e326ee feat(cproject): 重构项目文件结构并添加EtherCAT通信支持
- 将设备相关文件重新组织为device/spi和comm分组
- 添加EtherCAT从站通信模块(esc_exmc_bus、esc_lan9252、ethercat_slave等)
- 添加EXMC外设组件支持
- 统一文件命名规范为小写

refactor(canfd): 优化CANFD模块中断安全性和配置方式

- 替换自定义临界区函数为RT_CRITICAL_SAVE/RESTORE宏
- 使用配置常量CONFIG_IRQ_PREEMPT_CAN替代硬编码值
- 简化邮箱满时的处理逻辑,移除不必要的SysTick等待
- 移除废弃的中断保存头文件引用

refactor(timer): 更新定时器配置以使用配置常量

- 修复头文件包含路径大小写问题
- 使用CONFIG_NVIC_PRIORITY_GROUP配置项替代硬编码值
2026-06-26 00:57:59 +08:00

6.1 KiB

Verification Checklist

使能开关(未焊接保护)

  • sys/config.h 中 CONFIG_ETHERCAT_ENABLE 默认为 0
  • CONFIG_ETHERCAT_ENABLE=0 时 comm/ 全部代码不参与编译(用 #if 包裹)
  • CONFIG_ETHERCAT_ENABLE=0 时 sys/initial.cpp 不调用 EthercatSlave::init() / EthercatSync::init()
  • CONFIG_ETHERCAT_ENABLE=0 时 sys/task_runner.cpp 的 TASK_ETHERCAT_PROCESS 分支空操作
  • CONFIG_ETHERCAT_ENABLE=0 时 EXMC / EXTI0 / EXTI1 / EXTI2 不被配置
  • CONFIG_ETHERCAT_ENABLE=0 时编译产物与改造前功能等价(ADC/CAN/SPI 正常)
  • 阶段 1 实时架构改造(NVIC/BASEPRI/ISR 瘦身)不受 CONFIG_ETHERCAT_ENABLE 影响,始终生效
  • TASK_SPI_CMD_PROCESS 与 taskSpiCmdProcess() 不受 CONFIG_ETHERCAT_ENABLE 限制(阶段1 改造已需要)

阶段 1:实时架构改造

  • sys/critical.h 已创建,RT_CRITICAL_ENTER/EXIT/SAVE/RESTORE 宏基于 BASEPRI 实现
  • sys/config.h 中 CONFIG_NVIC_PRIORITY_GROUP 设为 NVIC_PRIGROUP_PRE4_SUB0
  • sys/config.h 中各中断优先级宏已按分层表配置(EtherCAT=0/调度器=1/CAN=2/SPI+EXTI+USART=3)
  • sys/config.h 中 CONFIG_MAIN_LOOP_WFI_ENABLE 默认为 0
  • device/Timer.cpp 中 nvic_priority_group_set 使用 CONFIG_NVIC_PRIORITY_GROUP
  • device/Timer.cpp 中调度器 NVIC 优先级为 (1, 0)
  • sys/task_manager.cpp 中 set() 和 takePending() 使用 BASEPRI 临界区
  • sys/task_manager.cpp 中无残留 __disable_irq/__set_PRIMASK
  • device/CANFD.cpp 中 hasRxFrame() 和 consumeRxFrame() 使用 BASEPRI 临界区
  • device/CANFD.cpp 中 CAN RX0 NVIC 优先级为 (2, n)
  • device/CANFD.cpp 中 handleRxInterrupt() 仅做入队+置位(验证未退化)
  • device/app_spi_command.cpp 中 SPI0 NVIC 优先级为 (3, 0)
  • device/app_spi_command.cpp 中 EXTI10_15 NVIC 优先级为 (3, 1)
  • device/app_spi_command.cpp 中 poll() 使用 BASEPRI 临界区
  • device/app_spi_command.cpp 中 onCsRelease() 不在 ISR 内调用 processCommand()(移主循环)
  • device/usart0.cpp 中 USART0 NVIC 优先级为 (3, 0)
  • device/usart0.cpp 中 putCharNonBlocking() 使用 BASEPRI 临界区
  • main.h 中 system_task_t 增加 TASK_ETHERCAT_PROCESS
  • main.h 中 system_task_t 增加 TASK_SPI_CMD_PROCESS
  • device/app_spi_command.h 中增加 processPendingCommand() 公有方法声明
  • device/app_spi_command.cpp 中 onCsRelease() 不再调用 processCommand(),改置位 m_cmdPending + TASK_SPI_CMD_PROCESS
  • device/app_spi_command.cpp 中 processPendingCommand() 清除 m_cmdPending 后调用 processCommand()
  • main.cpp 中 WFI 代码块由 CONFIG_MAIN_LOOP_WFI_ENABLE 开关控制
  • main.cpp 中 WFI 关闭时使用 __NOP() 忙等
  • 全项目搜索确认无遗漏的 __disable_irq / __set_PRIMASK(除 sys/critical.h 实现内)

阶段 2:LAN9252 ESC 驱动骨架

  • comm/esc_exmc_bus.h 已创建,声明 EscExmcBus 类接口
  • comm/esc_exmc_bus.cpp 已创建,EXMC NOR/SRAM 16-bit 初始化实现
  • comm/esc_exmc_bus.cpp 中 GPIO 配置使用 config.h 引脚宏(基于标准映射 PD0/PD1/PD4/PD5/PD7/PD8-PD11/PD14/PD15,PE7-PE15)
  • comm/esc_exmc_bus.cpp 中 read16/write16 通过内存映射地址(0x60000000)访问
  • comm/esc_lan9252.h 已创建,声明 EscLan9252 类接口
  • comm/esc_lan9252.cpp 已创建,实现 init() / selfTest() / readReg / writeReg / readPdi / writePdi
  • comm/esc_lan9252.cpp 中 selfTest() 读取 ESC ID 寄存器并校验
  • comm/ethercat_slave.h 已创建,声明 EthercatSlave 类与 PDO 双缓冲结构
  • comm/ethercat_slave.cpp 已创建,实现周期处理与双缓冲
  • comm/ethercat_slave.cpp 中 periodicIsr() 标记 __attribute__((section(".ramfunc")))
  • comm/ethercat_slave.cpp 中 periodicIsr() 执行:读输入→写输出→翻转指针→置位任务
  • comm/ethercat_slave.cpp 中 getLatestInputs() 无锁原子读取
  • comm/ethercat_sync.h / comm/ethercat_sync.cpp 已创建
  • comm/ethercat_sync.cpp 中 SYNC0 EXTI(PB0/EXTI0)配置完成,下降沿触发
  • comm/ethercat_sync.cpp 中 IRQ EXTI(PB1/EXTI1)配置完成,下降沿触发
  • comm/ethercat_sync.cpp 中 SYNC1 EXTI(PB2/EXTI2)配置完成,下降沿触发
  • comm/ethercat_sync.cpp 中 EXTI0_IRQn NVIC 优先级 (0, 0)(SYNC0 独占 preempt=0)
  • comm/ethercat_sync.cpp 中 EXTI1_IRQn NVIC 优先级 (1, 0)(IRQ preempt=1,可被 SYNC0 抢占)
  • comm/ethercat_sync.cpp 中 EXTI2_IRQn NVIC 优先级 (1, 0)(SYNC1 preempt=1,备用)
  • comm/ethercat_sync.cpp 中 onSync0Exti() 清 EXTI0 标志 → 调用 EthercatSlave::periodicIsr()
  • comm/ethercat_sync.cpp 中 onEscIrqExti() 清 EXTI1 标志 → 置位 TASK_ETHERCAT_PROCESS(极简)
  • comm/ethercat_sync.cpp 中 onSync1Exti() 清 EXTI2 标志(备用)
  • comm/ethercat_sync.cpp 中提供 EXTI0_IRQHandler / EXTI1_IRQHandler / EXTI2_IRQHandler C 包装
  • GPIO PB0/PB1/PB2 时钟使能与输入模式配置完成
  • PA0 未被占用,保留给未来 STANDBY 模式唤醒(WKUP_PIN0)
  • 降级模式 CONFIG_ETHERCAT_SYNC_MODE==1 时 TIMER0 配置可用

阶段 3:系统集成

  • sys/initial.cpp 中 AppInitializer::init() 增加 EthercatSlave::init() 调用
  • sys/initial.cpp 中增加 EthercatSync::init() 调用
  • sys/task_runner.cpp 中增加 taskEthercatProcess() 方法
  • sys/task_runner.cpp 中增加 taskSpiCmdProcess() 方法
  • sys/task_runner.cpp 中 runPending() 增加 TASK_ETHERCAT_PROCESS 分支
  • sys/task_runner.cpp 中 runPending() 增加 TASK_SPI_CMD_PROCESS 分支
  • sys/config.h 中 NVIC 分组、优先级、EXMC 引脚、ESC 中断引脚、SYNC 模式等配置宏已定义
  • 构建配置 GD32E508_DCU_APP.cproject.yml 包含 comm/ 目录

编译验证

  • 全量编译通过,无 error
  • 无新增 warning
  • 无遗漏的 __disable_irq/__set_PRIMASK(全项目搜索确认)
  • 新增文件均在 comm/ 目录下,不污染现有 device/ / sys/ 结构