Skip to content

Commit a1c642a

Browse files
illustriousnessRbb666
authored andcommitted
[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 c209173 commit a1c642a

File tree

3 files changed

+53
-15
lines changed

3 files changed

+53
-15
lines changed

components/drivers/can/Kconfig

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,26 @@ if RT_USING_CAN
66
config RT_CAN_USING_HDR
77
bool "Enable CAN hardware filter"
88
default n
9+
910
config RT_CAN_USING_CANFD
1011
bool "Enable CANFD support"
1112
default n
12-
endif
13+
14+
config RT_CANMSG_BOX_SZ
15+
int "CAN message box size"
16+
default 16
17+
help
18+
Set the size of the CAN message box.
19+
20+
config RT_CANSND_BOX_NUM
21+
int "Number of CAN send queues"
22+
default 1
23+
help
24+
Set the number of CAN send queues.
25+
26+
config RT_CANSND_MSG_TIMEOUT
27+
int "CAN send message timeout"
28+
default 100
29+
help
30+
Set the timeout for CAN send messages.
31+
endif

components/drivers/can/dev_can.c

Lines changed: 28 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,16 @@ 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+
if (rt_completion_wait(&(tx_tosnd->completion), RT_CANSND_MSG_TIMEOUT) != RT_EOK)
170+
{
171+
level = rt_hw_interrupt_disable();
172+
rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
173+
can->status.sndchange &= ~ (1<<no);
174+
rt_hw_interrupt_enable(level);
175+
rt_sem_release(&(tx_fifo->sem));
176+
goto err_ret;
177+
}
170178

171179
level = rt_hw_interrupt_disable();
172180
result = tx_tosnd->result;
@@ -237,8 +245,12 @@ rt_inline int _can_int_tx_priv(struct rt_can_device *can, const struct rt_can_ms
237245
{
238246
continue;
239247
}
240-
can->status.sndchange = 1;
241-
rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_WAITING_FOREVER);
248+
can->status.sndchange |= 1<<no;
249+
if (rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_CANSND_MSG_TIMEOUT) != RT_EOK)
250+
{
251+
can->status.sndchange &= ~ (1<<no);
252+
continue;
253+
}
242254

243255
result = tx_fifo->buffer[no].result;
244256
if (result == RT_CAN_SND_RESULT_OK)
@@ -892,16 +904,18 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
892904
no = event >> 8;
893905
tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
894906
RT_ASSERT(tx_fifo != RT_NULL);
895-
896-
if ((event & 0xff) == RT_CAN_EVENT_TX_DONE)
907+
if (can->status.sndchange&(1<<no))
897908
{
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;
909+
if ((event & 0xff) == RT_CAN_EVENT_TX_DONE)
910+
{
911+
tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_OK;
912+
}
913+
else
914+
{
915+
tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_ERR;
916+
}
917+
rt_completion_done(&(tx_fifo->buffer[no].completion));
903918
}
904-
rt_completion_done(&(tx_fifo->buffer[no].completion));
905919
break;
906920
}
907921
}
@@ -972,3 +986,4 @@ int cmd_canstat(int argc, void **argv)
972986
}
973987
MSH_CMD_EXPORT_ALIAS(cmd_canstat, canstat, stat can device status);
974988
#endif
989+

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)