mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 01:05:54 +08:00
Add poll method to serial drivers
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1268 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
+116
-53
@@ -57,6 +57,17 @@
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_DEV_CONSOLE) && !defined(CONFIG_DEV_LOWCONSOLE)
|
||||
# define HAVE_CONSOLE
|
||||
# define NPOLLFDS 2
|
||||
# define CONSNDX 0
|
||||
# define FIFONDX 1
|
||||
#else
|
||||
# undef HAVE_CONSOLE
|
||||
# define NPOLLFDS 1
|
||||
# define FIFONDX 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@@ -79,13 +90,15 @@
|
||||
|
||||
void *poll_listener(pthread_addr_t pvarg)
|
||||
{
|
||||
struct pollfd fds;
|
||||
struct pollfd fds[NPOLLFDS];
|
||||
char buffer[64];
|
||||
ssize_t nbytes;
|
||||
boolean timeout;
|
||||
boolean pollin;
|
||||
int nevents;
|
||||
int fd;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* Open the FIFO for non-blocking read */
|
||||
|
||||
@@ -105,15 +118,20 @@ void *poll_listener(pthread_addr_t pvarg)
|
||||
{
|
||||
message("poll_listener: Calling poll()\n");
|
||||
|
||||
memset(&fds, 0, sizeof(struct pollfd));
|
||||
fds.fd = fd;
|
||||
fds.events = POLLIN;
|
||||
fds.revents = 0;
|
||||
memset(fds, 0, sizeof(struct pollfd)*NPOLLFDS);
|
||||
#ifdef HAVE_CONSOLE
|
||||
fds[CONSNDX].fd = 0;
|
||||
fds[CONSNDX].events = POLLIN;
|
||||
fds[CONSNDX].revents = 0;
|
||||
#endif
|
||||
fds[FIFONDX].fd = fd;
|
||||
fds[FIFONDX].events = POLLIN;
|
||||
fds[FIFONDX].revents = 0;
|
||||
|
||||
timeout = FALSE;
|
||||
pollin = FALSE;
|
||||
timeout = FALSE;
|
||||
pollin = FALSE;
|
||||
|
||||
ret = poll(&fds, 1, POLL_LISTENER_DELAY);
|
||||
ret = poll(fds, NPOLLFDS, POLL_LISTENER_DELAY);
|
||||
|
||||
message("\npoll_listener: poll returned: %d\n", ret);
|
||||
if (ret < 0)
|
||||
@@ -122,71 +140,116 @@ void *poll_listener(pthread_addr_t pvarg)
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
message("poll_listener: Timeout, revents=%02x\n", fds.revents);
|
||||
message("poll_listener: Timeout\n");
|
||||
timeout = TRUE;
|
||||
if (fds.revents != 0)
|
||||
{
|
||||
message("poll_listener: ERROR? expected revents=00, received revents=%02x\n",
|
||||
fds.revents);
|
||||
}
|
||||
}
|
||||
else if (ret > NPOLLFDS)
|
||||
{
|
||||
message("poll_listener: ERROR poll reported: %d\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ret != 1)
|
||||
{
|
||||
message("poll_listener: ERROR poll reported: %d\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
pollin = TRUE;
|
||||
}
|
||||
pollin = TRUE;
|
||||
}
|
||||
|
||||
message("poll_listener: revents=%02x\n", fds.revents);
|
||||
if (fds.revents != POLLIN)
|
||||
nevents = 0;
|
||||
for (i = 0; i < NPOLLFDS; i++)
|
||||
{
|
||||
message("poll_listener: FIFO revents[%d]=%02x\n", i, fds[i].revents);
|
||||
if (timeout)
|
||||
{
|
||||
message("poll_listener: ERROR expected revents=%02x, received revents=%02x\n",
|
||||
fds.revents);
|
||||
message(" (might just be a race condition)\n");
|
||||
if (fds[i].revents != 0)
|
||||
{
|
||||
message("poll_listener: ERROR? expected revents=00, received revents[%d]=%02x\n",
|
||||
fds[i].revents, i);
|
||||
}
|
||||
}
|
||||
else if (pollin)
|
||||
{
|
||||
if (fds[i].revents == POLLIN)
|
||||
{
|
||||
nevents++;
|
||||
}
|
||||
else if (fds[i].revents != 0)
|
||||
{
|
||||
message("poll_listener: ERROR unexpected revents[i]=%02x\n",
|
||||
i, fds[i].revents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In any event, read until the pipe is empty */
|
||||
|
||||
do
|
||||
if (pollin && nevents != ret)
|
||||
{
|
||||
nbytes = read(fd, buffer, 63);
|
||||
if (nbytes <= 0)
|
||||
message("poll_listener: ERROR found %d events, poll reported %d\n", nevents, ret);
|
||||
}
|
||||
|
||||
/* In any event, read until the pipe/serial is empty */
|
||||
|
||||
for (i = 0; i < NPOLLFDS; i++)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (nbytes == 0 || errno == EAGAIN)
|
||||
#ifdef HAVE_CONSOLE
|
||||
/* Hack to work around the fact that the console driver on the
|
||||
* simulator is always non-blocking.
|
||||
*/
|
||||
|
||||
if (i == CONSNDX)
|
||||
{
|
||||
if (pollin)
|
||||
if ((fds[CONSNDX].revents & POLLIN) != 0)
|
||||
{
|
||||
message("poll_listener: ERROR no read data\n");
|
||||
buffer[0] = getchar();
|
||||
nbytes = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nbytes = 0;
|
||||
}
|
||||
}
|
||||
else if (errno != EINTR)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
message("poll_listener: read failed: %d\n", errno);
|
||||
}
|
||||
nbytes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeout)
|
||||
{
|
||||
message("poll_listener: ERROR? Poll timeout, but data read\n");
|
||||
message(" (might just be a race condition)\n");
|
||||
/* The pipe works differently, it returns whatever data
|
||||
* it has available without blocking.
|
||||
*/
|
||||
|
||||
nbytes = read(fds[i].fd, buffer, 63);
|
||||
}
|
||||
|
||||
buffer[nbytes] = '\0';
|
||||
message("poll_listener: Read '%s' (%d bytes)\n", buffer, nbytes);
|
||||
}
|
||||
if (nbytes <= 0)
|
||||
{
|
||||
if (nbytes == 0 || errno == EAGAIN)
|
||||
{
|
||||
if ((fds[i].revents & POLLIN) != 0)
|
||||
{
|
||||
message("poll_listener: ERROR no read data[%d]\n", i);
|
||||
}
|
||||
}
|
||||
else if (errno != EINTR)
|
||||
{
|
||||
message("poll_listener: read[%d] failed: %d\n", i, errno);
|
||||
}
|
||||
nbytes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeout)
|
||||
{
|
||||
message("poll_listener: ERROR? Poll timeout, but data read[%d]\n", i);
|
||||
message(" (might just be a race condition)\n");
|
||||
}
|
||||
|
||||
timeout = FALSE;
|
||||
pollin = FALSE;
|
||||
buffer[nbytes] = '\0';
|
||||
message("poll_listener: Read[%d] '%s' (%d bytes)\n", i, buffer, nbytes);
|
||||
}
|
||||
|
||||
/* Suppress error report if no read data on the next time through */
|
||||
|
||||
fds[i].revents = 0;
|
||||
}
|
||||
while (nbytes > 0);
|
||||
}
|
||||
while (nbytes > 0);
|
||||
|
||||
|
||||
/* Make sure that everything is displayed */
|
||||
|
||||
msgflush();
|
||||
|
||||
Reference in New Issue
Block a user