feat(canfd): 切换 CANFD 接收为中断驱动和环形缓冲机制

- 将 CANFD 接收机制由轮询改为 FIFO0 的中断事件驱动处理
- 实现循环取空硬件 FIFO0,提高接收效率和响应速度
- 引入环形缓冲区缓存接收帧,支持多路通道多帧队列管理
- 置位解析任务标志位,实现接收数据的异步解析
- 增加接收中断统计,包括 FIFO 满和溢出计数
- 重构临界区代码,使用自定义函数保护中断状态
- 修改接收过滤器配置,支持按掩码匹配标准帧进入 FIFO0
- 使能 CAN FIFO0 多种中断标志,包括非空、满和溢出中断
This commit is contained in:
cbb
2026-05-30 00:24:31 +08:00
parent 078ea06317
commit f63114f5fd
26 changed files with 1173 additions and 121 deletions
+13 -9
View File
@@ -20,7 +20,9 @@ public:
uint32_t tx_count; /**< 成功发送的报文计数。 */
uint32_t rx_count; /**< 成功接收的报文计数。 */
uint32_t error_count; /**< 发送失败或检测到的错误计数。 */
uint32_t rx_drop_count; /**< 接收 FIFO 满导致丢弃的报文计数。 */
uint32_t rx_drop_count; /**< 软件接收队列满导致丢弃的报文计数。 */
uint32_t rx_fifo_full_count; /**< 硬件 FIFO0 进入满状态的次数。 */
uint32_t rx_fifo_overfull_count; /**< 硬件 FIFO0 发生 overfull 的次数。 */
uint32_t tx_drop_count; /**< 发送 FIFO 满导致丢弃的报文计数。 */
uint32_t last_rx_id; /**< 最近一次接收报文的标识符。 */
uint32_t last_tx_id; /**< 最近一次发送报文的标识符。 */
@@ -105,7 +107,7 @@ public:
* @param[out] length 输出报文数据长度的指针;允许为空。
* @param[out] channel 输出报文来源的 CAN 通道号指针;允许为空。
* @retval bool true 表示成功消费一帧报文,false 表示当前 3 路缓存均为空。
* @note 每路通道各自保留最近一帧;消费顺序采用轮转扫描,避免长期偏向固定通道。
* @note 每路通道使用轻量环形缓冲保留多帧;消费顺序采用轮转扫描,避免长期偏向固定通道。
*/
static bool consumeRxFrame(uint32_t *id, uint8_t *data, uint8_t *length, uint8_t *channel = nullptr);
@@ -153,6 +155,8 @@ public:
static void handleRxInterrupt(uint8_t channelIndex);
private:
static constexpr uint8_t kRxQueueDepth = 16U;
struct RxFrame {
uint8_t channel;
uint32_t id;
@@ -161,16 +165,16 @@ private:
};
struct RxQueue {
RxFrame frames[4];
uint8_t head;
uint8_t tail;
uint8_t count;
RxFrame frames[kRxQueueDepth];
volatile uint8_t head;
volatile uint8_t tail;
volatile uint8_t count;
};
/** @brief 初始化 CAN0/CAN1/CAN2 相关 GPIO。 */
static void initGpio();
/** @brief 为指定控制器配置全接收过滤器。 */
static void filterAcceptAll(uint32_t canPeriph, uint8_t filterNumber);
/** @brief 为指定控制器配置接收过滤器。 */
static void configureRxFilter(uint32_t canPeriph, uint8_t filterNumber);
/** @brief 配置指定控制器的 CAN 仲裁段标称位时序。 */
static void initNominalTiming(uint32_t canPeriph);
/** @brief 配置指定控制器的 CAN FD 数据段位时序与 TDC。 */
@@ -188,4 +192,4 @@ private:
using canfd_diag_t = CanFd::Diag;
using canfd_status_payload_t = CanFd::StatusPayload;
#endif /* DEVICE_CANFD_H */
#endif /* DEVICE_CANFD_H */