Files
DCU_APP/.trae/specs/fix-ecat-postaudit-risks/tasks.md
T
cbb b171767023 feat(ethercat): 添加EtherCAT从站功能支持并优化同步机制
- 添加CAN反馈和ID快照SPI命令文件
- 移除EXMC组件依赖,精简项目配置
- 添加RAM函数段链接脚本,优化Flash等待周期抖动
- 实现EscExmcBus类,提供16位并行总线访问LAN9252
- 实现EscLan9252驱动,支持寄存器和PDI内存访问
- 实现EthercatSlave类,采用三缓冲机制进行PDO数据交换
- 实现EthercatSync同步管理,支持SYNC0/SYNC1中断和定时器模式
- 添加ISR执行时间统计和诊断功能
- 分离周期路径和事件路径通知机制,避免RMW竞态
2026-06-29 01:51:02 +08:00

4.4 KiB

Tasks

  • Task 1: 阶段 H1 — 重构 safe* 接口策略,关闭主循环误用陷阱(修复高危 H1)

    • SubTask 1.1: 修改 comm/esc_lan9252.cpp 中 safeReadReg/safeWriteReg/safeReadPdi/safeWritePdi 四个函数实现,移除内部的 __get_PRIMASK()/__disable_irq()/__set_PRIMASK() 包裹,直接调用对应的无锁版本(readReg/writeReg/readPdi/writePdi)
    • SubTask 1.2: 修改 comm/esc_lan9252.h 中四个 safe* 接口的注释,由"Thread-safe,主循环与 init 调用,PRIMASK 保护"改为"INIT-ONLY:仅允许在 EthercatSync::init() 使能 EXTI NVIC 之前调用;运行期禁止调用,需 ESC 寄存器访问须通过 SYNC0 ISR 代访队列(本 spec 不涵盖)"
    • SubTask 1.3: 修改 comm/ethercat_slave.cpp 中 process() 函数的注释,删除"若需访问 ESC 寄存器必须使用 safeReadReg/safeWriteReg"的诱导性说明,替换为"运行期 PDO 交换仅通过 getLatestInputs()/setOutputs() 三缓冲进行;ESC 寄存器访问仅限 init 阶段"
    • SubTask 1.4: 代码审查确认无主循环运行期路径调用 safe* 接口(grep safeReadReg/safeWriteReg/safeReadPdi/safeWritePdi 的调用点应仅在 EthercatSlave::init() 或更早的 init 代码中)
  • Task 2: 阶段 M1 — SYNC0 ISR 入口包装 RAM 化(修复中危 M1)

    • SubTask 2.1: 在 comm/ethercat_sync.cpp 中为 EXTI0_IRQHandler 函数添加 __attribute__((section(".ramfunc"), noinline)) 属性
    • SubTask 2.2: 在 comm/ethercat_sync.cpp 中为 onSync0Exti 函数添加 __attribute__((section(".ramfunc"), noinline)) 属性
    • SubTask 2.3: 修改 onSync0Exti 内部的 EXTI 标志位清零逻辑,将 exti_interrupt_flag_clear(EXTI_0) 替换为直接寄存器位写(EXTI_PD = EXTI_0 等价写法,参考 GD32E50x 寄存器定义);若 exti_interrupt_flag_get(EXTI_0) 用于条件判断,也替换为直接读 EXTI_PD 位
    • SubTask 2.4: 确认 onSync0Exti 调用的 EthercatSlave::periodicIsr() 已在上一轮整改中标记 .ramfunc,无需重复标注;确认 periodicIsr 调用链(readPdi/writePdi/read16/write16)均已 .ramfunc
    • SubTask 2.5: 确认 EXTI1_IRQHandler/onEscIrqExti 与 EXTI2_IRQHandler/onSync1Exti 不做改动(范围限定,preempt=1 非抖动关键)
  • Task 3: 阶段 M2 — NVIC 优先级分组设置前移(修复中危 M2)

    • SubTask 3.1: 在 sys/initial.cpp 的 AppInitializer::init() 最开头(任何外设 init 调用之前,通常在函数体第一行)增加 nvic_priority_group_set(CONFIG_NVIC_PRIORITY_GROUP);
    • SubTask 3.2: 在 device/timer.cpp 的 SchedulerTimer::init() 中移除原有的 nvic_priority_group_set(CONFIG_NVIC_PRIORITY_GROUP) 调用(改为由 initial.cpp 统一最早设置)
    • SubTask 3.3: 确认 sys/config.h 中已定义 CONFIG_NVIC_PRIORITY_GROUP(应为 NVIC_PRIGROUP_PRE4_SUB0);若无定义则补充
    • SubTask 3.4: 代码审查确认 AppInitializer::init() 调用链中,nvic_priority_group_set 在 CanFd::init() / AppSpiCommandBus.init() / SchedulerTimer::init() / EthercatSync::init() 之前执行
  • Task 4: 阶段 M3 — 删除未用的 readBlock/writeBlock(修复中危 M3)

    • SubTask 4.1: 删除 comm/esc_exmc_bus.cpp 中的 EscExmcBus::readBlock 与 EscExmcBus::writeBlock 函数实现
    • SubTask 4.2: 删除 comm/esc_exmc_bus.h 中的 readBlock 与 writeBlock 成员函数声明
    • SubTask 4.3: 删除或修正 comm/esc_exmc_bus.h 中关于 readBlock/writeBlock 的"ISR-only"注释(随声明一并删除)
    • SubTask 4.4: 全项目 grep 确认无 readBlock/writeBlock 残留引用
  • Task 5: 编译验证与一致性检查(静态审查完成,编译受 EXMC pack 阻塞)

    • SubTask 5.1: 全量编译通过,无 error(⚠️ 受 EXMC pack 解析问题阻塞,改为静态代码审查,详见下方)
    • SubTask 5.2: 静态代码审查确认:无 __disable_irq/__set_PRIMASK 残留于 comm/esc_lan9252.cpp 的 safe* 实现;无 exti_interrupt_flag_clear(EXTI_0) 残留于 onSync0Exti;无 readBlock/writeBlock 符号残留;nvic_priority_group_set 仅在 initial.cpp 调用一次
    • SubTask 5.3: 若可编译,查看 map 文件确认 EXTI0_IRQHandler/onSync0Exti 符号地址位于 SRAM(.ramfunc 段)(⚠️ 受编译阻塞,待编译环境修复后验证)

Task Dependencies

  • Task 1, 2, 3, 4 相互独立,可并行实施(改动不同文件/不同函数,无交叉)
  • Task 5 依赖 Task 1-4 全部完成