diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-10-09 19:20:02 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-10-09 19:20:02 +0000 |
commit | fd55042e823c1d6816caf1df68a57f4ae55491c3 (patch) | |
tree | e4b4ef16fb0e732b08c48f6cf16c2ad21764d41f | |
parent | a012cfa8dbb317c36eaf4ef9e6657907e649f2f4 (diff) | |
download | px4-nuttx-fd55042e823c1d6816caf1df68a57f4ae55491c3.tar.gz px4-nuttx-fd55042e823c1d6816caf1df68a57f4ae55491c3.tar.bz2 px4-nuttx-fd55042e823c1d6816caf1df68a57f4ae55491c3.zip |
Fixe open count error + O_NONBLOCK function
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1013 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r-- | nuttx/ChangeLog | 1 | ||||
-rw-r--r-- | nuttx/Documentation/NuttX.html | 3 | ||||
-rw-r--r-- | nuttx/drivers/serial.c | 57 |
3 files changed, 47 insertions, 14 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index b1589b13a..181967a05 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -491,6 +491,7 @@ * Add LPC214x USB serial configuration; Add examples/usbserial test (still a work in progress) * Added USB device side driver for the DM320 (untested at initial checkin) * Fixed an error in a previous (post 0.3.15) check-in that broke the LPC214x system timer. + * Fixed serial drive bugs related to (1) open counts and (2) recognizing O_NONBLOCK on read. diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html index e9376d5a3..09f2b465c 100644 --- a/nuttx/Documentation/NuttX.html +++ b/nuttx/Documentation/NuttX.html @@ -8,7 +8,7 @@ <tr align="center" bgcolor="#e4e4e4"> <td> <h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1> - <p>Last Updated: October 7, 2008</p> + <p>Last Updated: October 9, 2008</p> </td> </tr> </table> @@ -1081,6 +1081,7 @@ nuttx-0.3.16 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> * Add LPC214x USB serial configuration; Add examples/usbserial test (still a work in progress) * Added USB device side driver for the DM320 (untested at initial checkin) * Fixed an error in a previous (post 0.3.15) check-in that broke the LPC214x system timer. + * Fixed serial drive bugs related to (1) open counts and (2) recognizing O_NONBLOCK on read. pascal-0.1.3 2008-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> diff --git a/nuttx/drivers/serial.c b/nuttx/drivers/serial.c index 3d0536604..bd4ca33e7 100644 --- a/nuttx/drivers/serial.c +++ b/nuttx/drivers/serial.c @@ -38,12 +38,15 @@ ************************************************************************************/ #include <nuttx/config.h> + #include <sys/types.h> #include <unistd.h> #include <semaphore.h> #include <string.h> +#include <fcntl.h> #include <errno.h> #include <debug.h> + #include <nuttx/irq.h> #include <nuttx/arch.h> #include <nuttx/fs.h> @@ -254,7 +257,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen { FAR struct inode *inode = filep->f_inode; FAR uart_dev_t *dev = inode->i_private; - ssize_t ret = buflen; + ssize_t recvd = 0; /* Only one user can be accessing dev->recv.tail at once */ @@ -266,22 +269,50 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen */ uart_disablerxint(dev); - while (buflen) + while (recvd < buflen) { + /* Check if there is more data to return in the circular buffer */ + if (dev->recv.head != dev->recv.tail) { *buffer++ = dev->recv.buffer[dev->recv.tail]; - buflen--; + recvd++; if (++(dev->recv.tail) >= dev->recv.size) { dev->recv.tail = 0; } } + + /* No... then we would have to wait to get receive more data. + * If the user has specified the O_NONBLOCK option, then do not + * return what we have. + */ + + else if (filep->f_oflags & O_NONBLOCK) + { + /* If nothing was transferred, then return the -EAGAIN + * error (not zero which means end of file). + */ + + if (recvd < 1) + { + recvd = -EAGAIN; + } + + /* Break out of the loop and return the number of bytes + * received up to the wait condition. + */ + + break; + } + + /* Otherwise we are going to wait */ + else { /* Wait for some characters to be sent from the buffer - * with the TX interrupt disabled. + * with the TX interrupt re-enabled. */ dev->recvwaiting = TRUE; @@ -293,7 +324,7 @@ static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen uart_enablerxint(dev); uart_givesem(&dev->recv.sem); - return ret; + return recvd; } /************************************************************************************ @@ -421,7 +452,8 @@ static int uart_open(FAR struct file *filep) ret = uart_setup(dev); if (ret < 0) { - goto errout_with_irqsdisabled; + irqrestore(flags); + goto errout_with_sem; } } @@ -435,7 +467,8 @@ static int uart_open(FAR struct file *filep) if (ret < 0) { uart_shutdown(dev); - goto errout_with_irqsdisabled; + irqrestore(flags); + goto errout_with_sem; } /* Mark the io buffers empty */ @@ -448,15 +481,13 @@ static int uart_open(FAR struct file *filep) /* Enable the RX interrupt */ uart_enablerxint(dev); - - /* Save the new open count on success */ - - dev->open_count = tmp; - -errout_with_irqsdisabled: irqrestore(flags); } + /* Save the new open count on success */ + + dev->open_count = tmp; + errout_with_sem: uart_givesem(&dev->closesem); return ret; |