Open
Description
RT-Thread Version
5.1.0
Hardware Type/Architectures
STM32F407VET6
Develop Toolchain
RT-Thread Studio
Describe the bug
在CAN总线上设备掉电时发送CAN报文,STM32F407会产生SCE中断(错误码并非RT_CAN_BUS_ACK_ERR),drv_can中没有调用rt_hw_can_isr来执行
rt_completion_done(&(tx_fifo->buffer[no].completion));
这会导致 _can_int_tx 中
rt_completion_wait(&(tx_tosnd->completion), RT_WAITING_FOREVER)
永远不会返回。我尝试将他改成
if(RT_EOK != rt_completion_wait(&(tx_tosnd->completion), 100))
{
/* send timeout. */
level = rt_hw_interrupt_disable();
rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
rt_hw_interrupt_enable(level);
rt_sem_release(&(tx_fifo->sem));
// rt_kprintf("CAN send timeout, no %d\n", no);
goto err_ret;
}
来解决,不知道是否正确
Other additional context
No response
Activity
wdfk-prog commentedon May 31, 2025
unnamed2 commentedon May 31, 2025
感谢回复。
在我使用的版本中, _can_sce_isr的代码是直接写在CAN1_SCE_IRQHandler中的,经过对比,他们的实现上的差距并不算很大。
经过排查,在设备掉电瞬间发送报文会产生SCE中断,此时ESR寄存器的值为0x1800013(在被读取之后变更为0x0800003), 对应着RT_CAN_BUS_BIT_PAD_ERR,新版_can_sce_isr中和我使用的旧版本中对此错误的处理是一致的,仅仅对计数+1以记录错误,随后并未调用rt_hw_can_isr来进行处理,这也是导致rt_completion_done(&(tx_fifo->buffer[no].completion));无法返回的原因。
在我的案例中,设备掉电之后,我尝试发送CAN报文会正常产生RT_CAN_BUS_ACK_ERR错误,这时能正确唤醒被挂起的发送线程。
wdfk-prog commentedon May 31, 2025
rt-thread/bsp/stm32/libraries/HAL_Drivers/drivers/drv_can.c
Lines 724 to 731 in fe13089
RT_CAN_BUS_ACK_ERR
错误处理的逻辑直接copy到RT_CAN_BUS_BIT_PAD_ERR
错误处理上了.AutoRetransmission
时,对于TX发送导致进入的SCE中断执行进入rt_hw_can_isr
函数执行错误处理.