Files
DCU_APP/GD32E508_DCU_APP/sys/critical.h
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

63 lines
2.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file critical.h
* @brief 实时临界区基础设施:基于 BASEPRI 寄存器的中断屏蔽。
* @note EtherCAT 实时架构改造专用。GD32E508 为 Cortex-M4F,支持 BASEPRI 寄存器。
*
* @details 设计说明:
* - BASEPRI 阈值屏蔽抢占优先级 >= 1 的中断,仅保留 preempt=0(EtherCAT SYNC0
* 周期中断)可立即响应,保证 EtherCAT 周期抖动 <1us。
* - 取代原 PRIMASK 方案(`__disable_irq` / `__set_PRIMASK`),后者会屏蔽全部中断
* (含 preempt=0),无法满足 EtherCAT 实时性要求。
* - NVIC 优先级分组为 `NVIC_PRIGROUP_PRE4_SUB0`(4 位抢占 + 0 位子优先级),
* 因此 `__NVIC_PRIO_BITS = 4`,阈值 `(1U << (8U - 4U)) = 0x10`,即屏蔽优先级
* 数值 0x1x 及以上(对应 preempt 1..15),保留 preempt=0(优先级 0x0x)。
* - 阈值定义依赖 `__NVIC_PRIO_BITS`,该宏由 CMSIS 设备头文件提供(GD32E508 = 4)。
* - 项目使用 AC6(armclang) gnu++17,支持 GCC 语句表达式(statement expression),
* `RT_CRITICAL_SAVE()` 利用该特性返回保存的 BASEPRI 值,便于嵌套恢复。
*/
#ifndef SYS_CRITICAL_H
#define SYS_CRITICAL_H
#include "RTE_Components.h"
#include CMSIS_device_header
/** @brief BASEPRI 屏蔽阈值:屏蔽 preempt>=1,保留 preempt=0(EtherCAT SYNC0)。
* 对于 4 位抢占优先级(__NVIC_PRIO_BITS=4),该值为 0x10。 */
#define RT_CRITICAL_BASEPRI_VALUE (1U << (8U - __NVIC_PRIO_BITS))
/**
* @brief 进入临界区:屏蔽抢占优先级 >= 1 的中断。
* @note preempt=0 的 EtherCAT SYNC0 周期中断仍可立即抢占执行。
*/
#define RT_CRITICAL_ENTER() __set_BASEPRI(RT_CRITICAL_BASEPRI_VALUE)
/**
* @brief 退出临界区:恢复全部中断响应(BASEPRI 清零)。
*/
#define RT_CRITICAL_EXIT() __set_BASEPRI(0U)
/**
* @brief 保存当前 BASEPRI 并进入临界区,返回进入前的 BASEPRI 值。
* @return 进入临界区前的 BASEPRI 寄存器值(供 RT_CRITICAL_RESTORE 恢复)。
* @note 利用 GCC 语句表达式返回值,用于嵌套临界区场景:
* @code
* uint32_t save = RT_CRITICAL_SAVE();
* // ... 临界区代码 ...
* RT_CRITICAL_RESTORE(save);
* @endcode
*/
#define RT_CRITICAL_SAVE() \
({ \
uint32_t __basepri_save = __get_BASEPRI(); \
__set_BASEPRI(RT_CRITICAL_BASEPRI_VALUE); \
__basepri_save; \
})
/**
* @brief 恢复 BASEPRI 到指定值(用于 RT_CRITICAL_SAVE() 配套的嵌套恢复)。
* @param[in] val RT_CRITICAL_SAVE() 返回的 BASEPRI 值。
*/
#define RT_CRITICAL_RESTORE(val) __set_BASEPRI(val)
#endif /* SYS_CRITICAL_H */