Skip to content

Commit 44cf90a

Browse files
wdfk-progRbb666
authored andcommitted
fix(can): Resolve potential race condition in message transmission
Setting the send status flag `sndchange` after calling the can->ops->sendmsg function could lead to a race condition if a transmission timeout occurs, resulting in incorrect state handling. This patch moves the operation of setting the `sndchange` flag to before the call to can->ops->sendmsg. This ensures that the mailbox's status is correctly marked as "sending" before the hardware begins transmission, making the driver's state management more robust and reliable, especially in handling exceptions like timeouts. Additionally, new macros for CAN filter modes have been added in dev_can.h.
1 parent 2c92578 commit 44cf90a

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

components/drivers/can/dev_can.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
186186
no = ((rt_ubase_t)tx_tosnd - (rt_ubase_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list);
187187
tx_tosnd->result = RT_CAN_SND_RESULT_WAIT;
188188
rt_completion_init(&tx_tosnd->completion);
189+
can->status.sndchange |= 1<<no;
189190
if (can->ops->sendmsg(can, data, no) != RT_EOK)
190191
{
191192
/* send failed. */
@@ -196,7 +197,6 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
196197
goto err_ret;
197198
}
198199

199-
can->status.sndchange |= 1<<no;
200200
if (rt_completion_wait(&(tx_tosnd->completion), RT_CANSND_MSG_TIMEOUT) != RT_EOK)
201201
{
202202
level = rt_hw_local_irq_disable();
@@ -286,11 +286,12 @@ rt_inline int _can_int_tx_priv(struct rt_can_device *can, const struct rt_can_ms
286286
tx_fifo->buffer[no].result = RT_CAN_SND_RESULT_WAIT;
287287
rt_hw_local_irq_enable(level);
288288

289+
can->status.sndchange |= 1<<no;
289290
if (can->ops->sendmsg(can, data, no) != RT_EOK)
290291
{
291292
continue;
292293
}
293-
can->status.sndchange |= 1<<no;
294+
294295
if (rt_completion_wait(&(tx_fifo->buffer[no].completion), RT_CANSND_MSG_TIMEOUT) != RT_EOK)
295296
{
296297
can->status.sndchange &= ~ (1<<no);

components/drivers/include/drivers/dev_can.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ enum CANBAUD
6868
#define RT_CAN_MODE_PRIV 0x01
6969
#define RT_CAN_MODE_NOPRIV 0x00
7070

71+
#define RT_CAN_MODE_MASK 0x00
72+
#define RT_CAN_MODE_LIST 0x01
73+
7174
/**
7275
* @defgroup group_drivers_can CAN Driver
7376
* @brief CAN driver api

0 commit comments

Comments
 (0)