This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: RedBoot gets() problems



On 02-Mar-2001 Grant Edwards wrote:
>> and should not be encumbered on every input character, thus the
>> choice to only make such a check when the "console" port is
>> idle.
> 
> That cost is already incurred.  If the gap between rx
> characters is smaller than the time it takes to do a network
> poll, then initial characters in a command can be lost.  If I
> send a command line to the board at 57600 baud, I generally
> loose 2-3 characters due to the fact that rx characters are
> only processed between network polls.
> 

This is probably not the problem.  The true problem was that the
timeouts were not being handled properly if you have multiple 
serial channels and were scanning for a console to use.  In this
case, the old code would have waited for 10/N ms (where N is the
number of channels) on each channel before deciding that any
characters have arrived.  If N is 2, then this is 5 ms.  At a
baud rate of 57600, 5ms represents as many as 15 characters!
Thus, a bunch of characters could arrive on one channel while the
code was waiting for the other.

This patch will make it better, by forcing each channel to timeout
as fast as possible (sorry, but the granularity is only 1ms).

I'm still thinking about how [limited] network processing can take
place between characters.  However, I'm not convinced that RedBoot
is the place to be doing such processing.  It would seem to me that
if you need more processing and higher response rates, you should
really have a real application running, using interrupts, etc.
... but that's probably a whole different discussion.

 
Index: redboot/current/src/io.c
===================================================================
RCS file: /home/cvs/ecc/ecc/redboot/current/src/io.c,v
retrieving revision 1.20
diff -u -5 -p -r1.20 io.c
--- redboot/current/src/io.c    2001/01/17 13:50:59     1.20
+++ redboot/current/src/io.c    2001/03/03 13:20:26
@@ -88,32 +88,39 @@ mon_read_char(char *c)
         __chan = CYGACC_CALL_IF_DEBUG_PROCS();
         *c = CYGACC_COMM_IF_GETC(*__chan);
     }
 }
 
+#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
+static int _mon_timeout;
+#endif
+
 static bool
 mon_read_char_with_timeout(char *c)
 {
-    bool res;
+    bool res = false;
     hal_virtual_comm_table_t *__chan;
 
 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
     if (!console_selected) {
         int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
-        int i;
+        int i, tot;
         // Try input from all channels
-        for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  i++) {
-            CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
-            __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
-            res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c);
-            if (res) {
-                // Input available on this channel, make it be the console
-                if (*c != '\0') {
-                    // Don't chose this unless real data have arrived
-                    console_selected = true;
-                    CYGACC_CALL_IF_SET_DEBUG_COMM(i);
-                    return res;
+        tot = 0;
+        while (tot < _mon_timeout) {
+            for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  i++, tot++) {
+                CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
+                __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+                res = CYGACC_COMM_IF_GETC_TIMEOUT(*__chan, c);
+                if (res) {
+                    // Input available on this channel, make it be the console
+                    if (*c != '\0') {
+                        // Don't chose this unless real data have arrived
+                        console_selected = true;
+                        CYGACC_CALL_IF_SET_DEBUG_COMM(i);
+                        return res;
+                    }
                 }
             }
         }
         CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);        
     } else 
@@ -137,12 +144,13 @@ mon_set_read_char_timeout(int ms)
 
 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
     if (!console_selected) {
         int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
         int i;
-        // Set timeout on each channel so total amounts to desired value
-        ms = ms / CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;
+        // Set timeout to minimum on each channel; total amounts to desired value
+        _mon_timeout = ms;
+        ms = 1;
         for (i = 0;  i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS;  i++) {
             CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
             if ((__chan = CYGACC_CALL_IF_CONSOLE_PROCS()) != 0) {
                 CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_SET_TIMEOUT, ms);
             }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]