summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorliuyucai <[email protected]>2025-07-29 10:15:03 +0800
committerRbb666 <[email protected]>2025-07-29 20:18:14 +0800
commita1c642aa3a2848b47f2a1b52679dc4ee5156f2f4 (patch)
treeedd3003ddc42ab49851e92167ce36050d1f15790 /components
parentc209173061e7cda3af75935b9a206835f63a7963 (diff)
[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]>
Diffstat (limited to 'components')
-rw-r--r--components/drivers/can/Kconfig21
-rw-r--r--components/drivers/can/dev_can.c41
-rw-r--r--components/drivers/include/drivers/dev_can.h6
3 files changed, 53 insertions, 15 deletions
diff --git a/components/drivers/can/Kconfig b/components/drivers/can/Kconfig
index f4bc11dc86..c762a46d6b 100644
--- a/components/drivers/can/Kconfig
+++ b/components/drivers/can/Kconfig
@@ -6,7 +6,26 @@ if RT_USING_CAN
config RT_CAN_USING_HDR
bool "Enable CAN hardware filter"
default n
+
config RT_CAN_USING_CANFD
bool "Enable CANFD support"
default n
-endif
+
+ config RT_CANMSG_BOX_SZ
+ int "CAN message box size"
+ default 16
+ help
+ Set the size of the CAN message box.
+
+ config RT_CANSND_BOX_NUM
+ int "Number of CAN send queues"
+ default 1
+ help
+ Set the number of CAN send queues.
+
+ config RT_CANSND_MSG_TIMEOUT
+ int "CAN send message timeout"
+ default 100
+ help
+ Set the timeout for CAN send messages.
+endif \ No newline at end of file
diff --git a/components/drivers/can/dev_can.c b/components/drivers/can/dev_can.c
index 186f113828..8f70a1ddfb 100644
--- a/components/drivers/can/dev_can.c
+++ b/components/drivers/can/dev_can.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2024 RT-Thread Development Team
+ * Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -165,8 +165,16 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
goto err_ret;
}
- can->status.sndchange = 1;
- rt_completion_wait(&(tx_tosnd->completion), RT_WAITING_FOREVER);
+ can->status.sndchange |= 1<<no;
+ if (rt_completion_wait(&(tx_tosnd->completion), RT_CANSND_MSG_TIMEOUT) != RT_EOK)
+ {
+ level = rt_hw_interrupt_disable();
+ rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
+ can->status.sndchange &= ~ (1<<no);
+ rt_hw_interrupt_enable(level);
+ rt_sem_release(&(tx_fifo->sem));
+ goto err_ret;
+ }
level = rt_hw_interrupt_disable();
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
{
continue;
}
- can->status.sndchange = 1;
- rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_WAITING_FOREVER);
+ can->status.sndchange |= 1<<no;
+ if (rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_CANSND_MSG_TIMEOUT) != RT_EOK)
+ {
+ can->status.sndchange &= ~ (1<<no);
+ continue;
+ }
result = tx_fifo->buffer[no].result;
if (result == RT_CAN_SND_RESULT_OK)
@@ -892,16 +904,18 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
no = event >> 8;
tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
RT_ASSERT(tx_fifo != RT_NULL);
-
- if ((event & 0xff) == RT_CAN_EVENT_TX_DONE)
+ if (can->status.sndchange&(1<<no))
{
- tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_OK;
- }
- else
- {
- tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_ERR;
+ if ((event & 0xff) == RT_CAN_EVENT_TX_DONE)
+ {
+ tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_OK;
+ }
+ else
+ {
+ tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_ERR;
+ }
+ rt_completion_done(&(tx_fifo->buffer[no].completion));
}
- rt_completion_done(&(tx_fifo->buffer[no].completion));
break;
}
}
@@ -972,3 +986,4 @@ int cmd_canstat(int argc, void **argv)
}
MSH_CMD_EXPORT_ALIAS(cmd_canstat, canstat, stat can device status);
#endif
+
diff --git a/components/drivers/include/drivers/dev_can.h b/components/drivers/include/drivers/dev_can.h
index 35755dead0..81ea0927ed 100644
--- a/components/drivers/include/drivers/dev_can.h
+++ b/components/drivers/include/drivers/dev_can.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2024 RT-Thread Development Team
+ * Copyright (c) 2006-2025, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -21,6 +21,9 @@
#ifndef RT_CANSND_BOX_NUM
#define RT_CANSND_BOX_NUM 1
#endif
+#ifndef RT_CANSND_MSG_TIMEOUT
+#define RT_CANSND_MSG_TIMEOUT 100
+#endif
enum CAN_DLC
{
@@ -541,3 +544,4 @@ void rt_hw_can_isr(struct rt_can_device *can, int event);
/*! @}*/
#endif /*__DEV_CAN_H*/
+