From 0b0001d83ed30bde3d20503140ed47090b36bfc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=92=99=E8=92=99plus?= Date: Thu, 19 Mar 2026 15:45:30 +0800 Subject: [PATCH] =?UTF-8?q?fix(can):=20=E8=BF=9E=E7=BB=AD=E5=A4=9A?= =?UTF-8?q?=E5=8C=85=E5=8F=91=E9=80=81=EF=BC=8C=E6=98=AF=E4=BC=A0=E8=BE=93?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E4=B8=8E=E5=BA=94=E7=94=A8=E5=B1=82=E8=B0=83?= =?UTF-8?q?=E7=94=A8=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/drivers/can/dev_can.c | 61 +++++++++++++++++--------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/components/drivers/can/dev_can.c b/components/drivers/can/dev_can.c index 04f12620f3e..3ce92fc1cc1 100644 --- a/components/drivers/can/dev_can.c +++ b/components/drivers/can/dev_can.c @@ -229,7 +229,7 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da } else { -err_ret: + err_ret: level = rt_hw_local_irq_disable(); can->status.dropedsndpkg++; rt_hw_local_irq_enable(level); @@ -345,34 +345,41 @@ static rt_ssize_t _can_nonblocking_tx(struct rt_can_device *can, const struct rt { return -RT_EINVAL; } - + level = rt_hw_local_irq_disable(); while (sent_size < size) { - if (can->ops->sendmsg_nonblocking(can, pmsg) == RT_EOK) + if (rt_ringbuffer_data_len(&can->nb_tx_rb) >= sizeof(struct rt_can_msg)) { - pmsg++; - sent_size += sizeof(struct rt_can_msg); - continue; + if (rt_ringbuffer_space_len(&can->nb_tx_rb) >= sizeof(struct rt_can_msg)) + { + rt_ringbuffer_put(&can->nb_tx_rb, (rt_uint8_t *)pmsg, sizeof(struct rt_can_msg)); + pmsg++; + sent_size += sizeof(struct rt_can_msg); + continue; + } + else + { + /* Buffer is full, cannot process this message or subsequent ones. */ + can->status.dropedsndpkg += (size - sent_size) / sizeof(struct rt_can_msg); + break; + } } - - level = rt_hw_local_irq_disable(); - if (rt_ringbuffer_space_len(&can->nb_tx_rb) >= sizeof(struct rt_can_msg)) + else { - rt_ringbuffer_put(&can->nb_tx_rb, (rt_uint8_t *)pmsg, sizeof(struct rt_can_msg)); rt_hw_local_irq_enable(level); + if (can->ops->sendmsg_nonblocking(can, pmsg) != RT_EOK) + { + level = rt_hw_local_irq_disable(); + rt_ringbuffer_put_force(&can->nb_tx_rb, (rt_uint8_t *)pmsg, sizeof(struct rt_can_msg)); + rt_hw_local_irq_enable(level); + } pmsg++; sent_size += sizeof(struct rt_can_msg); - } - else - { - /* Buffer is full, cannot process this message or subsequent ones. */ - can->status.dropedsndpkg += (size - sent_size) / sizeof(struct rt_can_msg); - rt_hw_local_irq_enable(level); - break; + level = rt_hw_local_irq_disable(); } } - + rt_hw_local_irq_enable(level); return sent_size; } @@ -409,7 +416,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag) struct rt_can_rx_fifo *rx_fifo; rx_fifo = (struct rt_can_rx_fifo *) rt_malloc(sizeof(struct rt_can_rx_fifo) + - can->config.msgboxsz * sizeof(struct rt_can_msg_list)); + can->config.msgboxsz * sizeof(struct rt_can_msg_list)); RT_ASSERT(rx_fifo != RT_NULL); rx_fifo->buffer = (struct rt_can_msg_list *)(rx_fifo + 1); @@ -441,12 +448,12 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag) struct rt_can_tx_fifo *tx_fifo; tx_fifo = (struct rt_can_tx_fifo *) rt_malloc(sizeof(struct rt_can_tx_fifo) + - can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); + can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); RT_ASSERT(tx_fifo != RT_NULL); tx_fifo->buffer = (struct rt_can_sndbxinx_list *)(tx_fifo + 1); rt_memset(tx_fifo->buffer, 0, - can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); + can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); rt_list_init(&tx_fifo->freelist); for (i = 0; i < can->config.sndboxnumber; i++) { @@ -725,7 +732,6 @@ static rt_err_t rt_can_control(struct rt_device *dev, } rt_hw_local_irq_enable(level); } - } else { @@ -1057,7 +1063,6 @@ void rt_hw_can_isr(struct rt_can_device *can, int event) listmsg->owner = &can->hdr[hdr]; can->hdr[hdr].msgs++; } - } #endif rt_hw_local_irq_enable(level); @@ -1132,7 +1137,8 @@ void rt_hw_can_isr(struct rt_can_device *can, int event) level = rt_hw_local_irq_disable(); if (rt_ringbuffer_data_len(&can->nb_tx_rb) >= sizeof(struct rt_can_msg)) { - rt_ringbuffer_get(&can->nb_tx_rb, (rt_uint8_t *)&msg_to_send, sizeof(struct rt_can_msg)); + struct rt_ringbuffer rb_shadow = can->nb_tx_rb; + rt_ringbuffer_get(&rb_shadow, (rt_uint8_t *)&msg_to_send, sizeof(struct rt_can_msg)); msg_was_present = RT_TRUE; } rt_hw_local_irq_enable(level); @@ -1141,14 +1147,13 @@ void rt_hw_can_isr(struct rt_can_device *can, int event) { break; } - if (can->ops->sendmsg_nonblocking(can, &msg_to_send) != RT_EOK) { - level = rt_hw_local_irq_disable(); - rt_ringbuffer_put_force(&can->nb_tx_rb, (rt_uint8_t *)&msg_to_send, sizeof(struct rt_can_msg)); - rt_hw_local_irq_enable(level); break; } + level = rt_hw_local_irq_disable(); + rt_ringbuffer_get(&can->nb_tx_rb, (rt_uint8_t *)&msg_to_send, sizeof(struct rt_can_msg)); + rt_hw_local_irq_enable(level); } } break;