修复stm32 CAN的SCE中断中只在ACK错误检查发送完成导致小概率出错的问题#10354
Conversation
修复CAN总线在出错时没能处理的问题
|
所以是测试这么修改成功解决问题了是吗? 有条件可以测试一下其他SCE中断触发的错误是否也有这个情况(^▽^) |
|
rt-thread/bsp/stm32/libraries/HAL_Drivers/drv_can.c Lines 770 to 781 in aab2428 我使用最新版本进行一些测试确实没问题,但是我仍然不能保证他的正确性 这个是我之前使用的版本,这里面有一个不同的地方是他调用了HAL_CAN_IRQHandler, 在这个函数中会清除RQCP标志。这导致在我的版本中如果SCE中断没有处理,就会导致卡死的问题。 最新的版本中没有调用这个函数,这是不是意味着,不在SCE中断中处理任何发送错误也能避免这样的问题,所以删掉这些东西才是正确的? 我看之前的版本中考虑了自动重发的影响,这里我还没有测试过。 |
switch ((errtype & 0x70) >> 4)
{
} |
|
我在这里写了一个简单的程序来实验 void CAN2_SCE_IRQHandler(void) {
CAN_IRQ_Handler(&hcan2, "CAN2_SCE_IRQHandler");
// HAL_CAN_IRQHandler(&hcan2);
__HAL_CAN_CLEAR_FLAG(&hcan2, CAN_FLAG_ERRI);
CLEAR_BIT(hcan2.Instance->ESR, CAN_ESR_LEC);
}
void CAN2_TX_IRQHandler(void) {
CAN_IRQ_Handler(&hcan2, "CAN2_TX_IRQHandler");
// HAL_CAN_IRQHandler(&hcan2);
if(__HAL_CAN_GET_FLAG(&hcan2, CAN_FLAG_RQCP0)) {
__HAL_CAN_CLEAR_FLAG(&hcan2, CAN_FLAG_RQCP0);
}
if(__HAL_CAN_GET_FLAG(&hcan2, CAN_FLAG_RQCP1)) {
__HAL_CAN_CLEAR_FLAG(&hcan2, CAN_FLAG_RQCP1);
}
if(__HAL_CAN_GET_FLAG(&hcan2, CAN_FLAG_RQCP2)) {
__HAL_CAN_CLEAR_FLAG(&hcan2, CAN_FLAG_RQCP2);
}
}其中 CAN_IRQ_Handler 会输出寄存器状态以及中断函数名 void CAN_IRQ_Handler(CAN_HandleTypeDef *hcan, const char *irq_name) {
struct CANRegisters reg;
__disable_irq();
reg.MCR = hcan->Instance->MCR;
reg.MSR = hcan->Instance->MSR;
reg.TSR = hcan->Instance->TSR;
reg.RF0R = hcan->Instance->RF0R;
reg.RF1R = hcan->Instance->RF1R;
reg.IER = hcan->Instance->IER;
reg.ESR = hcan->Instance->ESR;
reg.BTR = hcan->Instance->BTR;
if (Status_Buffer_Index < 128) {
// Store the IRQ name and registers in the buffer
strncpy(Status_Buffer[Status_Buffer_Index].IRQ_name, irq_name,
sizeof(Status_Buffer[Status_Buffer_Index].IRQ_name) - 1);
Status_Buffer[Status_Buffer_Index].regs = reg;
Status_Buffer_Index++;
}
__enable_irq(); // Re-enable interrupts
}状态被保存之后,main函数中会进行输出。 CAN总线发送失败之后,会连续触发SCE和TX中断: 其中TSR寄存器的0x1C000009意味着CAN_TSR_RQCP0 | CAN_TSR_TERR0。 自动重发模式经过测试,在成功之前会不停的触发SCE中断,直到发送成功最后产生TX中断为止。 这样看感觉在SCE中断中直接检查发送完成好像是可以的,并且HAL好像就是这么做的。直接在switch之前调用_can_check_tx_complete就行了 |
|
抱歉回复晚了,最近在做其他的事情,没来得及调整这个代码。 |
📌 Code Review Assignment🏷️ Tag: bsp_stm32Path: Changed Files (Click to expand)
📊 Current Review Status (Last Updated: 2025-07-01 03:44 UTC)
📝 Review Instructions
|
我尝试多修改了一些地方;这些修改在我们的设备上测试,没有发现问题。 在检查TX的RQCP标志位时,可能出现多个CAN发送完成的情况,因此去掉了'else',一次性检查了RQCP0-RQCP2的值(HAL库也是一次检查了三个中断) 因为没有调用HAL_CAN_IRQHandler, 因此HAL_CAN_ErrorCallback永远不会执行。 |
|
@Rbb666 帮忙看一下^_^ |
|
@unnamed2 这份PR的标题麻烦修改下吧,直观体现下修复了什么问题 |
修复CAN总线在出错时没能处理的问题
拉取/合并请求描述:(PR description)
[
为什么提交这份PR (why to submit this PR)
尝试解决CAN总线出现波动的情况下,can发送阻塞的问题。
你的解决方案是什么 (what is your solution)
在CAN错误中断发生BITPAD错误时,和ACK错误一样,检测发送完成状态。
请提供验证的bsp和config (provide the config and bsp)
]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up