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