From 1bb21b43f79bc9384f60acd3c75cda1715f26a07 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 30 Jan 2015 08:09:38 -0600 Subject: Networking: SLIP interface improvements. From Macs N. --- nuttx/drivers/net/slip.c | 149 +++++++++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 57 deletions(-) diff --git a/nuttx/drivers/net/slip.c b/nuttx/drivers/net/slip.c index 0e94ce382..09f5cd3f6 100644 --- a/nuttx/drivers/net/slip.c +++ b/nuttx/drivers/net/slip.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/slip.c * - * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Reference: RFC 1055 @@ -56,6 +56,7 @@ #include #include +#include #include #include #include @@ -158,11 +159,12 @@ struct slip_statistics_s struct slip_driver_s { volatile bool bifup; /* true:ifup false:ifdown */ - int fd; /* TTY file descriptor */ + bool txnodelay; /* True: usleep() not needed */ + int16_t fd; /* TTY file descriptor */ + uint16_t rxlen; /* The number of bytes in rxbuf */ pid_t rxpid; /* Receiver thread ID */ pid_t txpid; /* Transmitter thread ID */ sem_t waitsem; /* Mutually exclusive access to uIP */ - uint16_t rxlen; /* The number of bytes in rxbuf */ /* Driver statistics */ @@ -195,7 +197,8 @@ static void slip_semtake(FAR struct slip_driver_s *priv); /* Common TX logic */ -static void slip_write(FAR struct slip_driver_s *priv, const uint8_t *buffer, int len); +static void slip_write(FAR struct slip_driver_s *priv, + FAR const uint8_t *buffer, int len); static void slip_putc(FAR struct slip_driver_s *priv, int ch); static int slip_transmit(FAR struct slip_driver_s *priv); static int slip_txpoll(FAR struct net_driver_s *dev); @@ -255,7 +258,7 @@ static void slip_semtake(FAR struct slip_driver_s *priv) ****************************************************************************/ static inline void slip_write(FAR struct slip_driver_s *priv, - const uint8_t *buffer, int len) + FAR const uint8_t *buffer, int len) { /* Handle the case where the write is awakened by a signal */ @@ -390,6 +393,7 @@ static int slip_transmit(FAR struct slip_driver_s *priv) /* And send the END token */ slip_putc(priv, SLIP_END); + priv->txnodelay = true; return OK; } @@ -454,6 +458,9 @@ static void slip_txtask(int argc, FAR char *argv[]) FAR struct slip_driver_s *priv; unsigned int index = *(argv[1]) - '0'; net_lock_t flags; + unsigned int msec_start; + unsigned int msec_now; + unsigned int hsec; ndbg("index: %d\n", index); DEBUGASSERT(index < CONFIG_SLIP_NINTERFACES); @@ -467,11 +474,22 @@ static void slip_txtask(int argc, FAR char *argv[]) /* Loop forever */ + msec_start = clock_systimer() * MSEC_PER_TICK; for (;;) { /* Wait for the timeout to expire (or until we are signaled by by */ - usleep(SLIP_WDDELAY); + slip_semtake(priv); + if (!priv->txnodelay) + { + slip_semgive(priv); + usleep(SLIP_WDDELAY); + } + else + { + priv->txnodelay = false; + slip_semgive(priv); + } /* Is the interface up? */ @@ -483,15 +501,23 @@ static void slip_txtask(int argc, FAR char *argv[]) slip_semtake(priv); - /* Poll uIP for new XMIT data. BUG: We really need to calculate - * the number of hsecs! When we are awakened by slip_txavail, the - * number will be smaller; when we have to wait for the semaphore - * (above), it may be larger. - */ + /* Poll the networking layer for new XMIT data. */ flags = net_lock(); priv->dev.d_buf = priv->txbuf; - (void)devif_timer(&priv->dev, slip_txpoll, SLIP_POLLHSEC); + + msec_now = clock_systimer() * MSEC_PER_TICK; + hsec = (unsigned int)(msec_now - msec_start) / (MSEC_PER_SEC / 2); + if (hsec) + { + (void)devif_timer(&priv->dev, slip_txpoll, hsec); + msec_start += hsec * (MSEC_PER_SEC / 2); + } + else + { + (void)uip_poll(&priv->dev, slip_uiptxpoll); + } + net_unlock(flags); slip_semgive(priv); } @@ -563,19 +589,21 @@ static inline void slip_receive(FAR struct slip_driver_s *priv) */ case SLIP_END: - nvdbg("END\n"); - - /* A minor optimization: if there is no data in the packet, ignore - * it. This is meant to avoid bothering IP with all the empty - * packets generated by the duplicate END characters which are in - * turn sent to try to detect line noise. - */ - - if (priv->rxlen > 0) - { - nvdbg("Received packet size %d\n", priv->rxlen); - return; - } + { + nvdbg("END\n"); + + /* A minor optimization: if there is no data in the packet, + * ignore it. This is meant to avoid bothering IP with all the + * empty packets generated by the duplicate END characters which + * are in turn sent to try to detect line noise. + */ + + if (priv->rxlen > 0) + { + nvdbg("Received packet size %d\n", priv->rxlen); + return; + } + } break; /* if it's the same code as an ESC character, wait and get another @@ -584,38 +612,44 @@ static inline void slip_receive(FAR struct slip_driver_s *priv) */ case SLIP_ESC: - nvdbg("ESC\n"); - ch = slip_getc(priv); - - /* if "ch" is not one of these two, then we have a protocol - * violation. The best bet seems to be to leave the byte alone - * and just stuff it into the packet - */ - - switch (ch) - { - case SLIP_ESC_END: - nvdbg("ESC-END\n"); - ch = SLIP_END; - break; - case SLIP_ESC_ESC: - nvdbg("ESC-ESC\n"); - ch = SLIP_ESC; - break; - default: - ndbg("ERROR: Protocol violation: %02x\n", ch); - break; - } - - /* Here we fall into the default handler and let it store the - * character for us - */ + { + nvdbg("ESC\n"); + ch = slip_getc(priv); + + /* if "ch" is not one of these two, then we have a protocol + * violation. The best bet seems to be to leave the byte alone + * and just stuff it into the packet + */ + + switch (ch) + { + case SLIP_ESC_END: + nvdbg("ESC-END\n"); + ch = SLIP_END; + break; + + case SLIP_ESC_ESC: + nvdbg("ESC-ESC\n"); + ch = SLIP_ESC; + break; + + default: + ndbg("ERROR: Protocol violation: %02x\n", ch); + break; + } + + /* Here we fall into the default handler and let it store the + * character for us + */ + } default: - if (priv->rxlen < CONFIG_NET_SLIP_MTU+2) - { - priv->rxbuf[priv->rxlen++] = ch; - } + { + if (priv->rxlen < CONFIG_NET_SLIP_MTU+2) + { + priv->rxbuf[priv->rxlen++] = ch; + } + } break; } } @@ -724,6 +758,7 @@ static int slip_rxtask(int argc, FAR char *argv[]) if (priv->dev.d_len > 0) { slip_transmit(priv); + kill(priv->txpid, SIGALRM); } net_unlock(flags); slip_semgive(priv); @@ -822,6 +857,7 @@ static int slip_txavail(FAR struct net_driver_s *dev) { /* Wake up the TX polling thread */ + priv->txnodelay = true; kill(priv->txpid, SIGALRM); } @@ -912,7 +948,7 @@ int slip_initialize(int intf, FAR const char *devname) { FAR struct slip_driver_s *priv; char buffer[8]; - FAR const char *argv[2]; + FAR char *argv[2]; /* Get the interface structure associated with this interface number. */ @@ -1002,4 +1038,3 @@ int slip_initialize(int intf, FAR const char *devname) } #endif /* CONFIG_NET && CONFIG_NET_SLIP */ - -- cgit v1.2.3