Mercurial > ecos
changeset 86:6512add4f5d6 ecos-sw-2000-05-05
Merge from eCos master repository on 2000-05-05-07:47:05-BST
line wrap: on
line diff
--- a/host/tools/ecostest/ChangeLog +++ b/host/tools/ecostest/ChangeLog @@ -1,3 +1,10 @@ +2000-05-03 Bart Veer <bartv@redhat.com> + + * common/permtest.cxx (find_ptest): + Do a little bit of searching for the permutation file. + Catch errors and give a diagnostic, rather than aborting because + of an uncaught C++ exception. + 2000-04-14 Simon FitzMaurice <sdf@redhat.co.uk> * common\ResetAttributes.cpp : do not carry forward values for skipped fields in reset strings * common\eCosTest.cpp : Avoid overflow in socket timeouts
--- a/host/tools/ecostest/common/eCosTestDownloadFilter.cpp +++ b/host/tools/ecostest/common/eCosTestDownloadFilter.cpp @@ -53,7 +53,7 @@ #include "eCosStd.h" #include "eCosTrace.h" -#define DL_FILTER_VER "$Id: eCosTestDownloadFilter.cpp,v 1.5 2000/04/28 18:18:41 jlarmour Exp $" +#define DL_FILTER_VER "$Id: eCosTestDownloadFilter.cpp,v 1.6 2000/05/05 17:31:08 jlarmour Exp $" #include "eCosTestDownloadFilter.h" CeCosTestDownloadFilter::CeCosTestDownloadFilter():
--- a/host/tools/ecostest/common/eCosTestMonitorFilter.cpp +++ b/host/tools/ecostest/common/eCosTestMonitorFilter.cpp @@ -45,7 +45,7 @@ #include "eCosStd.h" -#define SER_FILTER_VER "$Id: eCosTestMonitorFilter.cpp,v 1.4 2000/04/28 18:18:41 jlarmour Exp $" +#define SER_FILTER_VER "$Id: eCosTestMonitorFilter.cpp,v 1.5 2000/05/05 17:31:08 jlarmour Exp $" #include "eCosTestMonitorFilter.h" CeCosTestMonitorFilter::CeCosTestMonitorFilter():
--- a/host/tools/ecostest/common/eCosTestSerialFilter.cpp +++ b/host/tools/ecostest/common/eCosTestSerialFilter.cpp @@ -51,7 +51,7 @@ #include "eCosStd.h" -#define SER_FILTER_VER "$Id: eCosTestSerialFilter.cpp,v 1.5 2000/04/28 18:18:41 jlarmour Exp $" +#define SER_FILTER_VER "$Id: eCosTestSerialFilter.cpp,v 1.6 2000/05/05 17:31:08 jlarmour Exp $" #include "eCosTestSerialFilter.h" #include "eCosThreadUtils.h"
--- a/packages/NEWS +++ b/packages/NEWS @@ -1,3 +1,8 @@ +* IO serial driver + The common serial driver has been extended with a configurable option for + a non-blocking read/write mode. It has also been given some new callbacks + which allow low-level drivers to transfer data in blocks instead of as + single characters. * SH HAL Now provides ROMRAM startup type, copying code and data to RAM before executing, improving performance at cost of memory.
--- a/packages/io/common/current/ChangeLog +++ b/packages/io/common/current/ChangeLog @@ -1,3 +1,16 @@ +2000-05-05 Grant Edwards <grante@visi.com> + + * include/config_keys.h: Add key to inquire about serial buffer info + +2000-05-03 Jesper Skov <jskov@redhat.com> + + * include/config_keys.h: Added keys for DSP io. + Added key for overflow reset. + +2000-05-01 Jesper Skov <jskov@redhat.com> + + * include/config_keys.h: Added keys for read/write blocking. + 2000-03-28 John Dallaway <jld@cygnus.co.uk> * cdl/io.cdl:
--- a/packages/io/common/current/include/config_keys.h +++ b/packages/io/common/current/include/config_keys.h @@ -33,10 +33,10 @@ // ==================================================================== //#####DESCRIPTIONBEGIN#### // -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: Repository for all get/put config "keys" +// Author(s): gthomas +// Contributors: gthomas,jskov,grante +// Date: 1999-02-04 +// Purpose: Repository for all get/put config "keys" // Description: // //####DESCRIPTIONEND#### @@ -46,17 +46,38 @@ // This file contains all of the 'key' values used by all I/O components. // It is placed in this single repository to make it easy to reduce conflicts. +// ======== 0x0100 Serial ==================================================== // Get/Set configuration 'key' values for low-level serial I/O #define CYG_IO_GET_CONFIG_SERIAL_INFO 0x0101 #define CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN 0x0102 #define CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH 0x0103 #define CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH 0x0104 #define CYG_IO_GET_CONFIG_SERIAL_ABORT 0x0105 +#define CYG_IO_GET_CONFIG_SERIAL_READ_BLOCKING 0x0106 +#define CYG_IO_GET_CONFIG_SERIAL_WRITE_BLOCKING 0x0107 +#define CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO 0x0111 #define CYG_IO_SET_CONFIG_SERIAL_INFO 0x0181 +#define CYG_IO_SET_CONFIG_SERIAL_READ_BLOCKING 0x0182 +#define CYG_IO_SET_CONFIG_SERIAL_WRITE_BLOCKING 0x0183 +// ======== 0x0200 TTY ======================================================= // Get/Set configuration 'key' values for tty-like driver #define CYG_IO_GET_CONFIG_TTY_INFO 0x0201 // Get channel configuration #define CYG_IO_SET_CONFIG_TTY_INFO 0x0281 // Set channel configuration + +// ======== 0x0300 DSP ======================================================= +// Get/Set configuration 'key' values for low-level DSP I/O +#define CYG_IO_GET_CONFIG_DSP_OUTPUT_DRAIN 0x0301 +#define CYG_IO_GET_CONFIG_DSP_OUTPUT_FLUSH 0x0302 +#define CYG_IO_GET_CONFIG_DSP_INPUT_FLUSH 0x0303 +#define CYG_IO_GET_CONFIG_DSP_ABORT 0x0304 +#define CYG_IO_GET_CONFIG_DSP_READ_BLOCKING 0x0305 +#define CYG_IO_GET_CONFIG_DSP_WRITE_BLOCKING 0x0306 +#define CYG_IO_GET_CONFIG_DSP_INPUT_OVERFLOW_RESET 0x0307 + +#define CYG_IO_SET_CONFIG_DSP_READ_BLOCKING 0x0381 +#define CYG_IO_SET_CONFIG_DSP_WRITE_BLOCKING 0x0382 + #endif /* CYGONCE_CONFIG_KEYS_H */ /* EOF config_keys.h */
--- a/packages/io/serial/current/ChangeLog +++ b/packages/io/serial/current/ChangeLog @@ -1,3 +1,33 @@ +2000-05-05 Grant Edwards <grante@visi.com> + + * src/common/serial.c (serial_get_config): Support + CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO key to get buffer information + + * include/serialio.h: Add cyg_serial_buf_info_t + +2000-05-04 Jesper Skov <jskov@redhat.com> + + * cdl/io_serial.cdl: Only build tests when drivers enabled. + +2000-05-02 Jesper Skov <jskov@redhat.com> + + * src/common/serial.c (serial_set_config): Set proper parity for + blocking options. + (serial_get_config): Fix copy'n'paste buglet. + +2000-05-01 Jesper Skov <jskov@redhat.com> + + * src/common/serial.c: Added non-blocking config and operation for + read/write calls. + Added block transfer rcv/xmt callbacks. + Added (disabled for now) check for rcv overflow. [need to add + handling] + + * include/serial.h: Added non-blocking callbacks. + + * cdl/io_serial.cdl: Added non-blocking option. Added block + transfer interface. + 2000-04-17 Hugo Tyson <hmt@cygnus.co.uk> * src/PKGconf.mak: remove; it's obsolete.
--- a/packages/io/serial/current/cdl/io_serial.cdl +++ b/packages/io/serial/current/cdl/io_serial.cdl @@ -61,6 +61,23 @@ cdl_package CYGPKG_IO_SERIAL { puts $::cdl_header "/****** proc output end ******/" } + cdl_option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING { + display "Support non-blocking read and write calls" + default_value 0 + description " + This option enables extra code in the generic serial driver + which allows clients to switch read() and write() call + semantics from blocking to non-blocking." + } + + cdl_interface CYGINT_IO_SERIAL_BLOCK_TRANSFER { + display "Driver requires block transfer callback functions" + description " + Some low-level drivers can be optimized to transfer blocks + of data instead of a single character at a time. These usually + rely on a hardware FIFO of some sort." + } + cdl_component CYGPKG_IO_SERIAL_TTY { display "TTY-mode serial device drivers" flavor bool @@ -140,7 +157,7 @@ cdl_package CYGPKG_IO_SERIAL { display "Serial device driver tests" flavor data no_define - calculated { "tests/serial1 tests/serial2 tests/serial3 tests/serial4 tests/serial5 tests/tty1 tests/tty2" } + calculated { CYGPKG_IO_SERIAL_DEVICES ? "tests/serial1 tests/serial2 tests/serial3 tests/serial4 tests/serial5 tests/tty1 tests/tty2" : "" } description " This option specifies the set of tests for the serial device drivers." }
--- a/packages/io/serial/current/include/serial.h +++ b/packages/io/serial/current/include/serial.h @@ -46,6 +46,8 @@ // Serial I/O interfaces #include <pkgconf/system.h> +#include <pkgconf/io_serial.h> + #include <cyg/infra/cyg_type.h> #include <cyg/io/io.h> #include <cyg/io/serialio.h> @@ -62,14 +64,40 @@ typedef struct { void (*xmt_char)(serial_channel *chan); // Consume an input character void (*rcv_char)(serial_channel *chan, unsigned char c); + +#ifdef CYGINT_IO_SERIAL_BLOCK_TRANSFER + // Request space for input characters + bool (*data_rcv_req)(serial_channel *chan, int avail, + int* space_avail, unsigned char** space); + // Receive operation completed + void (*data_rcv_done)(serial_channel *chan); + // Request characters for transmission + bool (*data_xmt_req)(serial_channel *chan, int space, + int* chars_avail, unsigned char** chars); + // Transmit operation completed + void (*data_xmt_done)(serial_channel *chan); +#endif // CYGINT_IO_SERIAL_BLOCK_TRANSFER } serial_callbacks_t; +#ifdef CYGINT_IO_SERIAL_BLOCK_TRANSFER +#define SERIAL_CALLBACKS(_l,_init,_xmt_char,_rcv_char, _data_rcv_req, _data_rcv_done, _data_xmt_req, _data_xmt_done) \ +serial_callbacks_t _l = { \ + _init, \ + _xmt_char, \ + _rcv_char, \ + _data_rcv_req, \ + _data_rcv_done, \ + _data_xmt_req, \ + _data_xmt_done \ +}; +#else #define SERIAL_CALLBACKS(_l,_init,_xmt_char,_rcv_char) \ serial_callbacks_t _l = { \ _init, \ _xmt_char, \ _rcv_char \ }; +#endif extern serial_callbacks_t cyg_io_serial_callbacks; @@ -82,6 +110,9 @@ typedef struct { cyg_drv_cond_t wait; cyg_drv_mutex_t lock; bool waiting; +#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING + bool blocking; +#endif volatile bool abort; // Set by an outsider to kill processing volatile cyg_int32 pending; // This many bytes waiting to be sent } cbuf_t;
--- a/packages/io/serial/current/include/serialio.h +++ b/packages/io/serial/current/include/serialio.h @@ -116,6 +116,14 @@ typedef struct { cyg_uint32 flags; } cyg_serial_info_t; +typedef struct { + cyg_int32 rx_bufsize; + cyg_int32 rx_count; + cyg_int32 tx_bufsize; + cyg_int32 tx_count; +} cyg_serial_buf_info_t; + + #define CYG_SERIAL_INFO_INIT(_baud,_stop,_parity,_word_length,_flags) \ { _baud, _stop, _parity, _word_length, _flags}
--- a/packages/io/serial/current/src/common/serial.c +++ b/packages/io/serial/current/src/common/serial.c @@ -31,10 +31,10 @@ //========================================================================== //#####DESCRIPTIONBEGIN#### // -// Author(s): gthomas -// Contributors: gthomas -// Date: 1999-02-04 -// Purpose: Top level serial driver +// Author(s): gthomas +// Contributors: gthomas, grante +// Date: 1999-02-04 +// Purpose: Top level serial driver // Description: // //####DESCRIPTIONEND#### @@ -42,6 +42,8 @@ //========================================================================== #include <pkgconf/io.h> +#include <pkgconf/io_serial.h> + #include <cyg/io/io.h> #include <cyg/io/devtab.h> #include <cyg/io/serial.h> @@ -62,10 +64,28 @@ DEVIO_TABLE(cyg_io_serial_devio, static void serial_init(serial_channel *chan); static void serial_xmt_char(serial_channel *chan); static void serial_rcv_char(serial_channel *chan, unsigned char c); +#ifdef CYGINT_IO_SERIAL_BLOCK_TRANSFER +static bool serial_data_rcv_req(serial_channel *chan, int avail, + int* space_avail, unsigned char** space); +static void serial_data_rcv_done(serial_channel *chan); +static bool serial_data_xmt_req(serial_channel *chan, int space, + int* chars_avail, unsigned char** chars); +static void serial_data_xmt_done(serial_channel *chan); +SERIAL_CALLBACKS(cyg_io_serial_callbacks, + serial_init, + serial_xmt_char, + serial_rcv_char, + serial_data_rcv_req, + serial_data_rcv_done, + serial_data_xmt_req, + serial_data_xmt_done); +#else SERIAL_CALLBACKS(cyg_io_serial_callbacks, serial_init, serial_xmt_char, serial_rcv_char); +#endif + static void serial_init(serial_channel *chan) @@ -77,6 +97,9 @@ serial_init(serial_channel *chan) #endif chan->out_cbuf.waiting = false; chan->out_cbuf.abort = false; +#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING + chan->out_cbuf.blocking = true; +#endif chan->out_cbuf.pending = 0; cyg_drv_mutex_init(&chan->out_cbuf.lock); cyg_drv_cond_init(&chan->out_cbuf.wait, &chan->out_cbuf.lock); @@ -88,6 +111,9 @@ serial_init(serial_channel *chan) #endif chan->in_cbuf.waiting = false; chan->in_cbuf.abort = false; +#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING + chan->in_cbuf.blocking = true; +#endif cyg_drv_mutex_init(&chan->in_cbuf.lock); cyg_drv_cond_init(&chan->in_cbuf.wait, &chan->in_cbuf.lock); } @@ -108,6 +134,7 @@ serial_write(cyg_io_handle_t handle, con cbuf->abort = false; cyg_drv_mutex_lock(&cbuf->lock); + if (cbuf->len == 0) { // Non interrupt driven (i.e. polled) operation while (size-- > 0) { @@ -123,14 +150,24 @@ serial_write(cyg_io_handle_t handle, con cbuf->waiting = true; // Buffer full - wait for space (funs->start_xmit)(chan); // Make sure xmit is running + // Check flag: 'start_xmit' may have obviated the need to wait :-) if (cbuf->waiting) { - // Note: 'start_xmit' may have obviated the need to wait :-) +#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING + // Optionally return if configured for non-blocking mode. + if (!cbuf->blocking) { + *len -= size; // number of characters actually sent + cbuf->waiting = false; + res = -EAGAIN; + break; + } +#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING cbuf->pending += size; // Have this much more to send [eventually] cyg_drv_cond_wait(&cbuf->wait); cbuf->pending -= size; } if (cbuf->abort) { // Give up! + *len -= size; // number of characters actually sent cbuf->abort = false; cbuf->waiting = false; res = -EINTR; @@ -168,6 +205,7 @@ serial_read(cyg_io_handle_t handle, void cbuf->abort = false; cyg_drv_mutex_lock(&cbuf->lock); + if (cbuf->len == 0) { // Non interrupt driven (i.e. polled) operation while (size++ < *len) { @@ -181,6 +219,13 @@ serial_read(cyg_io_handle_t handle, void if (++cbuf->get == cbuf->len) cbuf->get = 0; size++; } else { +#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING + if (!cbuf->blocking) { + *len = size; // characters actually read + res = -EAGAIN; + break; + } +#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING cbuf->waiting = true; #ifdef XX_CYGDBG_DIAG_BUF enable_diag_uart = 0; @@ -199,6 +244,7 @@ serial_read(cyg_io_handle_t handle, void #endif // CYGDBG_DIAG_BUF if (cbuf->abort) { // Give up! + *len = size; // characters actually read cbuf->abort = false; cbuf->waiting = false; res = -EINTR; @@ -228,7 +274,8 @@ serial_get_config(cyg_io_handle_t handle serial_channel *chan = (serial_channel *)t->priv; cyg_serial_info_t *buf = (cyg_serial_info_t *)xbuf; Cyg_ErrNo res = ENOERR; - cbuf_t *cbuf = &chan->out_cbuf; + cbuf_t *out_cbuf = &chan->out_cbuf; + cbuf_t *in_cbuf = &chan->in_cbuf; serial_funs *funs = chan->funs; switch (key) { @@ -239,64 +286,112 @@ serial_get_config(cyg_io_handle_t handle *buf = chan->config; *len = sizeof(chan->config); break; + + case CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO: + // return rx/tx buffer sizes and counts + { + cyg_serial_buf_info_t *p; + if (*len < sizeof(cyg_serial_buf_info_t)) + return -EINVAL; + + *len = sizeof(cyg_serial_buf_info_t); + p = (cyg_serial_buf_info_t *)xbuf; + + p->rx_bufsize = chan->in_cbuf.len; + if (p->rx_bufsize) { + p->rx_count = chan->in_cbuf.put - chan->in_cbuf.get; + if (p->rx_count < 0) + p->rx_count += p->rx_bufsize; + } + else + p->rx_count = 0; + + p->tx_bufsize = chan->out_cbuf.len; + if (p->tx_bufsize) { + p->tx_count = chan->out_cbuf.put - chan->out_cbuf.get; + if (p->tx_count < 0) + p->tx_count += p->tx_bufsize; + } + else + p->tx_count = 0; + } + break; + case CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN: // Wait for any pending output to complete - if (cbuf->len == 0) break; // Nothing to do if not buffered - cyg_drv_mutex_lock(&cbuf->lock); // Stop any further output processing + if (out_cbuf->len == 0) break; // Nothing to do if not buffered + cyg_drv_mutex_lock(&out_cbuf->lock); // Stop any further output processing cyg_drv_dsr_lock(); - while (cbuf->pending || (cbuf->get != cbuf->put)) { - cbuf->waiting = true; - cyg_drv_cond_wait(&cbuf->wait); + while (out_cbuf->pending || (out_cbuf->get != out_cbuf->put)) { + out_cbuf->waiting = true; + cyg_drv_cond_wait(&out_cbuf->wait); } cyg_drv_dsr_unlock(); - cyg_drv_mutex_unlock(&cbuf->lock); + cyg_drv_mutex_unlock(&out_cbuf->lock); break; + case CYG_IO_GET_CONFIG_SERIAL_INPUT_FLUSH: // Flush any buffered input - cbuf = &chan->in_cbuf; - if (cbuf->len == 0) break; // Nothing to do if not buffered - cyg_drv_mutex_lock(&cbuf->lock); // Stop any further input processing + if (in_cbuf->len == 0) break; // Nothing to do if not buffered + cyg_drv_mutex_lock(&in_cbuf->lock); // Stop any further input processing cyg_drv_dsr_lock(); - if (cbuf->waiting) { - cbuf->abort = true; - cyg_drv_cond_signal(&cbuf->wait); - cbuf->waiting = false; + if (in_cbuf->waiting) { + in_cbuf->abort = true; + cyg_drv_cond_signal(&in_cbuf->wait); + in_cbuf->waiting = false; } - cbuf->get = cbuf->put; // Flush buffered input + in_cbuf->get = in_cbuf->put; // Flush buffered input cyg_drv_dsr_unlock(); - cyg_drv_mutex_unlock(&cbuf->lock); + cyg_drv_mutex_unlock(&in_cbuf->lock); break; + case CYG_IO_GET_CONFIG_SERIAL_ABORT: // Abort any outstanding I/O, including blocked reads // Caution - assumed to be called from 'timeout' (i.e. DSR) code - cbuf = &chan->in_cbuf; - if (cbuf->len != 0) { - cbuf->abort = true; - cyg_drv_cond_signal(&cbuf->wait); + if (in_cbuf->len != 0) { + in_cbuf->abort = true; + cyg_drv_cond_signal(&in_cbuf->wait); } - cbuf = &chan->out_cbuf; - if (cbuf->len != 0) { - cbuf->abort = true; - cyg_drv_cond_signal(&cbuf->wait); + if (out_cbuf->len != 0) { + out_cbuf->abort = true; + cyg_drv_cond_signal(&out_cbuf->wait); } break; + case CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH: // Throw away any pending output - if (cbuf->len == 0) break; // Nothing to do if not buffered - cyg_drv_mutex_lock(&cbuf->lock); // Stop any further output processing + if (out_cbuf->len == 0) break; // Nothing to do if not buffered + cyg_drv_mutex_lock(&out_cbuf->lock); // Stop any further output processing cyg_drv_dsr_lock(); - if (cbuf->get != cbuf->put) { - cbuf->get = cbuf->put; // Empties queue! + if (out_cbuf->get != out_cbuf->put) { + out_cbuf->get = out_cbuf->put; // Empties queue! (funs->stop_xmit)(chan); // Done with transmit } - if (cbuf->waiting) { - cbuf->abort = true; - cyg_drv_cond_signal(&cbuf->wait); - cbuf->waiting = false; + if (out_cbuf->waiting) { + out_cbuf->abort = true; + cyg_drv_cond_signal(&out_cbuf->wait); + out_cbuf->waiting = false; } cyg_drv_dsr_unlock(); - cyg_drv_mutex_unlock(&cbuf->lock); + cyg_drv_mutex_unlock(&out_cbuf->lock); + break; + +#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING + case CYG_IO_GET_CONFIG_SERIAL_READ_BLOCKING: + if (*len < sizeof(cyg_uint32)) { + return -EINVAL; + } + *(cyg_uint32*)xbuf = (in_cbuf->blocking) ? 1 : 0; break; + + case CYG_IO_GET_CONFIG_SERIAL_WRITE_BLOCKING: + if (*len < sizeof(cyg_uint32)) { + return -EINVAL; + } + *(cyg_uint32*)xbuf = (out_cbuf->blocking) ? 1 : 0; + break; +#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING + default: res = -EINVAL; } @@ -309,6 +404,10 @@ serial_set_config(cyg_io_handle_t handle Cyg_ErrNo res = ENOERR; cyg_devtab_entry_t *t = (cyg_devtab_entry_t *)handle; serial_channel *chan = (serial_channel *)t->priv; +#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING + cbuf_t *out_cbuf = &chan->out_cbuf; + cbuf_t *in_cbuf = &chan->in_cbuf; +#endif serial_funs *funs = chan->funs; cyg_serial_info_t *buf = (cyg_serial_info_t *)xbuf; @@ -322,6 +421,20 @@ serial_set_config(cyg_io_handle_t handle res = -EINVAL; } break; +#ifdef CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING + case CYG_IO_SET_CONFIG_SERIAL_READ_BLOCKING: + if (*len < sizeof(cyg_uint32) || 0 == in_cbuf->len) { + return -EINVAL; + } + in_cbuf->blocking = (1 == *(cyg_uint32*)xbuf) ? true : false; + break; + case CYG_IO_SET_CONFIG_SERIAL_WRITE_BLOCKING: + if (*len < sizeof(cyg_uint32) || 0 == out_cbuf->len) { + return -EINVAL; + } + out_cbuf->blocking = (1 == *(cyg_uint32*)xbuf) ? true : false; + break; +#endif // CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING default: res = -EINVAL; } @@ -366,6 +479,15 @@ serial_rcv_char(serial_channel *chan, un { cbuf_t *cbuf = &chan->in_cbuf; +#if 0 + // FIXME: add error handling + int space; + // Check for overflow + space = (cbuf->len + cbuf->put - cbuf->get) % cbuf->len; + if (space == (cbuf->len - 1)) + ; // full since put==get means empty +#endif + cbuf->data[cbuf->put++] = c; if (cbuf->put == cbuf->len) cbuf->put = 0; if (cbuf->waiting) { @@ -385,3 +507,109 @@ serial_rcv_char(serial_channel *chan, un } } +//---------------------------------------------------------------------------- +// Block transfer functions. Not all drivers require these. +#ifdef CYGINT_IO_SERIAL_BLOCK_TRANSFER + +static bool +serial_data_rcv_req(serial_channel *chan, int avail, + int* space_avail, unsigned char** space) +{ + cbuf_t *cbuf = &chan->in_cbuf; + int gap; + + // Check for space + gap = (cbuf->len + cbuf->put - cbuf->get) % cbuf->len; + if (gap == (cbuf->len - 1)) + return false; // full since put==get means empty + + if (0 == gap) { + // Buffer is empty. Reset put/get indexes to get max transfer in + // one chunk. + cbuf->get = 0; + cbuf->put = 0; + gap = cbuf->len - 1; + } else { + // Free space (G = get, P = put, x = data, . = empty) + // positive: xxxxP.....Gxxx + // negative: ..GxxxxxP..... [offer last chunk only] + + // First try for a gap between put and get locations + gap = cbuf->get - cbuf->put - 1; + if (gap < 0) { + // If failed, the gap is between put and the end of buffer + gap = cbuf->len - cbuf->put - 1; + } + } + + if (avail < gap) gap = avail; // bound by what's available from hw + + *space_avail = gap; + *space = &cbuf->data[cbuf->put]; + cbuf->put += gap; + + if (cbuf->put == cbuf->len) cbuf->put = 0; + + return true; +} + +static void +serial_data_rcv_done(serial_channel *chan) +{ + cbuf_t *cbuf = &chan->in_cbuf; + if (cbuf->waiting) { + cbuf->waiting = false; + cyg_drv_cond_signal(&cbuf->wait); + } +} + +static bool +serial_data_xmt_req(serial_channel *chan, int space, + int* chars_avail, unsigned char** chars) +{ + cbuf_t *cbuf = &chan->out_cbuf; + int avail; + + // Available data (G = get, P = put, x = data, . = empty) + // 0: no data + // negative: xxxxP.....Gxxx [offer last chunk only] + // positive: ..GxxxxxP..... + avail = cbuf->put - cbuf->get; + if (0 == avail) + return false; + if (avail < 0) { + avail = cbuf->len - cbuf->get; + } + + if (avail > space) avail = space; // bound by space in hardware + + *chars_avail = avail; + *chars = &cbuf->data[cbuf->get]; + cbuf->get += avail; + + if (cbuf->get == cbuf->len) cbuf->get = 0; + + return true; +} + +static void +serial_data_xmt_done(serial_channel *chan) +{ + cbuf_t *cbuf = &chan->out_cbuf; + serial_funs *funs = chan->funs; + int space; + + (funs->stop_xmit)(chan); // Done with transmit + + if (cbuf->waiting) { + // See if there is now enough room to restart writer + space = (cbuf->len + cbuf->get) - cbuf->put; + if (space > cbuf->len) space -= cbuf->len; + if (space >= cbuf->low_water) { + cbuf->waiting = false; + cyg_drv_cond_broadcast(&cbuf->wait); + } + } +} + +#endif // CYGINT_IO_SERIAL_BLOCK_TRANSFER
--- a/packages/kernel/current/ChangeLog +++ b/packages/kernel/current/ChangeLog @@ -1,3 +1,16 @@ +2000-05-04 Jonathan Larmour <jlarmour@redhat.co.uk> + + * include/instrmnt.h: Remove all CYG_UNUSED_PARAMs as they could + cause problems when used with volatile arguments + * src/intr/intr.cxx: Use CYG_UNUSED_PARAM to silence warning that + appears because of the above change. + +2000-05-02 Gary Thomas <gthomas@redhat.com> + + * tests/kintr0.c: + * tests/intr0.cxx: Correct test for cases when VSR_MIN or + ISR_MIN are not zero (bad assumption). + 2000-04-26 Jesper Skov <jskov@redhat.com> * tests/kcache1.c: Also to flush testing with unified caches.
--- a/packages/kernel/current/include/instrmnt.h +++ b/packages/kernel/current/include/instrmnt.h @@ -34,13 +34,19 @@ //========================================================================== //#####DESCRIPTIONBEGIN#### // -// Author(s): nickg -// Contributors: nickg -// Date: 1997-10-24 -// Purpose: Define kernel instrumentation -// Description: A set of definitions and macros used to implement an -// instrumentation interface for the kernel. -// Usage: #include <cyg/kernel/instrmnt.hxx> +// Author(s): nickg +// Contributors: nickg +// Date: 2000-05-04 +// Purpose: Define kernel instrumentation +// Description: A set of definitions and macros used to implement an +// instrumentation interface for the kernel. +// NOTE: Don't use CYG_UNUSED_PARAM (or similar) here to +// silence warnings about unused variables when using the +// empty macro definitions. Otherwise this can cause problems +// with volatile arguments and cause other side-effects. +// Instead it is up to the caller to ensure that unused +// arguments don't cause warnings +// Usage: #include <cyg/kernel/instrmnt.hxx> // //####DESCRIPTIONEND#### // @@ -78,11 +84,7 @@ externC void cyg_instrument_disable( cyg #else // ifdef CYGPKG_KERNEL_INSTRUMENT -#define CYG_INSTRUMENT(_type_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT(_type_,_arg1_,_arg2_) #endif // ifdef CYGPKG_KERNEL_INSTRUMENT @@ -240,11 +242,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_SCHED(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_SCHED(_event_,_arg1_,_arg2_) #endif @@ -258,11 +256,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_THREAD(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_THREAD(_event_,_arg1_,_arg2_) #endif @@ -276,11 +270,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_INTR(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_INTR(_event_,_arg1_,_arg2_) #endif @@ -294,11 +284,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_MUTEX(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_MUTEX(_event_,_arg1_,_arg2_) #endif @@ -312,11 +298,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_CONDVAR(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_CONDVAR(_event_,_arg1_,_arg2_) #endif @@ -330,11 +312,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_BINSEM(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_BINSEM(_event_,_arg1_,_arg2_) #endif @@ -348,11 +326,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_CNTSEM(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_CNTSEM(_event_,_arg1_,_arg2_) #endif @@ -366,11 +340,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_CLOCK(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_CLOCK(_event_,_arg1_,_arg2_) #endif @@ -384,11 +354,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_ALARM(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_ALARM(_event_,_arg1_,_arg2_) #endif @@ -402,11 +368,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_MBOXT(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_MBOXT(_event_,_arg1_,_arg2_) #endif @@ -420,11 +382,7 @@ externC void cyg_instrument_disable( cyg #else -#define CYG_INSTRUMENT_USER(_event_,_arg1_,_arg2_) \ - CYG_MACRO_START \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_)); \ - CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_)); \ - CYG_MACRO_END +#define CYG_INSTRUMENT_USER(_event_,_arg1_,_arg2_) #endif
--- a/packages/kernel/current/src/intr/intr.cxx +++ b/packages/kernel/current/src/intr/intr.cxx @@ -270,9 +270,10 @@ interrupt_end( // Sometimes we have a NULL intr object pointer. cyg_vector vector = (intr!=NULL)?intr->vector:0; - + CYG_INSTRUMENT_INTR(END, vector, isr_ret); + CYG_UNUSED_PARAM( cyg_vector, vector ); // prevent compiler warning #ifndef CYGIMP_KERNEL_INTERRUPTS_CHAIN
--- a/packages/kernel/current/tests/intr0.cxx +++ b/packages/kernel/current/tests/intr0.cxx @@ -87,7 +87,7 @@ static void dsr1(cyg_vector vector, cyg_ static bool flash( void ) { - Cyg_Interrupt intr0 = Cyg_Interrupt( 0, 0, (CYG_ADDRWORD)333, isr0, dsr0 ); + Cyg_Interrupt intr0 = Cyg_Interrupt(CYGNUM_HAL_ISR_MIN, 0, (CYG_ADDRWORD)333, isr0, dsr0 ); return true; } @@ -120,13 +120,13 @@ void intr0_main( void ) // Make sure the chosen levels are not already in use. int in_use; - cyg_vector lvl1 = 1 % (CYGNUM_HAL_ISR_COUNT); + cyg_vector lvl1 = (CYGNUM_HAL_ISR_MIN + 1) % (CYGNUM_HAL_ISR_COUNT); HAL_INTERRUPT_IN_USE( lvl1, in_use ); Cyg_Interrupt* intr0 = NULL; if (!in_use) intr0 = new((void *)&intr0_obj[0]) Cyg_Interrupt( lvl1, 1, (CYG_ADDRWORD)777, isr0, dsr0 ); - cyg_vector lvl2 = 15 % (CYGNUM_HAL_ISR_COUNT); + cyg_vector lvl2 = (CYGNUM_HAL_ISR_MIN + 15) % (CYGNUM_HAL_ISR_COUNT); HAL_INTERRUPT_IN_USE( lvl2, in_use ); Cyg_Interrupt* intr1 = NULL; if (!in_use && lvl1 != lvl2) @@ -149,7 +149,7 @@ void intr0_main( void ) // instead of adding to it we could be in a big mess if the // vector is being used by something important. - cyg_vector v = 11 % CYGNUM_HAL_VSR_COUNT; + cyg_vector v = (CYGNUM_HAL_VSR_MIN + 11) % CYGNUM_HAL_VSR_COUNT; cyg_VSR *old_vsr, *new_vsr; Cyg_Interrupt::set_vsr( v, vsr0, &old_vsr ); Cyg_Interrupt::get_vsr( v, &new_vsr ); @@ -179,7 +179,7 @@ void intr0_main( void ) v1 = 12 % CYGNUM_HAL_ISR_COUNT; else /* NOTE TRAILING ELSE... */ #endif - v1 = 6 % CYGNUM_HAL_ISR_COUNT; + v1 = (CYGNUM_HAL_ISR_MIN + 6) % CYGNUM_HAL_ISR_COUNT; Cyg_Interrupt::mask_interrupt(v1); Cyg_Interrupt::unmask_interrupt(v1);
--- a/packages/kernel/current/tests/kintr0.c +++ b/packages/kernel/current/tests/kintr0.c @@ -93,7 +93,8 @@ static bool flash( void ) cyg_handle_t handle; cyg_interrupt intr; - cyg_interrupt_create(0, 0, (cyg_addrword_t)333, isr0, dsr0, &handle, &intr ); + cyg_interrupt_create(CYGNUM_HAL_ISR_MIN, 0, (cyg_addrword_t)333, + isr0, dsr0, &handle, &intr ); cyg_interrupt_delete(handle); return true; @@ -120,10 +121,10 @@ static void vsr0() void kintr0_main( void ) { - cyg_vector_t v = 11 % CYGNUM_HAL_VSR_COUNT; + cyg_vector_t v = (CYGNUM_HAL_VSR_MIN + 11) % CYGNUM_HAL_VSR_COUNT; cyg_vector_t v1; - cyg_vector_t lvl1 = 1 % (CYGNUM_HAL_ISR_COUNT); - cyg_vector_t lvl2 = 15 % (CYGNUM_HAL_ISR_COUNT); + cyg_vector_t lvl1 = (CYGNUM_HAL_ISR_MIN + 1) % (CYGNUM_HAL_ISR_COUNT); + cyg_vector_t lvl2 = (CYGNUM_HAL_ISR_MIN + 15) % (CYGNUM_HAL_ISR_COUNT); int in_use; cyg_VSR_t *old_vsr, *new_vsr; @@ -136,7 +137,7 @@ void kintr0_main( void ) v1 = 12 % CYGNUM_HAL_ISR_COUNT; else /* NOTE TRAILING ELSE... */ #endif - v1 = 6 % CYGNUM_HAL_ISR_COUNT; + v1 = (CYGNUM_HAL_ISR_MIN + 6) % CYGNUM_HAL_ISR_COUNT; CHECK(flash()); CHECK(flash());
