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配置项替代硬编码值
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
# Tasks
|
||||
|
||||
- [x] Task 1: 新增 `sys/critical.h` BASEPRI 临界区基础设施
|
||||
- [x] SubTask 1.1: 定义 `RT_CRITICAL_ENTER()` / `RT_CRITICAL_EXIT()` 宏,基于 `__set_BASEPRI()` / `__get_BASEPRI()`,阈值为 preempt≥1
|
||||
- [x] SubTask 1.2: 定义 `RT_CRITICAL_SAVE()` 返回保存值,`RT_CRITICAL_RESTORE(val)` 恢复,用于嵌套场景
|
||||
- [x] SubTask 1.3: 确认 GD32E508 (Cortex-M4F/M33) 支持 BASEPRI 寄存器
|
||||
|
||||
- [x] Task 2: 修改 `sys/config.h` 增加 NVIC 分组、优先级与引脚配置
|
||||
- [x] SubTask 2.0: 增加 `CONFIG_ETHERCAT_ENABLE` 宏(默认 0,禁用),作为所有 EtherCAT 相关代码的编译使能开关
|
||||
- [x] SubTask 2.1: 增加 `CONFIG_NVIC_PRIORITY_GROUP` 宏设为 `NVIC_PRIGROUP_PRE4_SUB0`
|
||||
- [x] SubTask 2.2: 增加各中断抢占优先级宏:`CONFIG_IRQ_PREEMPT_ETHERCAT_SYNC=0` / `CONFIG_IRQ_PREEMPT_SCHED=1` / `CONFIG_IRQ_PREEMPT_CAN=2` / `CONFIG_IRQ_PREEMPT_ETHERCAT_ESC=1` / `CONFIG_IRQ_PREEMPT_SPI_USART=3`
|
||||
- [x] SubTask 2.3: 增加 `CONFIG_MAIN_LOOP_WFI_ENABLE` 开关宏(默认 0,关闭 WFI)
|
||||
- [x] SubTask 2.4: 增加 `CONFIG_ETHERCAT_SYNC_MODE` 宏(EXTI=0 默认 / TIMER=1 降级)
|
||||
- [x] SubTask 2.5: 增加 EXMC 引脚配置宏:D0-D15 / A16 / NOE / NWE / NE1 引脚(基于标准映射 PD0/PD1/PD4/PD5/PD7/PD8-PD11/PD14/PD15,PE7-PE15)
|
||||
- [x] SubTask 2.6: 增加 ESC 中断引脚宏:`CONFIG_ESC_SYNC0_PORT/PIN/EXTI/IRQn`(GPIOB/PB0/EXTI0/EXTI0_IRQn)、`CONFIG_ESC_IRQ_PORT/PIN/EXTI/IRQn`(GPIOB/PB1/EXTI1/EXTI1_IRQn)、`CONFIG_ESC_SYNC1_PORT/PIN/EXTI/IRQn`(GPIOB/PB2/EXTI2/EXTI2_IRQn),三个独立向量(保留 PA0 给 STANDBY 唤醒)
|
||||
- [x] SubTask 2.7: 增加 EXMC Region 基址宏 `CONFIG_ESC_EXMC_BASE_ADDR`(0x60000000)和 `CONFIG_ESC_EXMC_BANK_NOR_SRAM_REGION1`
|
||||
|
||||
- [x] Task 3: 修改 `device/Timer.cpp` NVIC 分组与调度器优先级
|
||||
- [x] SubTask 3.1: `configureNvic()` 中 `nvic_priority_group_set` 改为 `CONFIG_NVIC_PRIORITY_GROUP`
|
||||
- [x] SubTask 3.2: `CONFIG_SCHED_TIMER_IRQ_PREEMPT_PRIO` 改为 1,`CONFIG_SCHED_TIMER_IRQ_SUB_PRIO` 保持 0
|
||||
|
||||
- [x] Task 4: 修改 `sys/task_manager.cpp` 临界区换 BASEPRI
|
||||
- [x] SubTask 4.1: 移除本地 `enterCriticalSection()` / `exitCriticalSection()`(基于 PRIMASK)
|
||||
- [x] SubTask 4.2: 改用 `sys/critical.h` 的 `RT_CRITICAL_SAVE()/RESTORE()`
|
||||
- [x] SubTask 4.3: `set()` 和 `takePending()` 使用新临界区宏
|
||||
|
||||
- [x] Task 5: 修改 `device/CANFD.cpp` 优先级与临界区
|
||||
- [x] SubTask 5.1: 移除本地 `enterCriticalSection()` / `exitCriticalSection()`,改用 `sys/critical.h`
|
||||
- [x] 5.2: `init()` 中 `nvic_irq_enable` CAN RX0 优先级从 (1, n) 改为 (2, n)
|
||||
- [x] 5.3: 确认 `handleRxInterrupt()` 已只做入队+置位(当前已满足,验证即可)
|
||||
|
||||
- [x] Task 6: 修改 `device/app_spi_command.cpp` 优先级、临界区与 ISR 瘦身
|
||||
- [x] SubTask 6.1: `configureSpi0()` 中 SPI0 NVIC 优先级从 (2, 0) 改为 `(CONFIG_IRQ_PREEMPT_SPI_USART, 0)`
|
||||
- [x] SubTask 6.2: `configureExti()` 中 EXTI10_15 NVIC 优先级从 (1, 1) 改为 `(CONFIG_IRQ_PREEMPT_SPI_USART, 1)`
|
||||
- [x] SubTask 6.3: `poll()` 中 `__disable_irq/__enable_irq` 改用 `RT_CRITICAL_SAVE/RESTORE`
|
||||
- [x] SubTask 6.4: ISR 瘦身:`onCsRelease()` 中 `processCommand()` 移出 ISR,改为置位 `TASK_SPI_CMD_PROCESS` 标志由主循环执行
|
||||
- [x] SubTask 6.5: `AppSpiCommand` 类增加 `processPendingCommand()` 公有方法供主循环调用,内部调用 `processCommand()`
|
||||
- [x] SubTask 6.6: 增加 `volatile bool m_cmdPending` 标志,`onCsRelease()` 置位,`processPendingCommand()` 清除
|
||||
|
||||
- [x] Task 7: 修改 `device/usart0.cpp` 优先级与临界区
|
||||
- [x] SubTask 7.1: `init()` 中 USART0 NVIC 优先级从 (2, 0) 改为 (3, 0)
|
||||
- [x] SubTask 7.2: `putCharNonBlocking()` 中 `__disable_irq/__enable_irq` 改用 `RT_CRITICAL_SAVE/RESTORE`
|
||||
|
||||
- [x] Task 8: 修改 `main.h` 增加任务枚举
|
||||
- [x] SubTask 8.1: `system_task_t` 增加 `TASK_ETHERCAT_PROCESS`
|
||||
- [x] SubTask 8.2: `system_task_t` 增加 `TASK_SPI_CMD_PROCESS`(用于 SPI CS release 后的命令解析,移出 ISR)
|
||||
|
||||
- [x] Task 9: 修改 `main.cpp` 主循环 WFI 策略
|
||||
- [x] SubTask 9.1: 用 `#if (CONFIG_MAIN_LOOP_WFI_ENABLE != 0)` 包裹 WFI 代码块
|
||||
- [x] SubTask 9.2: WFI 关闭时改为 `__NOP()` 空转忙等
|
||||
- [x] SubTask 9.3: WFI 块内的临界区改用 `RT_CRITICAL_SAVE/RESTORE`
|
||||
|
||||
- [x] Task 10: 新建 `comm/esc_exmc_bus.h` EXMC 总线抽象接口
|
||||
- [x] SubTask 10.1: 声明 `EscExmcBus` 类:`init()` / `read16(addr)` / `write16(addr, data)` / `readBlock(addr, buf, len)` / `writeBlock(addr, buf, len)`
|
||||
- [x] SubTask 10.2: 定义 EXMC 寄存器基址宏、Region 选择宏(待引脚确认)
|
||||
|
||||
- [x] Task 11: 新建 `comm/esc_exmc_bus.cpp` EXMC 总线实现
|
||||
- [x] SubTask 11.0: 文件整体用 `#if CONFIG_ETHERCAT_ENABLE` 包裹实现(未使能时编译为空)
|
||||
- [x] SubTask 11.1: `init()`:配置 EXMC NOR/SRAM Region(GPIO 时钟、EXMC 时钟、时序参数)
|
||||
- [x] SubTask 11.2: GPIO 配置:D0-D15 / A16 / NOE / NWE / NE1(引脚基于标准映射)
|
||||
- [x] SubTask 11.3: EXMC 时序参数:按 LAN9252 HBI 时序要求配置(read/write wait state)
|
||||
- [x] SubTask 11.4: `read16/write16`:通过内存映射地址(0x60000000)直接读写
|
||||
- [x] SubTask 11.5: `readBlock/writeBlock`:循环调用 read16/write16
|
||||
|
||||
- [x] Task 12: 新建 `comm/esc_lan9252.h` LAN9252 ESC 驱动接口
|
||||
- [x] SubTask 12.1: 定义 LAN9252 关键寄存器地址宏(ESC ID、PDI 控制、中断使能等)
|
||||
- [x] SubTask 12.2: 声明 `EscLan9252` 类:`init()` / `selfTest()` / `readReg(addr)` / `writeReg(addr, val)` / `readPdi(offset, buf, len)` / `writePdi(offset, buf, len)`
|
||||
|
||||
- [x] Task 13: 新建 `comm/esc_lan9252.cpp` LAN9252 ESC 驱动实现
|
||||
- [x] SubTask 13.0: 文件整体用 `#if CONFIG_ETHERCAT_ENABLE` 包裹实现(未使能时编译为空)
|
||||
- [x] SubTask 13.1: `init()`:调用 `EscExmcBus::init()`,初始化 ESC 基本寄存器
|
||||
- [x] SubTask 13.2: `selfTest()`:读 ESC ID 寄存器校验(0x87654321 或芯片 ID)
|
||||
- [x] SubTask 13.3: `readReg/writeReg`:封装 EXMC 读写 + 地址映射
|
||||
- [x] SubTask 13.4: `readPdi/writePdi`:PDI 内存块读写
|
||||
|
||||
- [x] Task 14: 新建 `comm/ethercat_slave.h` 从站周期接口与双缓冲
|
||||
- [x] SubTask 14.1: 定义 PDO 输入/输出缓冲结构体(大小可配置)
|
||||
- [x] SubTask 14.2: 声明 `EthercatSlave` 类:`init()` / `periodicIsr()` / `getLatestInputs()` / `setOutputs()` / `process()`
|
||||
- [x] SubTask 14.3: 声明 ping-pong 双缓冲成员:两个输入缓冲 + 原子指针索引
|
||||
|
||||
- [x] Task 15: 新建 `comm/ethercat_slave.cpp` 从站周期实现
|
||||
- [x] SubTask 15.0: 文件整体用 `#if CONFIG_ETHERCAT_ENABLE` 包裹实现(未使能时编译为空)
|
||||
- [x] SubTask 15.1: `init()`:调用 `EscLan9252::init()` + `selfTest()` + 初始化双缓冲
|
||||
- [x] SubTask 15.2: `periodicIsr()`:标 `__attribute__((section(".ramfunc")))`,读输入 PDO → 写输出 PDO → 翻转缓冲指针 → 置位 `TASK_ETHERCAT_PROCESS`
|
||||
- [x] SubTask 15.3: `getLatestInputs()`:原子读取缓冲指针返回最新输入数据指针(无锁)
|
||||
- [x] SubTask 15.4: `setOutputs()`:写入输出缓冲供下次 ISR 发送
|
||||
- [x] SubTask 15.5: `process()`:应用层 PDO 映射入口(非实时,留接口)
|
||||
|
||||
- [x] Task 16: 新建 `comm/ethercat_sync.h` / `comm/ethercat_sync.cpp` SYNC0 同步(EXTI 独立向量 / TIMER0 降级)
|
||||
- [x] SubTask 16.0: `.cpp` 文件整体用 `#if CONFIG_ETHERCAT_ENABLE` 包裹实现(未使能时编译为空,EXTI0/1/2 不配置)
|
||||
- [x] SubTask 16.1: 声明 `EthercatSync` 类:`init()` / `onSync0Exti()` / `onEscIrqExti()` / `onSync1Exti()` / `onTimerIrq()`
|
||||
- [x] SubTask 16.2: `init()`:配置 SYNC0 EXTI(PB0/EXTI0,下降沿,NVIC EXTI0_IRQn preempt=0,sub=0)
|
||||
- [x] SubTask 16.3: `init()`:配置 IRQ EXTI(PB1/EXTI1,下降沿,NVIC EXTI1_IRQn preempt=1,sub=0)
|
||||
- [x] SubTask 16.4: `init()`:配置 SYNC1 EXTI(PB2/EXTI2,下降沿,NVIC EXTI2_IRQn preempt=1,sub=0)
|
||||
- [x] SubTask 16.5: `init()`:GPIO PB0/PB1/PB2 时钟使能与输入模式配置(GPIOB)
|
||||
- [x] SubTask 16.6: 降级模式(`CONFIG_ETHERCAT_SYNC_MODE==1`)时配置 TIMER0 周期 + NVIC preempt=0
|
||||
- [x] SubTask 16.7: `onSync0Exti()`:清 EXTI0 标志 → 调用 `EthercatSlave::periodicIsr()`
|
||||
- [x] SubTask 16.8: `onEscIrqExti()`:清 EXTI1 标志 → 置位 `TASK_ETHERCAT_PROCESS`
|
||||
- [x] SubTask 16.9: `onSync1Exti()`:清 EXTI2 标志(备用,暂不处理)
|
||||
- [x] SubTask 16.10: 提供 `EXTI0_IRQHandler` / `EXTI1_IRQHandler` / `EXTI2_IRQHandler` C 包装(及降级模式 `TIMER0_IRQHandler`)
|
||||
|
||||
- [x] Task 17: 修改 `sys/initial.cpp` 集成 EtherCAT 初始化(受使能开关保护)
|
||||
- [x] SubTask 17.1: `AppInitializer::init()` 中在 `SchedulerTimer::init()` 之后,用 `#if CONFIG_ETHERCAT_ENABLE` 包裹 `#include "comm/ethercat_slave.h"` 与 `comm/ethercat_sync.h"`
|
||||
- [x] SubTask 17.2: 在 `#if CONFIG_ETHERCAT_ENABLE` 块内调用 `EthercatSlave::init()`
|
||||
- [x] SubTask 17.3: 在 `EthercatSlave::init()` 之后(同块内)调用 `EthercatSync::init()`
|
||||
|
||||
- [x] Task 18: 修改 `sys/task_runner.cpp` 增加 EtherCAT 与 SPI 命令处理任务
|
||||
- [x] SubTask 18.1: 增加 `taskEthercatProcess()` 私有方法:用 `#if CONFIG_ETHERCAT_ENABLE` 包裹,内部调用 `EthercatSlave::getLatestInputs()` + `EthercatSlave::process()`
|
||||
- [x] SubTask 18.2: 增加 `taskSpiCmdProcess()` 私有方法:调用 `AppSpiCommandBus.processPendingCommand()`(此功能独立于 EtherCAT,不受 `CONFIG_ETHERCAT_ENABLE` 限制,阶段1 ISR 瘦身已需要)
|
||||
- [x] SubTask 18.3: `runPending()` 中增加 `TASK_ETHERCAT_PROCESS` 分支调用(受 `#if CONFIG_ETHERCAT_ENABLE` 保护)
|
||||
- [x] SubTask 18.4: `runPending()` 中增加 `TASK_SPI_CMD_PROCESS` 分支调用(无条件,阶段1 改造已需要)
|
||||
|
||||
- [x] Task 19: 构建配置纳入新文件
|
||||
- [x] SubTask 19.1: 确认 `GD32E508_DCU_APP.cproject.yml` 中 source 路径包含 `comm/` 目录
|
||||
- [x] SubTask 19.2: 确认 include 路径包含 `comm/` 目录
|
||||
|
||||
- [x] Task 20: 编译验证
|
||||
- [x] SubTask 20.1: 全量编译通过,无 error
|
||||
- [x] SubTask 20.2: 检查无新增 warning
|
||||
- [x] SubTask 20.3: 检查无遗漏的 `__disable_irq/__set_PRIMASK`(应全部改为 BASEPRI)
|
||||
|
||||
# Task Dependencies
|
||||
- Task 1 → Task 4, 5, 6, 7, 9(临界区宏是改造前提)
|
||||
- Task 2 → Task 3, 5, 6, 7, 16(config 优先级与引脚宏)
|
||||
- Task 8 → Task 6.4, 18(任务枚举先定义,才能在 ISR/task_runner 中引用)
|
||||
- Task 10, 12 → Task 11, 13(EXMC 接口定义在实现前)
|
||||
- Task 13, 14 → Task 15(ESC 驱动 + 从站接口在周期实现前)
|
||||
- Task 14, 16 → Task 15(双缓冲 + 同步中断在周期实现前)
|
||||
- Task 1-9(阶段1) 可与 Task 10-16(阶段2) 部分并行:阶段1 改造不依赖 comm/ 代码
|
||||
- Task 17, 18(阶段3) 依赖阶段1+阶段2 全部完成
|
||||
- Task 19 → Task 20(构建配置在编译验证前)
|
||||
Reference in New Issue
Block a user