# Verification Checklist ## 使能开关(未焊接保护) - [x] `sys/config.h` 中 `CONFIG_ETHERCAT_ENABLE` 默认为 0 - [x] `CONFIG_ETHERCAT_ENABLE=0` 时 `comm/` 全部代码不参与编译(用 `#if` 包裹) - [x] `CONFIG_ETHERCAT_ENABLE=0` 时 `sys/initial.cpp` 不调用 `EthercatSlave::init()` / `EthercatSync::init()` - [x] `CONFIG_ETHERCAT_ENABLE=0` 时 `sys/task_runner.cpp` 的 `TASK_ETHERCAT_PROCESS` 分支空操作 - [x] `CONFIG_ETHERCAT_ENABLE=0` 时 EXMC / EXTI0 / EXTI1 / EXTI2 不被配置 - [x] `CONFIG_ETHERCAT_ENABLE=0` 时编译产物与改造前功能等价(ADC/CAN/SPI 正常) - [x] 阶段 1 实时架构改造(NVIC/BASEPRI/ISR 瘦身)不受 `CONFIG_ETHERCAT_ENABLE` 影响,始终生效 - [x] `TASK_SPI_CMD_PROCESS` 与 `taskSpiCmdProcess()` 不受 `CONFIG_ETHERCAT_ENABLE` 限制(阶段1 改造已需要) ## 阶段 1:实时架构改造 - [x] `sys/critical.h` 已创建,`RT_CRITICAL_ENTER/EXIT/SAVE/RESTORE` 宏基于 BASEPRI 实现 - [x] `sys/config.h` 中 `CONFIG_NVIC_PRIORITY_GROUP` 设为 `NVIC_PRIGROUP_PRE4_SUB0` - [x] `sys/config.h` 中各中断优先级宏已按分层表配置(EtherCAT=0/调度器=1/CAN=2/SPI+EXTI+USART=3) - [x] `sys/config.h` 中 `CONFIG_MAIN_LOOP_WFI_ENABLE` 默认为 0 - [x] `device/Timer.cpp` 中 `nvic_priority_group_set` 使用 `CONFIG_NVIC_PRIORITY_GROUP` - [x] `device/Timer.cpp` 中调度器 NVIC 优先级为 (1, 0) - [x] `sys/task_manager.cpp` 中 `set()` 和 `takePending()` 使用 BASEPRI 临界区 - [x] `sys/task_manager.cpp` 中无残留 `__disable_irq/__set_PRIMASK` - [x] `device/CANFD.cpp` 中 `hasRxFrame()` 和 `consumeRxFrame()` 使用 BASEPRI 临界区 - [x] `device/CANFD.cpp` 中 CAN RX0 NVIC 优先级为 (2, n) - [x] `device/CANFD.cpp` 中 `handleRxInterrupt()` 仅做入队+置位(验证未退化) - [x] `device/app_spi_command.cpp` 中 SPI0 NVIC 优先级为 (3, 0) - [x] `device/app_spi_command.cpp` 中 EXTI10_15 NVIC 优先级为 (3, 1) - [x] `device/app_spi_command.cpp` 中 `poll()` 使用 BASEPRI 临界区 - [x] `device/app_spi_command.cpp` 中 `onCsRelease()` 不在 ISR 内调用 `processCommand()`(移主循环) - [x] `device/usart0.cpp` 中 USART0 NVIC 优先级为 (3, 0) - [x] `device/usart0.cpp` 中 `putCharNonBlocking()` 使用 BASEPRI 临界区 - [x] `main.h` 中 `system_task_t` 增加 `TASK_ETHERCAT_PROCESS` - [x] `main.h` 中 `system_task_t` 增加 `TASK_SPI_CMD_PROCESS` - [x] `device/app_spi_command.h` 中增加 `processPendingCommand()` 公有方法声明 - [x] `device/app_spi_command.cpp` 中 `onCsRelease()` 不再调用 `processCommand()`,改置位 `m_cmdPending` + `TASK_SPI_CMD_PROCESS` - [x] `device/app_spi_command.cpp` 中 `processPendingCommand()` 清除 `m_cmdPending` 后调用 `processCommand()` - [x] `main.cpp` 中 WFI 代码块由 `CONFIG_MAIN_LOOP_WFI_ENABLE` 开关控制 - [x] `main.cpp` 中 WFI 关闭时使用 `__NOP()` 忙等 - [x] 全项目搜索确认无遗漏的 `__disable_irq` / `__set_PRIMASK`(除 `sys/critical.h` 实现内) ## 阶段 2:LAN9252 ESC 驱动骨架 - [x] `comm/esc_exmc_bus.h` 已创建,声明 `EscExmcBus` 类接口 - [x] `comm/esc_exmc_bus.cpp` 已创建,EXMC NOR/SRAM 16-bit 初始化实现 - [x] `comm/esc_exmc_bus.cpp` 中 GPIO 配置使用 `config.h` 引脚宏(基于标准映射 PD0/PD1/PD4/PD5/PD7/PD8-PD11/PD14/PD15,PE7-PE15) - [x] `comm/esc_exmc_bus.cpp` 中 `read16/write16` 通过内存映射地址(0x60000000)访问 - [x] `comm/esc_lan9252.h` 已创建,声明 `EscLan9252` 类接口 - [x] `comm/esc_lan9252.cpp` 已创建,实现 `init()` / `selfTest()` / `readReg` / `writeReg` / `readPdi` / `writePdi` - [x] `comm/esc_lan9252.cpp` 中 `selfTest()` 读取 ESC ID 寄存器并校验 - [x] `comm/ethercat_slave.h` 已创建,声明 `EthercatSlave` 类与 PDO 双缓冲结构 - [x] `comm/ethercat_slave.cpp` 已创建,实现周期处理与双缓冲 - [x] `comm/ethercat_slave.cpp` 中 `periodicIsr()` 标记 `__attribute__((section(".ramfunc")))` - [x] `comm/ethercat_slave.cpp` 中 `periodicIsr()` 执行:读输入→写输出→翻转指针→置位任务 - [x] `comm/ethercat_slave.cpp` 中 `getLatestInputs()` 无锁原子读取 - [x] `comm/ethercat_sync.h` / `comm/ethercat_sync.cpp` 已创建 - [x] `comm/ethercat_sync.cpp` 中 SYNC0 EXTI(PB0/EXTI0)配置完成,下降沿触发 - [x] `comm/ethercat_sync.cpp` 中 IRQ EXTI(PB1/EXTI1)配置完成,下降沿触发 - [x] `comm/ethercat_sync.cpp` 中 SYNC1 EXTI(PB2/EXTI2)配置完成,下降沿触发 - [x] `comm/ethercat_sync.cpp` 中 EXTI0_IRQn NVIC 优先级 (0, 0)(SYNC0 独占 preempt=0) - [x] `comm/ethercat_sync.cpp` 中 EXTI1_IRQn NVIC 优先级 (1, 0)(IRQ preempt=1,可被 SYNC0 抢占) - [x] `comm/ethercat_sync.cpp` 中 EXTI2_IRQn NVIC 优先级 (1, 0)(SYNC1 preempt=1,备用) - [x] `comm/ethercat_sync.cpp` 中 `onSync0Exti()` 清 EXTI0 标志 → 调用 `EthercatSlave::periodicIsr()` - [x] `comm/ethercat_sync.cpp` 中 `onEscIrqExti()` 清 EXTI1 标志 → 置位 `TASK_ETHERCAT_PROCESS`(极简) - [x] `comm/ethercat_sync.cpp` 中 `onSync1Exti()` 清 EXTI2 标志(备用) - [x] `comm/ethercat_sync.cpp` 中提供 `EXTI0_IRQHandler` / `EXTI1_IRQHandler` / `EXTI2_IRQHandler` C 包装 - [x] GPIO PB0/PB1/PB2 时钟使能与输入模式配置完成 - [x] PA0 未被占用,保留给未来 STANDBY 模式唤醒(WKUP_PIN0) - [x] 降级模式 `CONFIG_ETHERCAT_SYNC_MODE==1` 时 TIMER0 配置可用 ## 阶段 3:系统集成 - [x] `sys/initial.cpp` 中 `AppInitializer::init()` 增加 `EthercatSlave::init()` 调用 - [x] `sys/initial.cpp` 中增加 `EthercatSync::init()` 调用 - [x] `sys/task_runner.cpp` 中增加 `taskEthercatProcess()` 方法 - [x] `sys/task_runner.cpp` 中增加 `taskSpiCmdProcess()` 方法 - [x] `sys/task_runner.cpp` 中 `runPending()` 增加 `TASK_ETHERCAT_PROCESS` 分支 - [x] `sys/task_runner.cpp` 中 `runPending()` 增加 `TASK_SPI_CMD_PROCESS` 分支 - [x] `sys/config.h` 中 NVIC 分组、优先级、EXMC 引脚、ESC 中断引脚、SYNC 模式等配置宏已定义 - [x] 构建配置 `GD32E508_DCU_APP.cproject.yml` 包含 `comm/` 目录 ## 编译验证 - [x] 全量编译通过,无 error - [x] 无新增 warning - [x] 无遗漏的 `__disable_irq/__set_PRIMASK`(全项目搜索确认) - [x] 新增文件均在 `comm/` 目录下,不污染现有 `device/` / `sys/` 结构