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 -10
View File
@@ -50,12 +50,14 @@ bool Usart0::isBufferEmpty()
* @param[in] ch 待发送字符。
* @param[out] 无。
* @retval bool true 表示成功写入发送缓冲,false 表示缓冲已满而被丢弃。
* @note 缓冲满时仅增加丢弃计数,不阻塞主流程。
* @note 当前统一由 TBE 中断从队列中取字节发送;此处只负责入队并使能发送中断。
*/
bool Usart0::putCharNonBlocking(int ch)
{
uint16_t next = nextIndex(s_txHead);
__disable_irq();
const uint16_t next = nextIndex(s_txHead);
if(next == s_txTail) {
__enable_irq();
s_dropCount++;
return false;
}
@@ -63,15 +65,16 @@ bool Usart0::putCharNonBlocking(int ch)
s_txBuf[s_txHead] = static_cast<uint8_t>(ch);
s_txHead = next;
usart_interrupt_enable(USART0, USART_INT_TBE);
__enable_irq();
return true;
}
/**
* @brief 向 USART0 发送缓冲写入一个字符。
* @brief 将字符写入 USART0 发送环形缓冲。
* @param[in] ch 待发送字符。
* @param[in] f 标准流指针。
* @param[in] f 标准流指针,实际未使用。
* @param[out] 无。
* @retval int 返回写入缓冲的字符值。
* @retval int 返回待发送字符值。
* @note 当前采用非阻塞写入策略;若缓冲已满则丢弃该字符但仍返回原字符值。
*/
int Usart0::putChar(int ch, FILE *f)
@@ -94,8 +97,7 @@ void Usart0::onInterrupt()
if(!isBufferEmpty()) {
usart_data_transmit(USART0, s_txBuf[s_txTail]);
s_txTail = nextIndex(s_txTail);
}
if(isBufferEmpty()) {
} else {
usart_interrupt_disable(USART0, USART_INT_TBE);
}
}
@@ -106,11 +108,12 @@ void Usart0::onInterrupt()
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 将 PA9 配置为复用推挽发送脚,将 PA10 配置为浮空输入接收脚。
* @note 将 PA9 配置为复用推挽发送脚,将 PA10 配置为浮空输入接收脚,并使能 AF 时钟。
*/
void Usart0::configurePins()
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_AF);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
}
@@ -120,7 +123,7 @@ void Usart0::configurePins()
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 使用 `CONFIG_USART0_BAUDRATE` 配置串口参数,并使能 USART0 中断。
* @note 使用 `CONFIG_USART0_BAUDRATE` 配置串口参数,并使能 USART0 TBE 中断用于队列发送。
*/
void Usart0::init()
{
@@ -142,7 +145,7 @@ void Usart0::init()
* @param[in] ch 待发送字符。
* @param[in] f 标准流指针。
* @param[out] 无。
* @retval int 返回写入缓冲的字符值。
* @retval int 返回待发送字符值。
* @note 该 C 包装函数内部转调 `Usart0::putChar()`。
*/
extern "C" int fputc(int ch, FILE *f) { return Usart0::putChar(ch, f); }