9
0
Fork 0

Correct error handling in the case of an overrun error in the serial driver

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3774 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2011-07-12 14:29:08 +00:00
parent 09a3f5701f
commit ec4e2f86f5
2 changed files with 42 additions and 22 deletions

View File

@ -1900,4 +1900,11 @@
* Makefile: Added a export target that will bundle up all of the NuttX
libraries, header files, and the startup object into an export-able
tarball.
tarball.
* arch/arm/src/lpc17xx/lpc17_can.h: Correct some typos in the CAN
register definitions.
* drivers/serial/serialirq.c: Correct an error that can occur if the
serial RX buffer becomes full. Data is now discarded in that case;
before, leaving data in the hardware would cause infinite interrupts
one most MCUs since you must read the data in order to clear the
interrupt.

View File

@ -1,7 +1,7 @@
/************************************************************************************
* drivers/serial/serialirq.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
@ -101,8 +101,8 @@ void uart_xmitchars(FAR uart_dev_t *dev)
}
}
/* When all of the characters have been sent from the buffer
* disable the TX interrupt.
/* When all of the characters have been sent from the buffer disable the TX
* interrupt.
*/
if (dev->xmit.head == dev->xmit.tail)
@ -110,8 +110,8 @@ void uart_xmitchars(FAR uart_dev_t *dev)
uart_disabletxint(dev);
}
/* If any bytes were removed from the buffer, inform any waiters
* there there is space available.
/* If any bytes were removed from the buffer, inform any waiters there there is
* space available.
*/
if (nbytes)
@ -126,8 +126,8 @@ void uart_xmitchars(FAR uart_dev_t *dev)
* Description:
* This function is called from the UART interrupt handler when an interrupt
* is received indicating that are bytes available in the receive fifo. This
* function will add chars to head of receive buffer. Driver read() logic will take
* characters from the tail of the buffer.
* function will add chars to head of receive buffer. Driver read() logic will
* take characters from the tail of the buffer.
*
************************************************************************************/
@ -142,28 +142,41 @@ void uart_recvchars(FAR uart_dev_t *dev)
nexthead = 0;
}
/* Loop putting characters into the receive buffer until either: (1) the buffer
* is full, or (2) there are no further characters to add.
/* Loop putting characters into the receive buffer until either there are no
* further characters to available.
*/
while (nexthead != dev->recv.tail && uart_rxavailable(dev))
while (uart_rxavailable(dev))
{
/* Add the character to the buffer */
char ch = uart_receive(dev, &status);
/* If the RX buffer becomes full, then the serial data is discarded. This is
* necessary because on most serial hardware, you must read the data in order
* to clear the RX interrupt. An option on some hardware might be to simply
* disable RX interrupts until the RX buffer becomes non-FULL. However, that
* would probably just cause the overrun to occur in hardware (unless it has
* some large internal buffering).
*/
dev->recv.buffer[dev->recv.head] = uart_receive(dev, &status);
nbytes++;
/* Increment the head index */
dev->recv.head = nexthead;
if (++nexthead >= dev->recv.size)
if (nexthead != dev->recv.tail)
{
nexthead = 0;
/* Add the character to the buffer */
dev->recv.buffer[dev->recv.head] = ch;
nbytes++;
/* Increment the head index */
dev->recv.head = nexthead;
if (++nexthead >= dev->recv.size)
{
nexthead = 0;
}
}
}
/* If any bytes were added to the buffer, inform any waiters
* there there is new incoming data available.
/* If any bytes were added to the buffer, inform any waiters there there is new
* incoming data available.
*/
if (nbytes)