Skip to content

Commit 3c3acb9

Browse files
[Fix] <components>:drivers/can/dev_can.c 修复CAN底层无法工作时导致调用 _can_int_tx 的线程一直挂起的问题
Solution: 使用 can->status.sndchange 的bit位来表示某个发送邮箱超时 如果超时 底层驱动再通知tx_done或者tx_fail事件时不予处理 Signed-off-by: Yucai Liu <[email protected]>
1 parent 95bd685 commit 3c3acb9

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

components/drivers/can/dev_can.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2006-2024 RT-Thread Development Team
2+
* Copyright (c) 2006-2025, RT-Thread Development Team
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
@@ -165,8 +165,17 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
165165
goto err_ret;
166166
}
167167

168-
can->status.sndchange = 1;
169-
rt_completion_wait(&(tx_tosnd->completion), RT_WAITING_FOREVER);
168+
can->status.sndchange |= 1<<no;
169+
170+
if( rt_completion_wait(&(tx_tosnd->completion), RT_CANSND_MSG_TIMEOUT)!=RT_EOK)
171+
{
172+
level = rt_hw_interrupt_disable();
173+
rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
174+
can->status.sndchange &= ~ (1<<no);
175+
rt_hw_interrupt_enable(level);
176+
rt_sem_release(&(tx_fifo->sem));
177+
goto err_ret;
178+
}
170179

171180
level = rt_hw_interrupt_disable();
172181
result = tx_tosnd->result;
@@ -237,8 +246,12 @@ rt_inline int _can_int_tx_priv(struct rt_can_device *can, const struct rt_can_ms
237246
{
238247
continue;
239248
}
240-
can->status.sndchange = 1;
241-
rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_WAITING_FOREVER);
249+
can->status.sndchange |= 1<<no;
250+
if(rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_CANSND_MSG_TIMEOUT)!= RT_EOK)
251+
{
252+
can->status.sndchange &= ~ (1<<no);
253+
continue;
254+
}
242255

243256
result = tx_fifo->buffer[no].result;
244257
if (result == RT_CAN_SND_RESULT_OK)
@@ -892,16 +905,18 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
892905
no = event >> 8;
893906
tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
894907
RT_ASSERT(tx_fifo != RT_NULL);
895-
896-
if ((event & 0xff) == RT_CAN_EVENT_TX_DONE)
908+
if (can->status.sndchange&(1<<no))
897909
{
898-
tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_OK;
899-
}
900-
else
901-
{
902-
tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_ERR;
910+
if ((event & 0xff) == RT_CAN_EVENT_TX_DONE)
911+
{
912+
tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_OK;
913+
}
914+
else
915+
{
916+
tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_ERR;
917+
}
918+
rt_completion_done(&(tx_fifo->buffer[no].completion));
903919
}
904-
rt_completion_done(&(tx_fifo->buffer[no].completion));
905920
break;
906921
}
907922
}
@@ -972,3 +987,4 @@ int cmd_canstat(int argc, void **argv)
972987
}
973988
MSH_CMD_EXPORT_ALIAS(cmd_canstat, canstat, stat can device status);
974989
#endif
990+

components/drivers/include/drivers/dev_can.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2006-2024 RT-Thread Development Team
2+
* Copyright (c) 2006-2025, RT-Thread Development Team
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*
@@ -21,6 +21,9 @@
2121
#ifndef RT_CANSND_BOX_NUM
2222
#define RT_CANSND_BOX_NUM 1
2323
#endif
24+
#ifndef RT_CANSND_MSG_TIMEOUT
25+
#define RT_CANSND_MSG_TIMEOUT 100
26+
#endif
2427

2528
enum CAN_DLC
2629
{
@@ -541,3 +544,4 @@ void rt_hw_can_isr(struct rt_can_device *can, int event);
541544
/*! @}*/
542545

543546
#endif /*__DEV_CAN_H*/
547+

0 commit comments

Comments
 (0)