Merged in masayuki2009/nuttx.nuttx/fix_serial_driver_for_smp (pull request #1052)

drivers: serial: Fix data corruption when outputting data in SMP mode

Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>

Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
Masayuki Ishikawa
2019-10-16 13:09:03 +00:00
committed by Gregory Nutt
parent 78d68fe8cc
commit dacd041a94
2 changed files with 33 additions and 5 deletions
+21 -5
View File
@@ -229,6 +229,10 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock)
int nexthead; int nexthead;
int ret; int ret;
#ifdef CONFIG_SMP
flags = enter_critical_section();
#endif
/* Increment to see what the next head pointer will be. We need to use the "next" /* Increment to see what the next head pointer will be. We need to use the "next"
* head pointer to determine when the circular buffer would overrun * head pointer to determine when the circular buffer would overrun
*/ */
@@ -251,7 +255,8 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock)
dev->xmit.buffer[dev->xmit.head] = ch; dev->xmit.buffer[dev->xmit.head] = ch;
dev->xmit.head = nexthead; dev->xmit.head = nexthead;
return OK; ret = OK;
goto err_out;
} }
/* The TX buffer is full. Should be block, waiting for the hardware /* The TX buffer is full. Should be block, waiting for the hardware
@@ -325,7 +330,8 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock)
if (dev->disconnected) if (dev->disconnected)
{ {
return -ENOTCONN; ret = -ENOTCONN;
goto err_out;
} }
#endif #endif
/* Check if we were awakened by signal. */ /* Check if we were awakened by signal. */
@@ -336,7 +342,8 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock)
* non-full will abort the transfer. * non-full will abort the transfer.
*/ */
return -EINTR; ret = -EINTR;
goto err_out;
} }
} }
@@ -346,7 +353,8 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock)
else else
{ {
return -EAGAIN; ret = -EAGAIN;
goto err_out;
} }
} }
@@ -354,7 +362,15 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, bool oktoblock)
* unreachable. * unreachable.
*/ */
return OK; ret = OK;
err_out:
#ifdef CONFIG_SMP
leave_critical_section(flags);
#endif
return ret;
} }
/************************************************************************************ /************************************************************************************
+12
View File
@@ -39,6 +39,10 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#ifdef CONFIG_SMP
# include <nuttx/irq.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#include <stdint.h> #include <stdint.h>
#include <semaphore.h> #include <semaphore.h>
@@ -65,6 +69,10 @@ void uart_xmitchars(FAR uart_dev_t *dev)
{ {
uint16_t nbytes = 0; uint16_t nbytes = 0;
#ifdef CONFIG_SMP
irqstate_t flags = enter_critical_section();
#endif
/* Send while we still have data in the TX buffer & room in the fifo */ /* Send while we still have data in the TX buffer & room in the fifo */
while (dev->xmit.head != dev->xmit.tail && uart_txready(dev)) while (dev->xmit.head != dev->xmit.tail && uart_txready(dev))
@@ -104,6 +112,10 @@ void uart_xmitchars(FAR uart_dev_t *dev)
{ {
uart_datasent(dev); uart_datasent(dev);
} }
#ifdef CONFIG_SMP
leave_critical_section(flags);
#endif
} }
/************************************************************************************ /************************************************************************************