Skip to content

Commit fce8348

Browse files
authored
[serial_v2] 修复阻塞模式下中断发送的逻辑顺序问题与多线程下的竞态条件 (#7997)
1 parent 2d630e3 commit fce8348

File tree

1 file changed

+14
-4
lines changed

1 file changed

+14
-4
lines changed

components/drivers/serial/serial_v2.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -533,16 +533,19 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
533533
(rt_uint8_t *)buffer + offset,
534534
size);
535535

536-
offset += tx_fifo->put_size;
537-
size -= tx_fifo->put_size;
538536
/* Call the transmit interface for transmission */
539537
serial->ops->transmit(serial,
540538
(rt_uint8_t *)buffer + offset,
541539
tx_fifo->put_size,
542540
RT_SERIAL_TX_BLOCKING);
541+
542+
offset += tx_fifo->put_size;
543+
size -= tx_fifo->put_size;
543544
/* Waiting for the transmission to complete */
544545
rt_completion_wait(&(tx_fifo->tx_cpt), RT_WAITING_FOREVER);
545546
}
547+
/* Finally Inactivate the tx->fifo */
548+
tx_fifo->activated = RT_FALSE;
546549

547550
return length;
548551
}
@@ -598,7 +601,7 @@ static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev,
598601
return length;
599602
}
600603

601-
/* If the activated mode is RT_FALSE, it means that serial device is transmitting,
604+
/* If the activated mode is RT_TRUE, it means that serial device is transmitting,
602605
* where only the data in the ringbuffer and there is no need to call the transmit() API.
603606
* Note that this part of the code requires disable interrupts
604607
* to prevent multi thread reentrant */
@@ -1551,13 +1554,20 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
15511554
* then the transmit completion callback is triggered*/
15521555
if (tx_length == 0)
15531556
{
1554-
tx_fifo->activated = RT_FALSE;
15551557
/* Trigger the transmit completion callback */
15561558
if (serial->parent.tx_complete != RT_NULL)
15571559
serial->parent.tx_complete(&serial->parent, RT_NULL);
15581560

1561+
/* Maybe some datas left in the buffer still need to be sent in block mode,
1562+
* so tx_fifo->activated should be RT_TRUE */
15591563
if (serial->parent.open_flag & RT_SERIAL_TX_BLOCKING)
1564+
{
15601565
rt_completion_done(&(tx_fifo->tx_cpt));
1566+
}
1567+
else
1568+
{
1569+
tx_fifo->activated = RT_FALSE;
1570+
}
15611571

15621572
break;
15631573
}

0 commit comments

Comments
 (0)