[PATCH 5/8] termios: Change receive callback invocation

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Feb 23 14:45:37 UTC 2017


Call the receive callback in case a read will succeed without to block.
This enables the use of the receive callback for a poll() and select()
support.  Increase raw input buffer size to allow buffering of one line.
---
 cpukit/libcsupport/src/termios.c | 59 ++++++++++++++++++++++++++++++++--------
 1 file changed, 48 insertions(+), 11 deletions(-)

diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index dccdfd7..18fe269 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -84,7 +84,7 @@ int  rtems_termios_nlinesw =
 extern rtems_id rtems_termios_ttyMutex;
 
 static size_t rtems_termios_cbufsize = 256;
-static size_t rtems_termios_raw_input_size = 128;
+static size_t rtems_termios_raw_input_size = 256;
 static size_t rtems_termios_raw_output_size = 64;
 
 static const IMFS_node_control rtems_termios_imfs_node_control;
@@ -1282,11 +1282,8 @@ erase (struct rtems_termios_tty *tty, int lineFlag)
   }
 }
 
-/*
- * Process a single input character
- */
-static int
-iproc (unsigned char c, struct rtems_termios_tty *tty)
+static unsigned char
+iprocEarly (unsigned char c, rtems_termios_tty *tty)
 {
   if (tty->termios.c_iflag & ISTRIP)
     c &= 0x7f;
@@ -1302,6 +1299,15 @@ iproc (unsigned char c, struct rtems_termios_tty *tty)
       c = '\r';
   }
 
+  return c;
+}
+
+/*
+ * Process a single input character
+ */
+static int
+iproc (unsigned char c, struct rtems_termios_tty *tty)
+{
   if ((c != '\0') && (tty->termios.c_lflag & ICANON)) {
     if (c == tty->termios.c_cc[VERASE]) {
       erase (tty, 0);
@@ -1372,6 +1378,7 @@ siprocPoll (unsigned char c, rtems_termios_tty *tty)
     return 0;
   }
 
+  c = iprocEarly (c, tty);
   return siproc (c, tty);
 }
 
@@ -1568,6 +1575,26 @@ void rtems_termios_rxirq_occured(struct rtems_termios_tty *tty)
   rtems_event_send(tty->rxTaskId,TERMIOS_RX_PROC_EVENT);
 }
 
+static bool
+mustCallReceiveCallback (const rtems_termios_tty *tty, unsigned char c,
+                         unsigned int newTail, unsigned int head)
+{
+  if ((tty->termios.c_lflag & ICANON) != 0) {
+    return c == '\n' || c == tty->termios.c_cc[VEOF] ||
+      c == tty->termios.c_cc[VEOL] || c == tty->termios.c_cc[VEOL2];
+  } else {
+    unsigned int rawContentSize = (newTail - head + tty->rawInBuf.Size) %
+      tty->rawInBuf.Size;
+    cc_t vmin = tty->termios.c_cc[VMIN];
+
+    if (vmin == 0) {
+      vmin = 1;
+    }
+
+    return rawContentSize >= vmin;
+  }
+}
+
 /*
  * Place characters on raw queue.
  * NOTE: This routine runs in the context of the
@@ -1645,11 +1672,14 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
       unsigned int head;
       unsigned int oldTail;
       unsigned int newTail;
+      bool callReciveCallback;
 
       if (c == '\r' && (tty->termios.c_iflag & IGNCR) != 0) {
         continue;
       }
 
+      c = iprocEarly (c, tty);
+
       rtems_termios_device_lock_acquire (ctx, &lock_context);
 
       head = tty->rawInBuf.Head;
@@ -1680,22 +1710,29 @@ rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len)
         }
       }
 
+      callReciveCallback = false;
+
       if (newTail != head) {
         tty->rawInBuf.theBuf[newTail] = c;
         tty->rawInBuf.Tail = newTail;
 
-        rtems_termios_device_lock_release (ctx, &lock_context);
-
         /*
          * check to see if rcv wakeup callback was set
          */
         if (tty->tty_rcv.sw_pfn != NULL && !tty->tty_rcvwakeup) {
-          tty->tty_rcvwakeup = true;
-          (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
+          if (mustCallReceiveCallback (tty, c, newTail, head)) {
+            tty->tty_rcvwakeup = true;
+            callReciveCallback = true;
+          }
         }
       } else {
         ++dropped;
-        rtems_termios_device_lock_release (ctx, &lock_context);
+      }
+
+      rtems_termios_device_lock_release (ctx, &lock_context);
+
+      if (callReciveCallback) {
+        (*tty->tty_rcv.sw_pfn)(&tty->termios, tty->tty_rcv.sw_arg);
       }
     }
   }
-- 
1.8.4.5




More information about the devel mailing list