diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-07-12 14:29:08 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2011-07-12 14:29:08 +0000 |
commit | e6f4d56ce41c0e258632e9525b2e62dd17fe8273 (patch) | |
tree | 0be8c681d24f91bc218f1124ad14597f274a5371 | |
parent | 63a3dea74d1a3bb9b867016295079276036b72b5 (diff) | |
download | nuttx-e6f4d56ce41c0e258632e9525b2e62dd17fe8273.tar.gz nuttx-e6f4d56ce41c0e258632e9525b2e62dd17fe8273.tar.bz2 nuttx-e6f4d56ce41c0e258632e9525b2e62dd17fe8273.zip |
Correct error handling in the case of an overrun error in the serial driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3774 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | nuttx/ChangeLog | 9 | ||||
-rw-r--r-- | nuttx/drivers/serial/serialirq.c | 53 |
2 files changed, 41 insertions, 21 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 9e7bace44..8522f814b 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -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.
\ No newline at end of file + 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.
\ No newline at end of file diff --git a/nuttx/drivers/serial/serialirq.c b/nuttx/drivers/serial/serialirq.c index 18bca2e0c..22af6896f 100644 --- a/nuttx/drivers/serial/serialirq.c +++ b/nuttx/drivers/serial/serialirq.c @@ -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). + */ + + if (nexthead != dev->recv.tail) + { + /* Add the character to the buffer */ - dev->recv.buffer[dev->recv.head] = uart_receive(dev, &status); - nbytes++; + dev->recv.buffer[dev->recv.head] = ch; + nbytes++; - /* Increment the head index */ + /* Increment the head index */ - dev->recv.head = nexthead; - if (++nexthead >= dev->recv.size) - { - nexthead = 0; + 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) |