This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
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