summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorJaeyeong Lee <[email protected]>2026-08-29 20:48:24 +0900
committerRbb666 <[email protected]>2026-10-11 17:37:11 +0800
commit8a3ca7bfa3fb0b779fe24fd912a3a72cc2aeb59d (patch)
tree3c816b64788d3f5bb77372fe1804e63a2a60eb90 /components
parent3577e7a6ed0f183534e207179de5251e155fd49e (diff)
fix[usb]: stop aliasing rt_ringbuffer as rt_serial_rx_fifo in VCOM
With RT_USB_DEVICE_CDC and RT_USING_SERIAL_V2 both enabled, _function_enable assigned the embedded rx_ringbuffer to serial.serial_rx. Serial V2 reads that pointer as a struct rt_serial_rx_fifo, whose first member is a rt_ringbuffer, so ring-buffer access happened to work while rx_cpt, rx_cpt_index and rx_timeout landed on the following members of struct vcom, corrupting tx_rbp. The layout shifts again with RT_SERIAL_USING_DMA, which inserts dma_ping_rb ahead of those fields. Serial V2 already owns the receive FIFO: dev_serial_v2.c allocates it with rt_malloc on open and releases it with rt_free on close, so the assignment also made rt_free run on memory inside struct vcom. Drop the assignment and read the FIFO Serial V2 owns. rt_hw_serial_isr reports RX_IND from serial_rx->rb, so the endpoint handler now fills that ring buffer and _vcom_getc drains it. The Serial V1 path is unchanged. Fixes #11739 Signed-off-by: Jaeyeong Lee <[email protected]>
Diffstat (limited to 'components')
-rw-r--r--components/legacy/usb/usbdevice/class/cdc_vcom.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/components/legacy/usb/usbdevice/class/cdc_vcom.c b/components/legacy/usb/usbdevice/class/cdc_vcom.c
index 44f013f005..7d4463ea89 100644
--- a/components/legacy/usb/usbdevice/class/cdc_vcom.c
+++ b/components/legacy/usb/usbdevice/class/cdc_vcom.c
@@ -338,6 +338,9 @@ static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size)
{
rt_base_t level;
struct vcom *data;
+#ifdef RT_USING_SERIAL_V2
+ struct rt_serial_rx_fifo *rx_fifo;
+#endif
RT_ASSERT(func != RT_NULL);
@@ -351,7 +354,15 @@ static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size)
/* receive data from USB VCOM */
level = rt_hw_interrupt_disable();
+#ifdef RT_USING_SERIAL_V2
+ rx_fifo = (struct rt_serial_rx_fifo *)data->serial.serial_rx;
+ if (rx_fifo != RT_NULL)
+ {
+ rt_ringbuffer_put(&rx_fifo->rb, data->ep_out->buffer, size);
+ }
+#else
rt_ringbuffer_put(&data->rx_ringbuffer, data->ep_out->buffer, size);
+#endif
rt_hw_interrupt_enable(level);
/* notify receive data */
@@ -514,10 +525,6 @@ static rt_err_t _function_enable(ufunction_t func)
data->ep_out->buffer = rt_malloc(CDC_RX_BUFSIZE);
RT_ASSERT(data->ep_out->buffer != RT_NULL);
-#ifdef RT_USING_SERIAL_V2
- data->serial.serial_rx = &data->rx_ringbuffer;
-#endif
-
data->ep_out->request.buffer = data->ep_out->buffer;
data->ep_out->request.size = EP_MAXPACKET(data->ep_out);
@@ -719,18 +726,30 @@ static int _vcom_getc(struct rt_serial_device *serial)
rt_base_t level;
struct ufunction *func;
struct vcom *data;
+#ifdef RT_USING_SERIAL_V2
+ struct rt_serial_rx_fifo *rx_fifo;
+#endif
func = (struct ufunction*)serial->parent.user_data;
data = (struct vcom*)func->user_data;
+ RT_UNUSED(data);
result = -1;
level = rt_hw_interrupt_disable();
+#ifdef RT_USING_SERIAL_V2
+ rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
+ if(rx_fifo != RT_NULL && rt_ringbuffer_getchar(&rx_fifo->rb, &ch) != 0)
+ {
+ result = ch;
+ }
+#else
if(rt_ringbuffer_getchar(&data->rx_ringbuffer, &ch) != 0)
{
result = ch;
}
+#endif
rt_hw_interrupt_enable(level);