This is the mail archive of the ecos-discuss@sourceware.org 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]
Other format: [Raw text]

Re: DSR Scheduling Problem


Grant Edwards <grante@visi.com> writes:

> On 2006-01-14, Paul D. DeRocco <pderocco@ix.netcom.com> wrote:
>
>> If the transmitter has a hardware FIFO, and the software
>> transmits one byte per interrupt,
>
> Then the sofware is completely and utterly broken.  It doesn't
> deserve to work.
>
>> then presenting a block of data to it after an idle period
>> will invoke the ISR/DSR a slew of times until the FIFO is
>> full.
>
> That's insane. Nobody with a clue would write software like that.

Actually, the generic 16x5x serial driver in eCos works exactly like
that.

> When you get a TX interrupt you write data to the tx FIFO until it's
> full.

Yep. I've made a somewhat quick-and-dirty fix that is attached below.


Regards,
-- 
Daniel Néri <daniel.neri@sigicom.se>
Sigicom AB, Stockholm, Sweden


diff -r bc43d0ddc306 -r 851938281d52 devs/serial/generic/16x5x/current/src/ser_16x5x.c
--- a/devs/serial/generic/16x5x/current/src/ser_16x5x.c	Mon Nov 28 14:51:31 2005
+++ b/devs/serial/generic/16x5x/current/src/ser_16x5x.c	Thu Dec  1 10:44:47 2005
@@ -212,6 +212,8 @@
         s16550,
         s16550a
     } deviceType;
+    unsigned tx_fifo_size;
+    volatile unsigned tx_fifo_avail;
 #endif
 } pc_serial_info;
 
@@ -332,10 +334,15 @@
                 _fcr_thresh=FCR_RT14; break;
             }
             _fcr_thresh|=FCR_FE|FCR_CRF|FCR_CTF;
+            ser_chan->tx_fifo_size = 16;
             HAL_WRITE_UINT8(base+REG_fcr, _fcr_thresh); // Enable and clear FIFO
         }
-        else
+        else {
+            ser_chan->tx_fifo_size = 1;
             HAL_WRITE_UINT8(base+REG_fcr, 0); // make sure it's disabled
+        }
+
+        ser_chan->tx_fifo_avail = ser_chan->tx_fifo_size;
 #endif
         if (chan->out_cbuf.len != 0) {
             _ier = IER_RCV;
@@ -423,16 +430,26 @@
 static bool
 pc_serial_putc(serial_channel *chan, unsigned char c)
 {
+#ifndef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
     cyg_uint8 _lsr;
+#endif
     pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;
     cyg_addrword_t base = ser_chan->base;
 
+#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
+    if (ser_chan->tx_fifo_avail > 0) {
+        HAL_WRITE_UINT8(base+REG_thr, c);
+        --ser_chan->tx_fifo_avail;
+        return true;
+    }
+#else
     HAL_READ_UINT8(base+REG_lsr, _lsr);
     if (_lsr & LSR_THE) {
         // Transmit buffer is empty
         HAL_WRITE_UINT8(base+REG_thr, c);
         return true;
     }
+#endif
     // No space
     return false;
 }
@@ -626,6 +643,9 @@
             break;
         }
         case ISR_Tx:
+#ifdef CYGPKG_IO_SERIAL_GENERIC_16X5X_FIFO
+            ser_chan->tx_fifo_avail = ser_chan->tx_fifo_size;
+#endif
             (chan->callbacks->xmt_char)(chan);
             break;
 

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

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