|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
I/O Package (Device Drivers)
|
I/O Package (Device Drivers)
|
|
|
|
|
|
|
|
|
Introduction
|
Introduction
|
|
|
|
|
The I/O package is designed as a general purpose framework for
|
The I/O package is designed as a general purpose framework for
|
supporting device drivers. This includes all classes of
|
supporting device drivers. This includes all classes of
|
drivers from simple serial to networking stacks and beyond.
|
drivers from simple serial to networking stacks and beyond.
|
|
|
|
|
|
|
Components of the I/O package, such as device drivers, are
|
Components of the I/O package, such as device drivers, are
|
configured into the system just like all other components.
|
configured into the system just like all other components.
|
Additionally, end users may add their own drivers to this set.
|
Additionally, end users may add their own drivers to this set.
|
|
|
|
|
|
|
While the set of drivers (and the devices they represent) may be
|
While the set of drivers (and the devices they represent) may be
|
considered static, they must be accessed via an opaque
|
considered static, they must be accessed via an opaque
|
“handle”. Each device in the system has a unique name and
|
“handle”. Each device in the system has a unique name and
|
the cyg_io_lookup() function is used to map that
|
the cyg_io_lookup() function is used to map that
|
name onto the handle for the device. This “hiding” of the
|
name onto the handle for the device. This “hiding” of the
|
device implementation allows for generic, named devices, as well as
|
device implementation allows for generic, named devices, as well as
|
more flexibility. Also, the cyg_io_lookup()
|
more flexibility. Also, the cyg_io_lookup()
|
function provides drivers the opportunity to initialize the device
|
function provides drivers the opportunity to initialize the device
|
when usage actually starts.
|
when usage actually starts.
|
|
|
|
|
|
|
All devices have a name. The standard provided devices use names such
|
All devices have a name. The standard provided devices use names such
|
as “/dev/console” and
|
as “/dev/console” and
|
“/dev/serial0”, where the
|
“/dev/serial0”, where the
|
“/dev/” prefix indicates that this is
|
“/dev/” prefix indicates that this is
|
the name of a device.
|
the name of a device.
|
|
|
|
|
The entire I/O package API, as well as the standard
|
The entire I/O package API, as well as the standard
|
set of provided drivers, is written in C.
|
set of provided drivers, is written in C.
|
|
|
Basic functions are provided to send data to and receive data
|
Basic functions are provided to send data to and receive data
|
from a device. The details of how this is done is left to the device [class] itself.
|
from a device. The details of how this is done is left to the device [class] itself.
|
For example, writing data to a block device like a disk drive may
|
For example, writing data to a block device like a disk drive may
|
have different semantics than writing to a serial port.
|
have different semantics than writing to a serial port.
|
|
|
Additional functions are provided to manipulate the state
|
Additional functions are provided to manipulate the state
|
of the driver and/or the actual device. These functions
|
of the driver and/or the actual device. These functions
|
are, by design, quite specific to the actual driver.
|
are, by design, quite specific to the actual driver.
|
|
|
This driver model supports layering; in other words, a device
|
This driver model supports layering; in other words, a device
|
may actually be created “on top of” another device.
|
may actually be created “on top of” another device.
|
For example, the “tty” (terminal-like) devices are
|
For example, the “tty” (terminal-like) devices are
|
built on top of simple serial devices. The upper layer then has
|
built on top of simple serial devices. The upper layer then has
|
the flexibility to add features and functions not found at the lower
|
the flexibility to add features and functions not found at the lower
|
layers. In this case the “tty” device provides
|
layers. In this case the “tty” device provides
|
for line buffering and editing not available from the simple serial
|
for line buffering and editing not available from the simple serial
|
drivers.
|
drivers.
|
|
|
|
|
Some drivers will support visibility of the layers they depend
|
Some drivers will support visibility of the layers they depend
|
upon. The “tty” driver allows information about
|
upon. The “tty” driver allows information about
|
the actual serial device to be manipulated by passing get/set
|
the actual serial device to be manipulated by passing get/set
|
config calls that use a serial driver “key” down
|
config calls that use a serial driver “key” down
|
to the serial driver itself.
|
to the serial driver itself.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
User API
|
User API
|
|
|
|
|
All functions, except cyg_io_lookup()
|
All functions, except cyg_io_lookup()
|
require an I/O “handle”.
|
require an I/O “handle”.
|
|
|
|
|
|
|
All functions return a value of the type Cyg_ErrNo. If an
|
All functions return a value of the type Cyg_ErrNo. If an
|
error condition is detected, this value will be negative and the
|
error condition is detected, this value will be negative and the
|
absolute value indicates the actual error, as specified in
|
absolute value indicates the actual error, as specified in
|
cyg/error/codes.h. The only other legal return
|
cyg/error/codes.h. The only other legal return
|
value will be ENOERR. All other function arguments
|
value will be ENOERR. All other function arguments
|
are pointers (references). This allows the drivers to pass information
|
are pointers (references). This allows the drivers to pass information
|
efficiently, both into and out of the driver. The most striking
|
efficiently, both into and out of the driver. The most striking
|
example of this is the “length” value passed to the read
|
example of this is the “length” value passed to the read
|
and write functions. This parameter contains the desired length of
|
and write functions. This parameter contains the desired length of
|
data on input to the function and the actual transferred length on
|
data on input to the function and the actual transferred length on
|
return.
|
return.
|
|
|
|
|
|
|
// Lookup a device and return its handle
|
// Lookup a device and return its handle
|
Cyg_ErrNo cyg_io_lookup(
|
Cyg_ErrNo cyg_io_lookup(
|
const char *name,
|
const char *name,
|
cyg_io_handle_t *handle )
|
cyg_io_handle_t *handle )
|
|
|
|
|
|
|
This function maps a device name onto an appropriate handle. If the
|
This function maps a device name onto an appropriate handle. If the
|
named device is not in the system, then the error
|
named device is not in the system, then the error
|
-ENOENT is returned. If the device is found, then
|
-ENOENT is returned. If the device is found, then
|
the handle for the device is returned by way of the handle pointer
|
the handle for the device is returned by way of the handle pointer
|
*handle.
|
*handle.
|
|
|
|
|
|
|
// Write data to a device
|
// Write data to a device
|
Cyg_ErrNo cyg_io_write(
|
Cyg_ErrNo cyg_io_write(
|
cyg_io_handle_t handle,
|
cyg_io_handle_t handle,
|
const void *buf,
|
const void *buf,
|
cyg_uint32 *len )
|
cyg_uint32 *len )
|
|
|
|
|
|
|
This function sends data to a device. The size of data to send is
|
This function sends data to a device. The size of data to send is
|
contained in *len and the actual size sent will
|
contained in *len and the actual size sent will
|
be returned in the same place.
|
be returned in the same place.
|
|
|
|
|
|
|
// Read data from a device
|
// Read data from a device
|
Cyg_ErrNo cyg_io_read(
|
Cyg_ErrNo cyg_io_read(
|
cyg_io_handle_t handle,
|
cyg_io_handle_t handle,
|
void *buf,
|
void *buf,
|
cyg_uint32 *len )
|
cyg_uint32 *len )
|
|
|
|
|
|
|
This function receives data from a device. The desired size of data to
|
This function receives data from a device. The desired size of data to
|
receive is contained in *len and the actual
|
receive is contained in *len and the actual
|
size obtained will be returned in the same place.
|
size obtained will be returned in the same place.
|
|
|
|
|
|
|
// Get the configuration of a device
|
// Get the configuration of a device
|
Cyg_ErrNo cyg_io_get_config(
|
Cyg_ErrNo cyg_io_get_config(
|
cyg_io_handle_t handle,
|
cyg_io_handle_t handle,
|
cyg_uint32 key,
|
cyg_uint32 key,
|
void *buf,
|
void *buf,
|
cyg_uint32 *len )
|
cyg_uint32 *len )
|
|
|
|
|
|
|
This function is used to obtain run-time configuration about a
|
This function is used to obtain run-time configuration about a
|
device. The type of information retrieved is specified by the
|
device. The type of information retrieved is specified by the
|
key. The data will be returned in the given
|
key. The data will be returned in the given
|
buffer. The value of *len should contain the
|
buffer. The value of *len should contain the
|
amount of data requested, which must be at least as large as the size
|
amount of data requested, which must be at least as large as the size
|
appropriate to the selected key. The actual size of data retrieved is
|
appropriate to the selected key. The actual size of data retrieved is
|
placed in *len. The appropriate key values
|
placed in *len. The appropriate key values
|
differ for each driver and are all listed in the file
|
differ for each driver and are all listed in the file
|
<cyg/io/config_keys.h>.
|
<cyg/io/config_keys.h>.
|
|
|
|
|
|
|
// Change the configuration of a device
|
// Change the configuration of a device
|
Cyg_ErrNo cyg_io_set_config(
|
Cyg_ErrNo cyg_io_set_config(
|
cyg_io_handle_t handle,
|
cyg_io_handle_t handle,
|
cyg_uint32 key,
|
cyg_uint32 key,
|
const void *buf,
|
const void *buf,
|
cyg_uint32 *len )
|
cyg_uint32 *len )
|
|
|
|
|
|
|
This function is used to manipulate or change the run-time
|
This function is used to manipulate or change the run-time
|
configuration of a device. The type of information is specified by the
|
configuration of a device. The type of information is specified by the
|
key. The data will be obtained from the given
|
key. The data will be obtained from the given
|
buffer. The value of *len should contain the
|
buffer. The value of *len should contain the
|
amount of data provided, which must match the size appropriate to the
|
amount of data provided, which must match the size appropriate to the
|
selected key. The appropriate key values differ for each driver and
|
selected key. The appropriate key values differ for each driver and
|
are all listed in the file
|
are all listed in the file
|
<cyg/io/config_keys.h>.
|
<cyg/io/config_keys.h>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serial driver details
|
Serial driver details
|
|
|
|
|
Two different classes of serial drivers are provided as a standard
|
Two different classes of serial drivers are provided as a standard
|
part of the eCos system. These are described as “raw
|
part of the eCos system. These are described as “raw
|
serial” (serial) and “tty-like” (tty).
|
serial” (serial) and “tty-like” (tty).
|
|
|
|
|
|
|
|
|
|
|
Raw Serial Driver
|
Raw Serial Driver
|
|
|
|
|
Use the include file <cyg/io/serialio.h> for
|
Use the include file <cyg/io/serialio.h> for
|
this driver.
|
this driver.
|
|
|
|
|
|
|
The raw serial driver is capable of sending
|
The raw serial driver is capable of sending
|
and receiving blocks of raw data to a serial device. Controls are
|
and receiving blocks of raw data to a serial device. Controls are
|
provided to configure the actual hardware, but there is no manipulation
|
provided to configure the actual hardware, but there is no manipulation
|
of the data by this driver.
|
of the data by this driver.
|
|
|
|
|
|
|
There may be many instances of this driver in a given system,
|
There may be many instances of this driver in a given system,
|
one for each serial channel. Each channel corresponds to a physical
|
one for each serial channel. Each channel corresponds to a physical
|
device and there will typically be a device module created for this
|
device and there will typically be a device module created for this
|
purpose. The device modules themselves are configurable, allowing
|
purpose. The device modules themselves are configurable, allowing
|
specification of the actual hardware details, as well as such details
|
specification of the actual hardware details, as well as such details
|
as whether the channel should be buffered by the serial driver,
|
as whether the channel should be buffered by the serial driver,
|
etc.
|
etc.
|
|
|
|
|
|
|
|
|
|
|
Runtime Configuration
|
Runtime Configuration
|
|
|
|
|
Runtime configuration is achieved by exchanging data structures with
|
Runtime configuration is achieved by exchanging data structures with
|
the driver via the cyg_io_set_config() and
|
the driver via the cyg_io_set_config() and
|
cyg_io_get_config() functions.
|
cyg_io_get_config() functions.
|
|
|
|
|
|
|
typedef struct {
|
typedef struct {
|
cyg_serial_baud_rate_t baud;
|
cyg_serial_baud_rate_t baud;
|
cyg_serial_stop_bits_t stop;
|
cyg_serial_stop_bits_t stop;
|
cyg_serial_parity_t parity;
|
cyg_serial_parity_t parity;
|
cyg_serial_word_length_t word_length;
|
cyg_serial_word_length_t word_length;
|
cyg_uint32 flags;
|
cyg_uint32 flags;
|
} cyg_serial_info_t;
|
} cyg_serial_info_t;
|
|
|
|
|
|
|
The field word_length contains the number of data bits per word
|
-->word_length contains the number of data bits per word
|
(character). This must be one of the values:
|
(character). This must be one of the values:
|
|
|
|
|
|
|
CYGNUM_SERIAL_WORD_LENGTH_5
|
CYGNUM_SERIAL_WORD_LENGTH_5
|
CYGNUM_SERIAL_WORD_LENGTH_6
|
CYGNUM_SERIAL_WORD_LENGTH_6
|
CYGNUM_SERIAL_WORD_LENGTH_7
|
CYGNUM_SERIAL_WORD_LENGTH_7
|
CYGNUM_SERIAL_WORD_LENGTH_8
|
CYGNUM_SERIAL_WORD_LENGTH_8
|
|
|
|
|
|
|
The field baud contains a baud rate selection. This must be
|
-->baud contains a baud rate selection. This must be
|
one of the values:
|
one of the values:
|
|
|
|
|
|
|
CYGNUM_SERIAL_BAUD_50
|
CYGNUM_SERIAL_BAUD_50
|
CYGNUM_SERIAL_BAUD_75
|
CYGNUM_SERIAL_BAUD_75
|
CYGNUM_SERIAL_BAUD_110
|
CYGNUM_SERIAL_BAUD_110
|
CYGNUM_SERIAL_BAUD_134_5
|
CYGNUM_SERIAL_BAUD_134_5
|
CYGNUM_SERIAL_BAUD_150
|
CYGNUM_SERIAL_BAUD_150
|
CYGNUM_SERIAL_BAUD_200
|
CYGNUM_SERIAL_BAUD_200
|
CYGNUM_SERIAL_BAUD_300
|
CYGNUM_SERIAL_BAUD_300
|
CYGNUM_SERIAL_BAUD_600
|
CYGNUM_SERIAL_BAUD_600
|
CYGNUM_SERIAL_BAUD_1200
|
CYGNUM_SERIAL_BAUD_1200
|
CYGNUM_SERIAL_BAUD_1800
|
CYGNUM_SERIAL_BAUD_1800
|
CYGNUM_SERIAL_BAUD_2400
|
CYGNUM_SERIAL_BAUD_2400
|
CYGNUM_SERIAL_BAUD_3600
|
CYGNUM_SERIAL_BAUD_3600
|
CYGNUM_SERIAL_BAUD_4800
|
CYGNUM_SERIAL_BAUD_4800
|
CYGNUM_SERIAL_BAUD_7200
|
CYGNUM_SERIAL_BAUD_7200
|
CYGNUM_SERIAL_BAUD_9600
|
CYGNUM_SERIAL_BAUD_9600
|
CYGNUM_SERIAL_BAUD_14400
|
CYGNUM_SERIAL_BAUD_14400
|
CYGNUM_SERIAL_BAUD_19200
|
CYGNUM_SERIAL_BAUD_19200
|
CYGNUM_SERIAL_BAUD_38400
|
CYGNUM_SERIAL_BAUD_38400
|
CYGNUM_SERIAL_BAUD_57600
|
CYGNUM_SERIAL_BAUD_57600
|
CYGNUM_SERIAL_BAUD_115200
|
CYGNUM_SERIAL_BAUD_115200
|
CYGNUM_SERIAL_BAUD_234000
|
CYGNUM_SERIAL_BAUD_234000
|
|
|
|
|
The field stop contains the number of stop bits. This must be
|
-->stop contains the number of stop bits. This must be
|
one of the values:
|
one of the values:
|
|
|
|
|
CYGNUM_SERIAL_STOP_1
|
CYGNUM_SERIAL_STOP_1
|
CYGNUM_SERIAL_STOP_1_5
|
CYGNUM_SERIAL_STOP_1_5
|
CYGNUM_SERIAL_STOP_2
|
CYGNUM_SERIAL_STOP_2
|
|
|
|
|
|
|
Note
|
Note
|
|
|
On most hardware, a selection of 1.5 stop bits is only valid
|
On most hardware, a selection of 1.5 stop bits is only valid
|
if the word (character) length is 5.
|
if the word (character) length is 5.
|
|
|
|
|
|
|
The field parity contains the parity mode. This must be one of
|
-->parity contains the parity mode. This must be one of
|
the values:
|
the values:
|
|
|
|
|
CYGNUM_SERIAL_PARITY_NONE
|
CYGNUM_SERIAL_PARITY_NONE
|
CYGNUM_SERIAL_PARITY_EVEN
|
CYGNUM_SERIAL_PARITY_EVEN
|
CYGNUM_SERIAL_PARITY_ODD
|
CYGNUM_SERIAL_PARITY_ODD
|
CYGNUM_SERIAL_PARITY_MARK
|
CYGNUM_SERIAL_PARITY_MARK
|
CYGNUM_SERIAL_PARITY_SPACE
|
CYGNUM_SERIAL_PARITY_SPACE
|
|
|
|
|
The field flags is a bitmask which controls the behavior of the
|
-->flags is a bitmask which controls the behavior of the
|
serial device driver. It should be built from the values
|
serial device driver. It should be built from the values
|
CYG_SERIAL_FLAGS_xxx defined below:
|
CYG_SERIAL_FLAGS_xxx defined below:
|
|
|
|
|
|
|
#define CYG_SERIAL_FLAGS_RTSCTS 0x0001
|
#define CYG_SERIAL_FLAGS_RTSCTS 0x0001
|
|
|
|
|
If this bit is set then the port is placed in “hardware
|
If this bit is set then the port is placed in “hardware
|
handshake” mode. In this mode, the CTS and RTS pins control
|
handshake” mode. In this mode, the CTS and RTS pins control
|
when data is allowed to be sent/received at the port. This
|
when data is allowed to be sent/received at the port. This
|
bit is ignored if the hardware does not support this level of
|
bit is ignored if the hardware does not support this level of
|
handshake.
|
handshake.
|
|
|
|
|
|
|
typedef struct {
|
typedef struct {
|
cyg_int32 rx_bufsize;
|
cyg_int32 rx_bufsize;
|
cyg_int32 rx_count;
|
cyg_int32 rx_count;
|
cyg_int32 tx_bufsize;
|
cyg_int32 tx_bufsize;
|
cyg_int32 tx_count;
|
cyg_int32 tx_count;
|
} cyg_serial_buf_info_t;
|
} cyg_serial_buf_info_t;
|
|
|
|
|
The field rx_bufsize contains
|
The field rx_bufsize contains
|
the total size of the incoming data buffer. This is set to zero on
|
the total size of the incoming data buffer. This is set to zero on
|
devices that do not support buffering (i.e. polled devices).
|
devices that do not support buffering (i.e. polled devices).
|
|
|
The field rx_count contains the
|
The field rx_count contains the
|
number of bytes currently occupied in the incoming data buffer.
|
number of bytes currently occupied in the incoming data buffer.
|
This is set to zero on devices that do not support buffering (i.e. polled
|
This is set to zero on devices that do not support buffering (i.e. polled
|
devices).
|
devices).
|
|
|
The field tx_bufsize contains the
|
The field tx_bufsize contains the
|
total size of the transmit data buffer. This is set to zero on devices
|
total size of the transmit data buffer. This is set to zero on devices
|
that do not support buffering (i.e. polled devices).
|
that do not support buffering (i.e. polled devices).
|
|
|
The field tx_count contains the
|
The field tx_count contains the
|
number of bytes currently occupied in the transmit data buffer. This
|
number of bytes currently occupied in the transmit data buffer. This
|
is set to zero on devices that do not support buffering (i.e. polled
|
is set to zero on devices that do not support buffering (i.e. polled
|
devices).
|
devices).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
API Details
|
API Details
|
|
|
|
|
|
|
|
|
cyg_io_write
|
cyg_io_write
|
|
|
|
|
cyg_io_write(handle, buf, len)
|
cyg_io_write(handle, buf, len)
|
|
|
|
|
|
|
Send the data from buf to the device. The
|
Send the data from buf to the device. The
|
driver maintains a buffer to hold the data. The size of the
|
driver maintains a buffer to hold the data. The size of the
|
intermediate buffer is configurable within the interface module. The
|
intermediate buffer is configurable within the interface module. The
|
data is not modified at all while it is being buffered. On return,
|
data is not modified at all while it is being buffered. On return,
|
*len contains the amount of characters actually
|
*len contains the amount of characters actually
|
consumed .
|
consumed .
|
|
|
|
|
It is possible to configure the write call to be blocking
|
It is possible to configure the write call to be blocking
|
(default) or non-blocking. Non-blocking mode requires both the configuration
|
(default) or non-blocking. Non-blocking mode requires both the configuration
|
option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
|
option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
|
to be enabled, and the specific device to be set to non-blocking
|
to be enabled, and the specific device to be set to non-blocking
|
mode for writes (see cyg_io_set_config()).
|
mode for writes (see cyg_io_set_config()).
|
|
|
|
|
|
|
In blocking mode, the call will not return until there is space in the
|
In blocking mode, the call will not return until there is space in the
|
buffer and the entire contents of buf have been
|
buffer and the entire contents of buf have been
|
consumed.
|
consumed.
|
|
|
|
|
|
|
In non-blocking mode, as much as possible gets consumed from
|
In non-blocking mode, as much as possible gets consumed from
|
buf. If everything was consumed, the call
|
buf. If everything was consumed, the call
|
returns ENOERR. If only part of the
|
returns ENOERR. If only part of the
|
buf contents was consumed,
|
buf contents was consumed,
|
-EAGAIN is returned and the caller must try
|
-EAGAIN is returned and the caller must try
|
again. On return, *len contains the number of characters actually
|
again. On return, *len contains the number of characters actually
|
consumed .
|
consumed .
|
|
|
|
|
The call can also return -EINTR if interrupted
|
The call can also return -EINTR if interrupted
|
via the cyg_io_get_config()/ABORT key.
|
via the cyg_io_get_config()/ABORT key.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_io_read
|
cyg_io_read
|
|
|
|
|
cyg_io_read(handle, buf, len)
|
cyg_io_read(handle, buf, len)
|
|
|
|
|
|
|
Receive data into the buffer, buf, from the
|
Receive data into the buffer, buf, from the
|
device. No manipulation of the data is performed before being
|
device. No manipulation of the data is performed before being
|
transferred. An interrupt driven interface module will support data
|
transferred. An interrupt driven interface module will support data
|
arriving when no read is pending by buffering the data in the serial
|
arriving when no read is pending by buffering the data in the serial
|
driver. Again, this buffering is completely configurable. On return,
|
driver. Again, this buffering is completely configurable. On return,
|
*len contains the number of characters actually
|
*len contains the number of characters actually
|
received.
|
received.
|
|
|
|
|
It is possible to configure the read call to be blocking (default)
|
It is possible to configure the read call to be blocking (default)
|
or non-blocking. Non-blocking mode requires both the configuration
|
or non-blocking. Non-blocking mode requires both the configuration
|
option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
|
option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
|
to be enabled, and the specific device to be set to non-blocking
|
to be enabled, and the specific device to be set to non-blocking
|
mode for reads (see cyg_io_set_config()).
|
mode for reads (see cyg_io_set_config()).
|
|
|
|
|
|
|
In blocking mode, the call will not return until the requested
|
In blocking mode, the call will not return until the requested
|
amount of data has been read.
|
amount of data has been read.
|
|
|
|
|
In non-blocking mode, data waiting in the device buffer is copied to
|
In non-blocking mode, data waiting in the device buffer is copied to
|
buf, and the call returns immediately. If there
|
buf, and the call returns immediately. If there
|
was enough data in the buffer to fulfill the request,
|
was enough data in the buffer to fulfill the request,
|
ENOERR is returned. If only part of the request
|
ENOERR is returned. If only part of the request
|
could be fulfilled, -EAGAIN is returned and the
|
could be fulfilled, -EAGAIN is returned and the
|
caller must try again. On return, *len contains
|
caller must try again. On return, *len contains
|
the number of characters actually received.
|
the number of characters actually received.
|
|
|
|
|
The call can also return -EINTR if interrupted via
|
The call can also return -EINTR if interrupted via
|
the cyg_io_get_config()/ABORT
|
the cyg_io_get_config()/ABORT
|
key.
|
key.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_io_get_config
|
cyg_io_get_config
|
|
|
|
|
cyg_io_get_config(handle, key, buf, len)
|
cyg_io_get_config(handle, key, buf, len)
|
|
|
|
|
This function returns current [runtime] information
|
This function returns current [runtime] information
|
about the device and/or driver.
|
about the device and/or driver.
|
|
|
|
|
|
|
CYG_IO_GET_CONFIG_SERIAL_INFO
|
CYG_IO_GET_CONFIG_SERIAL_INFO
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
cyg_serial_info_t
|
cyg_serial_info_t
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
This function retrieves the current state of the driver
|
This function retrieves the current state of the driver
|
and hardware. This information contains fields for
|
and hardware. This information contains fields for
|
hardware baud rate, number of stop bits, and parity
|
hardware baud rate, number of stop bits, and parity
|
mode. It also includes a set of flags that control the
|
mode. It also includes a set of flags that control the
|
port, such as hardware flow control.
|
port, such as hardware flow control.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO
|
CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
cyg_serial_buf_info_t
|
cyg_serial_buf_info_t
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
This function retrieves the current state of the
|
This function retrieves the current state of the
|
software buffers in the serial drivers. For both
|
software buffers in the serial drivers. For both
|
receive and transmit buffers it returns the total
|
receive and transmit buffers it returns the total
|
buffer size and the current number of bytes occupied in
|
buffer size and the current number of bytes occupied in
|
the buffer. It does not take into account any buffering
|
the buffer. It does not take into account any buffering
|
such as FIFOs or holding registers that the serial
|
such as FIFOs or holding registers that the serial
|
device itself may have.
|
device itself may have.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
|
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
void *
|
void *
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
This function waits for any buffered output to
|
This function waits for any buffered output to
|
complete. This function only completes when there is no
|
complete. This function only completes when there is no
|
more data remaining to be sent to the device.
|
more data remaining to be sent to the device.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH
|
CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
void *
|
void *
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
This function discards any buffered output for the
|
This function discards any buffered output for the
|
device.
|
device.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CYG_IO_GET_CONFIG_SERIAL_INPUT_DRAIN
|
CYG_IO_GET_CONFIG_SERIAL_INPUT_DRAIN
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
void *
|
void *
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
This function discards any buffered input for the
|
This function discards any buffered input for the
|
device.
|
device.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CYG_IO_GET_CONFIG_SERIAL_ABORT
|
CYG_IO_GET_CONFIG_SERIAL_ABORT
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
void*
|
void*
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
This function will cause any pending read or write calls on
|
This function will cause any pending read or write calls on
|
this device to return with -EABORT.
|
this device to return with -EABORT.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CYG_IO_GET_CONFIG_SERIAL_READ_BLOCKING
|
CYG_IO_GET_CONFIG_SERIAL_READ_BLOCKING
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
cyg_uint32 (values 0 or 1)
|
cyg_uint32 (values 0 or 1)
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
This function will read back the blocking-mode
|
This function will read back the blocking-mode
|
setting for read calls on this device. This call is only
|
setting for read calls on this device. This call is only
|
available if the configuration option
|
available if the configuration option
|
CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING is
|
CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING is
|
enabled.
|
enabled.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CYG_IO_GET_CONFIG_SERIAL_WRITE_BLOCKING
|
CYG_IO_GET_CONFIG_SERIAL_WRITE_BLOCKING
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
cyg_uint32 (values 0 or 1)
|
cyg_uint32 (values 0 or 1)
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
This function will read back the blocking-mode
|
This function will read back the blocking-mode
|
setting for write calls on this device. This call is only
|
setting for write calls on this device. This call is only
|
available if the configuration option
|
available if the configuration option
|
CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING is enabled.
|
CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING is enabled.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_io_set_config
|
cyg_io_set_config
|
|
|
|
|
cyg_io_set_config(handle, key, buf,len)
|
cyg_io_set_config(handle, key, buf,len)
|
|
|
|
|
This function is used to update or change runtime configuration
|
This function is used to update or change runtime configuration
|
of a port.
|
of a port.
|
|
|
|
|
|
|
CYG_IO_SET_CONFIG_SERIAL_INFO
|
CYG_IO_SET_CONFIG_SERIAL_INFO
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
cyg_serial_info_t
|
cyg_serial_info_t
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
This function updates the information for the driver
|
This function updates the information for the driver
|
and hardware. The information contains fields for
|
and hardware. The information contains fields for
|
hardware baud rate, number of stop bits, and parity
|
hardware baud rate, number of stop bits, and parity
|
mode. It also includes a set of flags that control the
|
mode. It also includes a set of flags that control the
|
port, such as hardware flow control.
|
port, such as hardware flow control.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CYG_IO_SET_CONFIG_SERIAL_READ_BLOCKING
|
CYG_IO_SET_CONFIG_SERIAL_READ_BLOCKING
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
cyg_uint32 (values 0 or 1)
|
cyg_uint32 (values 0 or 1)
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
This function will set the blocking-mode for read
|
This function will set the blocking-mode for read
|
calls on this device. This call is only available if the
|
calls on this device. This call is only available if the
|
configuration option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
|
configuration option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
|
is enabled.
|
is enabled.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CYG_IO_SET_CONFIG_SERIAL_WRITE_BLOCKING
|
CYG_IO_SET_CONFIG_SERIAL_WRITE_BLOCKING
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
cyg_uint32 (values 0 or 1)
|
cyg_uint32 (values 0 or 1)
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
This function will set the blocking-mode for write
|
This function will set the blocking-mode for write
|
calls on this device. This call is only available if the
|
calls on this device. This call is only available if the
|
configuration option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
|
configuration option CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING
|
is enabled.
|
is enabled.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TTY driver
|
TTY driver
|
|
|
|
|
Use the include file <cyg/io/ttyio.h> for
|
Use the include file <cyg/io/ttyio.h> for
|
this driver.
|
this driver.
|
|
|
|
|
|
|
This driver is built on top of the simple
|
This driver is built on top of the simple
|
serial driver and is typically used for a device that interfaces with
|
serial driver and is typically used for a device that interfaces with
|
humans such as a terminal. It provides some minimal formatting of data
|
humans such as a terminal. It provides some minimal formatting of data
|
on output and allows for line-oriented editing on input.
|
on output and allows for line-oriented editing on input.
|
|
|
|
|
|
|
|
|
|
|
Runtime configuration
|
Runtime configuration
|
|
|
|
|
Runtime configuration is achieved by exchanging data structures with
|
Runtime configuration is achieved by exchanging data structures with
|
the driver via the cyg_io_set_config() and
|
the driver via the cyg_io_set_config() and
|
cyg_io_get_config() functions.
|
cyg_io_get_config() functions.
|
|
|
|
|
|
|
|
|
typedef struct {
|
typedef struct {
|
cyg_uint32 tty_out_flags;
|
cyg_uint32 tty_out_flags;
|
cyg_uint32 tty_in_flags;
|
cyg_uint32 tty_in_flags;
|
} cyg_tty_info_t;
|
} cyg_tty_info_t;
|
|
|
|
|
The field tty_out_flags
|
The field tty_out_flags
|
is used to control what happens to data as it is send to the serial
|
is used to control what happens to data as it is send to the serial
|
port. It contains a bitmap comprised of the bits as defined by the
|
port. It contains a bitmap comprised of the bits as defined by the
|
CYG_TTY_OUT_FLAGS_xxx values below.
|
CYG_TTY_OUT_FLAGS_xxx values below.
|
|
|
|
|
#define CYG_TTY_OUT_FLAGS_CRLF 0x0001 // Map '\n' => '\n\r' on output
|
#define CYG_TTY_OUT_FLAGS_CRLF 0x0001 // Map '\n' => '\n\r' on output
|
|
|
|
|
If this bit is set in tty_out_flags,
|
If this bit is set in tty_out_flags,
|
any occurrence of the character "\n" will
|
any occurrence of the character "\n" will
|
be replaced by the sequence "\n\r" before
|
be replaced by the sequence "\n\r" before
|
being sent to the device.
|
being sent to the device.
|
|
|
The field tty_in_flags
|
The field tty_in_flags
|
is used to control how data is handled as it comes from the serial
|
is used to control how data is handled as it comes from the serial
|
port. It contains a bitmap comprised of the bits as defined by the
|
port. It contains a bitmap comprised of the bits as defined by the
|
CYG_TTY_IN_FLAGS_xxx values below.
|
CYG_TTY_IN_FLAGS_xxx values below.
|
|
|
|
|
#define CYG_TTY_IN_FLAGS_CR 0x0001 // Map '\r' => '\n' on input
|
#define CYG_TTY_IN_FLAGS_CR 0x0001 // Map '\r' => '\n' on input
|
|
|
|
|
If this bit is set in tty_in_flags, the
|
If this bit is set in tty_in_flags, the
|
character "\r" (“return” or “enter” on
|
character "\r" (“return” or “enter” on
|
most keyboards) will be mapped to "\n".
|
most keyboards) will be mapped to "\n".
|
|
|
|
|
#define CYG_TTY_IN_FLAGS_CRLF 0x0002 // Map '\n\r' => '\n' on input
|
#define CYG_TTY_IN_FLAGS_CRLF 0x0002 // Map '\n\r' => '\n' on input
|
|
|
|
|
|
|
If this bit is set in tty_in_flags, the
|
If this bit is set in tty_in_flags, the
|
character sequence "\n\r" (often sent by DOS/Windows
|
character sequence "\n\r" (often sent by DOS/Windows
|
based terminals) will be mapped to "\n".
|
based terminals) will be mapped to "\n".
|
|
|
|
|
#define CYG_TTY_IN_FLAGS_BINARY 0x0004 // No input processing
|
#define CYG_TTY_IN_FLAGS_BINARY 0x0004 // No input processing
|
|
|
|
|
If this bit is set in tty_in_flags, the
|
If this bit is set in tty_in_flags, the
|
input will not be manipulated in any way before being placed in
|
input will not be manipulated in any way before being placed in
|
the user’s buffer.
|
the user’s buffer.
|
|
|
|
|
#define CYG_TTY_IN_FLAGS_ECHO 0x0008 // Echo characters as processed
|
#define CYG_TTY_IN_FLAGS_ECHO 0x0008 // Echo characters as processed
|
|
|
|
|
|
|
If this bit is set in tty_in_flags, characters
|
If this bit is set in tty_in_flags, characters
|
will be echoed back to the serial port as they are processed.
|
will be echoed back to the serial port as they are processed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
API details
|
API details
|
|
|
|
|
cyg_io_read(handle, buf, len)
|
cyg_io_read(handle, buf, len)
|
|
|
|
|
This function is used to read data from the device. In the
|
This function is used to read data from the device. In the
|
default case, data is read until an end-of-line character ("\n"
|
default case, data is read until an end-of-line character ("\n"
|
or "\r") is read. Additionally, the characters are echoed
|
or "\r") is read. Additionally, the characters are echoed
|
back to the [terminal] device. Minimal editing
|
back to the [terminal] device. Minimal editing
|
of the input is also supported.
|
of the input is also supported.
|
|
|
|
|
When connecting to a remote target via GDB it is not possible
|
When connecting to a remote target via GDB it is not possible
|
to provide console input while GDB is connected. The GDB remote
|
to provide console input while GDB is connected. The GDB remote
|
protocol does not support input. Users must disconnect from GDB
|
protocol does not support input. Users must disconnect from GDB
|
if this functionality is required.
|
if this functionality is required.
|
|
|
|
|
|
|
cyg_io_write(handle, buf, len)
|
cyg_io_write(handle, buf, len)
|
|
|
|
|
This function is used to send data to the device. In the default
|
This function is used to send data to the device. In the default
|
case, the end-of-line character "\n" is replaced by the
|
case, the end-of-line character "\n" is replaced by the
|
sequence "\n\r".
|
sequence "\n\r".
|
|
|
|
|
cyg_io_get_config(handle, key, buf, len)
|
cyg_io_get_config(handle, key, buf, len)
|
|
|
|
|
This function is used to get information about the channel’s
|
This function is used to get information about the channel’s
|
configuration at runtime.
|
configuration at runtime.
|
|
|
|
|
|
|
CYG_IO_GET_CONFIG_TTY_INFO
|
CYG_IO_GET_CONFIG_TTY_INFO
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
cyg_tty_info_t
|
cyg_tty_info_t
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
This function retrieves the current state of the
|
This function retrieves the current state of the
|
driver.
|
driver.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serial driver keys (see above) may also be specified
|
Serial driver keys (see above) may also be specified
|
in which case the call is passed directly to the serial
|
in which case the call is passed directly to the serial
|
driver.
|
driver.
|
|
|
|
|
cyg_io_set_config(handle, key, buf, len)
|
cyg_io_set_config(handle, key, buf, len)
|
|
|
|
|
This function is used to modify the channel’s configuration
|
This function is used to modify the channel’s configuration
|
at runtime.
|
at runtime.
|
|
|
|
|
|
|
|
|
CYG_IO_SET_CONFIG_TTY_INFO
|
CYG_IO_SET_CONFIG_TTY_INFO
|
|
|
|
|
|
|
Buf type:
|
Buf type:
|
|
|
cyg_tty_info_t
|
cyg_tty_info_t
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
This function changes the current state of the
|
This function changes the current state of the
|
driver.
|
driver.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serial driver
|
Serial driver
|
keys (see above) may also be specified in which case the
|
keys (see above) may also be specified in which case the
|
call is passed directly to the serial driver.
|
call is passed directly to the serial driver.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
How to Write a Driver
|
How to Write a Driver
|
|
|
|
|
|
|
|
|
A device driver is nothing more than a
|
A device driver is nothing more than a
|
named entity that supports the basic I/O functions - read, write, get
|
named entity that supports the basic I/O functions - read, write, get
|
config, and set config. Typically a device driver also uses and
|
config, and set config. Typically a device driver also uses and
|
manages interrupts from the device. While the interface is generic and
|
manages interrupts from the device. While the interface is generic and
|
device driver independent, the actual driver implementation is
|
device driver independent, the actual driver implementation is
|
completely up to the device driver designer.
|
completely up to the device driver designer.
|
|
|
That said, the reason for using a device driver is to provide
|
That said, the reason for using a device driver is to provide
|
access to a device from application code in as general purpose a
|
access to a device from application code in as general purpose a
|
fashion as reasonable. Most driver writers are also concerned with
|
fashion as reasonable. Most driver writers are also concerned with
|
making this access as simple as possible while being as efficient
|
making this access as simple as possible while being as efficient
|
as possible.
|
as possible.
|
|
|
Most device drivers are concerned with the movement of information,
|
Most device drivers are concerned with the movement of information,
|
for example data bytes along a serial interface, or packets in a
|
for example data bytes along a serial interface, or packets in a
|
network. In order to make the most efficient use of system resources,
|
network. In order to make the most efficient use of system resources,
|
interrupts are used. This will allow other application processing
|
interrupts are used. This will allow other application processing
|
to take place while the data transfers are under way, with interrupts
|
to take place while the data transfers are under way, with interrupts
|
used to indicate when various events have occurred. For example,
|
used to indicate when various events have occurred. For example,
|
a serial port typically generates an interrupt after a character
|
a serial port typically generates an interrupt after a character
|
has been sent “down the wire” and the interface
|
has been sent “down the wire” and the interface
|
is ready for another. It makes sense to allow further application
|
is ready for another. It makes sense to allow further application
|
processing while the data is being sent since this can take quite
|
processing while the data is being sent since this can take quite
|
a long time. The interrupt can be used to allow the driver to send
|
a long time. The interrupt can be used to allow the driver to send
|
a character as soon as the current one is complete, without any
|
a character as soon as the current one is complete, without any
|
active participation by the application code.
|
active participation by the application code.
|
|
|
The main building blocks for device drivers are found in the
|
The main building blocks for device drivers are found in the
|
include file: <cyg/io/devtab.h>
|
include file: <cyg/io/devtab.h>
|
|
|
All device drivers in eCos are described
|
All device drivers in eCos are described
|
by a device table entry, using the cyg_devtab_entry_t type.
|
by a device table entry, using the cyg_devtab_entry_t type.
|
The entry should be created using the DEVTAB_ENTRY() macro,
|
The entry should be created using the DEVTAB_ENTRY() macro,
|
like this:
|
like this:
|
|
|
|
|
DEVTAB_ENTRY(l, name, dep_name, handlers, init, lookup, priv)
|
DEVTAB_ENTRY(l, name, dep_name, handlers, init, lookup, priv)
|
|
|
|
|
|
|
Arguments
|
Arguments
|
|
|
l
|
l
|
The "C" label for this device table entry.
|
The "C" label for this device table entry.
|
|
|
|
|
name
|
name
|
The "C" string name for the device.
|
The "C" string name for the device.
|
|
|
|
|
dep_name
|
dep_name
|
For a layered device, the "C" string name of the
|
For a layered device, the "C" string name of the
|
device this device is built upon.
|
device this device is built upon.
|
|
|
|
|
handlers
|
handlers
|
A pointer to the I/O function "handlers" (see below).
|
A pointer to the I/O function "handlers" (see below).
|
|
|
|
|
init
|
init
|
A function called when eCos is initialized. This
|
A function called when eCos is initialized. This
|
function can query the device, setup hardware, etc.
|
function can query the device, setup hardware, etc.
|
|
|
|
|
lookup
|
lookup
|
A function called when cyg_io_lookup() is called
|
A function called when cyg_io_lookup() is called
|
for this device.
|
for this device.
|
|
|
|
|
priv
|
priv
|
A placeholder for any device specific data
|
A placeholder for any device specific data
|
required by the driver.
|
required by the driver.
|
|
|
|
|
|
|
The interface to the driver is through the handlers field. This is a pointer to
|
-->handlers field. This is a pointer to
|
a set of functions which implement the various cyg_io_XXX()
|
a set of functions which implement the various cyg_io_XXX()
|
routines. This table is defined by the macro:
|
routines. This table is defined by the macro:
|
|
|
|
|
|
|
DEVIO_TABLE(l, write, read, get_config, set_config)
|
DEVIO_TABLE(l, write, read, get_config, set_config)
|
|
|
|
|
|
|
Arguments
|
Arguments
|
|
|
l
|
l
|
The "C" label for this table of handlers.
|
The "C" label for this table of handlers.
|
|
|
|
|
write
|
write
|
The function called as a result of
|
The function called as a result of
|
cyg_io_write().
|
cyg_io_write().
|
|
|
|
|
read
|
read
|
The function called as a result of
|
The function called as a result of
|
cyg_io_read().
|
cyg_io_read().
|
|
|
|
|
get_config
|
get_config
|
The function called as a result of
|
The function called as a result of
|
cyg_io_get_config().
|
cyg_io_get_config().
|
|
|
|
|
set_config
|
set_config
|
The function called as a result of
|
The function called as a result of
|
cyg_io_set_config().
|
cyg_io_set_config().
|
|
|
|
|
|
|
|
|
When eCos is initialized (sometimes called
|
When eCos is initialized (sometimes called
|
“boot” time), the init() function is called
|
“boot” time), the init() function is called
|
for all devices in the system. The init() function is
|
for all devices in the system. The init() function is
|
allowed to return an error in which case the device will be placed
|
allowed to return an error in which case the device will be placed
|
“off line” and all I/O requests to that device will be
|
“off line” and all I/O requests to that device will be
|
considered in error.
|
considered in error.
|
|
|
|
|
|
|
The lookup() function is called whenever
|
The lookup() function is called whenever
|
the cyg_io_lookup() function
|
the cyg_io_lookup() function
|
is called with this device name. The lookup function may cause the device
|
is called with this device name. The lookup function may cause the device
|
to come “on line” which would then allow I/O
|
to come “on line” which would then allow I/O
|
operations to proceed. Future versions of the I/O system
|
operations to proceed. Future versions of the I/O system
|
will allow for other states, including power saving modes,
|
will allow for other states, including power saving modes,
|
etc.
|
etc.
|
|
|
|
|
|
|
|
|
|
|
|
|
How to Write a Serial Hardware Interface Driver
|
How to Write a Serial Hardware Interface Driver
|
|
|
|
|
The standard serial driver supplied with
|
The standard serial driver supplied with
|
eCos is structured as a hardware independent
|
eCos is structured as a hardware independent
|
portion and a hardware dependent interface module. To add support for
|
portion and a hardware dependent interface module. To add support for
|
a new serial port, the user should be able to use the existing
|
a new serial port, the user should be able to use the existing
|
hardware independent portion and just add their own interface driver which handles the details of the
|
-->interface driver which handles the details of the
|
actual device. The user should have no need to change the hardware
|
actual device. The user should have no need to change the hardware
|
independent portion.
|
independent portion.
|
|
|
The interfaces used by the serial driver and serial implementation
|
The interfaces used by the serial driver and serial implementation
|
modules are contained in the file <cyg/io/serial.h>
|
modules are contained in the file <cyg/io/serial.h>
|
|
|
|
|
|
|
In the sections below we use the notation <<xx>> to
|
In the sections below we use the notation <<xx>> to
|
mean a module specific value, referred to as “xx” below.
|
mean a module specific value, referred to as “xx” below.
|
|
|
|
|
|
|
|
|
|
|
DevTab Entry
|
DevTab Entry
|
|
|
The interface module contains the devtab entry (or entries
|
The interface module contains the devtab entry (or entries
|
if a single module supports more than one interface). This entry
|
if a single module supports more than one interface). This entry
|
should have the form:
|
should have the form:
|
|
|
|
|
DEVTAB_ENTRY(<<module_name>>,
|
DEVTAB_ENTRY(<<module_name>>,
|
<<device_name>>,
|
<<device_name>>,
|
0,
|
0,
|
&serial_devio,
|
&serial_devio,
|
<<module_init>>,
|
<<module_init>>,
|
<<module_lookup>>,
|
<<module_lookup>>,
|
&<<serial_channel>>
|
&<<serial_channel>>
|
);
|
);
|
|
|
|
|
|
|
Arguments
|
Arguments
|
|
|
module_name
|
module_name
|
The "C" label for this devtab entry
|
The "C" label for this devtab entry
|
|
|
|
|
device_name
|
device_name
|
The "C" string for the
|
The "C" string for the
|
device. E.g. /dev/serial0.
|
device. E.g. /dev/serial0.
|
|
|
|
|
serial_devio
|
serial_devio
|
The table of I/O functions. This set is defined in
|
The table of I/O functions. This set is defined in
|
the hardware independent serial driver and should be used.
|
the hardware independent serial driver and should be used.
|
|
|
|
|
|
|
module_init
|
module_init
|
The module initialization function.
|
The module initialization function.
|
|
|
|
|
module_lookup
|
module_lookup
|
The device lookup function. This function
|
The device lookup function. This function
|
typically sets up the device for actual use, turning on
|
typically sets up the device for actual use, turning on
|
interrupts, configuring the port, etc.
|
interrupts, configuring the port, etc.
|
|
|
|
|
serial_channel
|
serial_channel
|
This table (defined below) contains the interface
|
This table (defined below) contains the interface
|
between the interface module and the serial driver proper.
|
between the interface module and the serial driver proper.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serial Channel Structure
|
Serial Channel Structure
|
|
|
Each serial device must have a “serial channel”.
|
Each serial device must have a “serial channel”.
|
This is a set of data which describes all operations on the device.
|
This is a set of data which describes all operations on the device.
|
It also contains buffers, etc., if the device is to be buffered.
|
It also contains buffers, etc., if the device is to be buffered.
|
The serial channel is created by the macro:
|
The serial channel is created by the macro:
|
|
|
|
|
SERIAL_CHANNEL_USING_INTERRUPTS(l, funs, dev_priv, baud,stop, parity, word_length,
|
SERIAL_CHANNEL_USING_INTERRUPTS(l, funs, dev_priv, baud,stop, parity, word_length,
|
flags, out_buf, out_buflen, in_buf, in_buflen)
|
flags, out_buf, out_buflen, in_buf, in_buflen)
|
|
|
|
|
|
|
Arguments
|
Arguments
|
|
|
l
|
l
|
The "C" label for this structure.
|
The "C" label for this structure.
|
|
|
|
|
funs
|
funs
|
The set of interface functions (see below).
|
The set of interface functions (see below).
|
|
|
|
|
dev_priv
|
dev_priv
|
A placeholder for any device specific data for
|
A placeholder for any device specific data for
|
this channel.
|
this channel.
|
|
|
|
|
baud
|
baud
|
The initial baud rate value
|
The initial baud rate value
|
(cyg_serial_baud_t).
|
(cyg_serial_baud_t).
|
|
|
|
|
stop
|
stop
|
The initial stop bits value
|
The initial stop bits value
|
(cyg_serial_stop_bits_t).
|
(cyg_serial_stop_bits_t).
|
|
|
|
|
parity
|
parity
|
The initial parity mode value
|
The initial parity mode value
|
(cyg_serial_parity_t).
|
(cyg_serial_parity_t).
|
|
|
|
|
word_length
|
word_length
|
The initial word length value
|
The initial word length value
|
(cyg_serial_word_length_t).
|
(cyg_serial_word_length_t).
|
|
|
|
|
flags
|
flags
|
The initial driver flags value.
|
The initial driver flags value.
|
|
|
|
|
out_buf
|
out_buf
|
Pointer to the output
|
Pointer to the output
|
buffer. NULL if none required.
|
buffer. NULL if none required.
|
|
|
|
|
out_buflen
|
out_buflen
|
The length of the output buffer.
|
The length of the output buffer.
|
|
|
|
|
in_buf
|
in_buf
|
pointer to the input
|
pointer to the input
|
buffer. NULL if none required.
|
buffer. NULL if none required.
|
|
|
|
|
in_buflen
|
in_buflen
|
The length of the input buffer.
|
The length of the input buffer.
|
|
|
|
|
|
|
|
|
If either buffer length is zero, no buffering will take place
|
If either buffer length is zero, no buffering will take place
|
in that direction and only polled mode functions will be used.
|
in that direction and only polled mode functions will be used.
|
|
|
|
|
|
|
The interface from the hardware independent driver into the
|
The interface from the hardware independent driver into the
|
hardware interface module is contained in the funs table.
|
hardware interface module is contained in the funs table.
|
This is defined by the macro:
|
This is defined by the macro:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serial Functions Structure
|
Serial Functions Structure
|
|
|
|
|
SERIAL_FUNS(l, putc, getc, set_config, start_xmit, stop_xmit)
|
SERIAL_FUNS(l, putc, getc, set_config, start_xmit, stop_xmit)
|
|
|
|
|
|
|
|
|
Arguments
|
Arguments
|
|
|
l
|
l
|
The "C" label for this structure.
|
The "C" label for this structure.
|
|
|
|
|
putc
|
putc
|
|
|
bool (*putc)(serial_channel *priv, unsigned char
|
bool (*putc)(serial_channel *priv, unsigned char
|
c)
|
c)
|
|
|
This function sends one character to the interface. It should
|
This function sends one character to the interface. It should
|
return true if the character is actually consumed. It should
|
return true if the character is actually consumed. It should
|
return false if there is no space in the interface
|
return false if there is no space in the interface
|
|
|
|
|
|
|
|
|
getc
|
getc
|
|
|
unsigned char (*getc)(serial_channel *priv)
|
unsigned char (*getc)(serial_channel *priv)
|
|
|
This function fetches one character from the interface. It will
|
This function fetches one character from the interface. It will
|
be only called in a non-interrupt driven mode, thus it should
|
be only called in a non-interrupt driven mode, thus it should
|
wait for a character by polling the device until ready.
|
wait for a character by polling the device until ready.
|
|
|
|
|
|
|
|
|
set_config
|
set_config
|
|
|
bool (*set_config)(serial_channel
|
bool (*set_config)(serial_channel
|
*priv,cyg_serial_info_t *config)
|
*priv,cyg_serial_info_t *config)
|
|
|
This function is used to configure the port. It should return
|
This function is used to configure the port. It should return
|
true if the hardware is updated to match the desired
|
true if the hardware is updated to match the desired
|
configuration. It should return false if the port cannot
|
configuration. It should return false if the port cannot
|
support some parameter specified by the given
|
support some parameter specified by the given
|
configuration. E.g. selecting 1.5 stop bits and 8 data bits is
|
configuration. E.g. selecting 1.5 stop bits and 8 data bits is
|
invalid for most serial devices and should not be allowed.
|
invalid for most serial devices and should not be allowed.
|
|
|
|
|
|
|
|
|
start_xmit
|
start_xmit
|
void (*start_xmit)(serial_channel *priv)
|
void (*start_xmit)(serial_channel *priv)
|
|
|
In interrupt mode, turn on the transmitter and allow for
|
In interrupt mode, turn on the transmitter and allow for
|
transmit interrupts.
|
transmit interrupts.
|
|
|
|
|
|
|
|
|
stop_xmit
|
stop_xmit
|
|
|
void (*stop_xmit)(serial_channel *priv)
|
void (*stop_xmit)(serial_channel *priv)
|
In interrupt mode, turn off the transmitter.
|
In interrupt mode, turn off the transmitter.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Callbacks
|
Callbacks
|
|
|
|
|
The device interface module can execute functions in the
|
The device interface module can execute functions in the
|
hardware independent driver via chan->callbacks.
|
hardware independent driver via chan->callbacks.
|
These functions are available:
|
These functions are available:
|
|
|
|
|
|
|
void (*serial_init)( serial_channel *chan )
|
void (*serial_init)( serial_channel *chan )
|
|
|
|
|
This function is used to initialize the serial channel. It
|
This function is used to initialize the serial channel. It
|
is only required if the channel is being used in interrupt
|
is only required if the channel is being used in interrupt
|
mode.
|
mode.
|
|
|
|
|
void (*xmt_char)( serial_channel *chan )
|
void (*xmt_char)( serial_channel *chan )
|
|
|
|
|
|
|
This function would be called from an interrupt handler after a
|
This function would be called from an interrupt handler after a
|
transmit interrupt indicating that additional characters may be
|
transmit interrupt indicating that additional characters may be
|
sent. The upper driver will call the putc
|
sent. The upper driver will call the putc
|
function as appropriate to send more data to the device.
|
function as appropriate to send more data to the device.
|
|
|
|
|
void (*rcv_char)( serial_channel *chan, unsigned char c )
|
void (*rcv_char)( serial_channel *chan, unsigned char c )
|
|
|
|
|
|
|
|
|
This function is used to tell the driver that a character has arrived
|
This function is used to tell the driver that a character has arrived
|
at the interface. This function is typically called from the interrupt
|
at the interface. This function is typically called from the interrupt
|
handler.
|
handler.
|
|
|
|
|
Furthermore, if the device has a FIFO it should require the hardware
|
Furthermore, if the device has a FIFO it should require the hardware
|
independent driver to provide block transfer functionality (driver CDL
|
independent driver to provide block transfer functionality (driver CDL
|
should include "implements
|
should include "implements
|
CYGINT_IO_SERIAL_BLOCK_TRANSFER"). In that case, the following
|
CYGINT_IO_SERIAL_BLOCK_TRANSFER"). In that case, the following
|
functions are available as well:
|
functions are available as well:
|
|
|
|
|
bool (*data_xmt_req)(serial_channel *chan,
|
bool (*data_xmt_req)(serial_channel *chan,
|
int space,
|
int space,
|
int* chars_avail,
|
int* chars_avail,
|
unsigned char** chars)
|
unsigned char** chars)
|
void (*data_xmt_done)(serial_channel *chan)
|
void (*data_xmt_done)(serial_channel *chan)
|
|
|
|
|
|
|
Instead of calling xmt_char() to get a single
|
Instead of calling xmt_char() to get a single
|
character for transmission at a time, the driver should call
|
character for transmission at a time, the driver should call
|
data_xmt_req() in a loop, requesting character
|
data_xmt_req() in a loop, requesting character
|
blocks for transfer. Call with a space argument of how much space
|
blocks for transfer. Call with a space argument of how much space
|
there is available in the FIFO.
|
there is available in the FIFO.
|
|
|
If the call returns true, the driver can read
|
If the call returns true, the driver can read
|
chars_avail characters from
|
chars_avail characters from
|
chars and copy them into the FIFO.
|
chars and copy them into the FIFO.
|
|
|
If the call returns false, there are
|
If the call returns false, there are
|
no more buffered characters and the driver should continue without
|
no more buffered characters and the driver should continue without
|
filling up the FIFO.
|
filling up the FIFO.
|
|
|
When all data has been unloaded, the
|
When all data has been unloaded, the
|
driver must call data_xmt_done().
|
driver must call data_xmt_done().
|
|
|
|
|
|
|
bool (*data_rcv_req)(serial_channel *chan,
|
bool (*data_rcv_req)(serial_channel *chan,
|
int avail,
|
int avail,
|
int* space_avail,
|
int* space_avail,
|
unsigned char** space)
|
unsigned char** space)
|
void (*data_rcv_done)(serial_channel *chan)
|
void (*data_rcv_done)(serial_channel *chan)
|
|
|
|
|
Instead of calling rcv_char() with a single
|
Instead of calling rcv_char() with a single
|
character at a time, the driver should call
|
character at a time, the driver should call
|
data_rcv_req() in a loop, requesting space to
|
data_rcv_req() in a loop, requesting space to
|
unload the FIFO to. avail is the number of
|
unload the FIFO to. avail is the number of
|
characters the driver wishes to unload.
|
characters the driver wishes to unload.
|
|
|
|
|
If the call returns true, the driver can copy
|
If the call returns true, the driver can copy
|
space_avail characters to
|
space_avail characters to
|
space.
|
space.
|
|
|
|
|
If the call returns false, the input buffer is
|
If the call returns false, the input buffer is
|
full. It is up to the driver to decide what to do in that case
|
full. It is up to the driver to decide what to do in that case
|
(callback functions for registering overflow are being planned for
|
(callback functions for registering overflow are being planned for
|
later versions of the serial driver).
|
later versions of the serial driver).
|
|
|
|
|
When all data has been unloaded, the driver must call
|
When all data has been unloaded, the driver must call
|
data_rcv_done().
|
data_rcv_done().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serial testing with ser_filter
|
Serial testing with ser_filter
|
|
|
|
|
|
|
|
|
Rationale
|
Rationale
|
|
|
|
|
Since some targets only have one serial connection, a serial testing harness
|
Since some targets only have one serial connection, a serial testing harness
|
needs to be able to share the connection with GDB
|
needs to be able to share the connection with GDB
|
(however, the test and GDB can also run on separate
|
(however, the test and GDB can also run on separate
|
lines).
|
lines).
|
|
|
|
|
|
|
The serial filter (ser_filter)
|
The serial filter (ser_filter)
|
sits between the serial port and GDB and monitors
|
sits between the serial port and GDB and monitors
|
the exchange of data between GDB and the target.
|
the exchange of data between GDB and the target.
|
Normally, no changes are made to the data.
|
Normally, no changes are made to the data.
|
|
|
|
|
|
|
When a test request packet is sent from the test on the target, it is
|
When a test request packet is sent from the test on the target, it is
|
intercepted by the filter.
|
intercepted by the filter.
|
|
|
|
|
|
|
The filter and target then enter a loop, exchanging protocol data between
|
The filter and target then enter a loop, exchanging protocol data between
|
them which GDB never sees.
|
them which GDB never sees.
|
|
|
|
|
|
|
In the event of a timeout, or a crash on the target, the filter falls
|
In the event of a timeout, or a crash on the target, the filter falls
|
back into its pass-through mode. If this happens due to a crash it should be
|
back into its pass-through mode. If this happens due to a crash it should be
|
possible to start regular debugging with GDB. The
|
possible to start regular debugging with GDB. The
|
filter will stay in the pass-though mode until GDB
|
filter will stay in the pass-though mode until GDB
|
disconnects.
|
disconnects.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The Protocol
|
The Protocol
|
|
|
The protocol commands are prefixed with an "@"
|
The protocol commands are prefixed with an "@"
|
character which the serial filter is looking for. The protocol
|
character which the serial filter is looking for. The protocol
|
commands include:
|
commands include:
|
|
|
|
|
|
|
|
|
PING
|
PING
|
|
|
Allows the test on the target to probe for the filter. The
|
Allows the test on the target to probe for the filter. The
|
filter responds with OK, while
|
filter responds with OK, while
|
GDB would just ignore the
|
GDB would just ignore the
|
command. This allows the tests to do nothing if they require the
|
command. This allows the tests to do nothing if they require the
|
filter and it is not present.
|
filter and it is not present.
|
|
|
|
|
|
|
CONFIG
|
CONFIG
|
|
|
Requests a change of serial line configuration. Arguments
|
Requests a change of serial line configuration. Arguments
|
to the command specify baud rate, data bits, stop bits, and
|
to the command specify baud rate, data bits, stop bits, and
|
parity. [This command is not fully implemented yet - there is no
|
parity. [This command is not fully implemented yet - there is no
|
attempt made to recover if the new configuration turns out to
|
attempt made to recover if the new configuration turns out to
|
cause loss of data.]
|
cause loss of data.]
|
|
|
|
|
|
|
BINARY
|
BINARY
|
|
|
Requests data to be sent from the filter to the
|
Requests data to be sent from the filter to the
|
target. The data is checksummed, allowing errors in the transfer
|
target. The data is checksummed, allowing errors in the transfer
|
to be detected. Sub-options of this command control how the
|
to be detected. Sub-options of this command control how the
|
data transfer is made:
|
data transfer is made:
|
|
|
|
|
NO_ECHO
|
NO_ECHO
|
|
|
(serial driver receive test) Just send data from the
|
(serial driver receive test) Just send data from the
|
filter to the target. The test verifies the checksum and
|
filter to the target. The test verifies the checksum and
|
PASS/FAIL depending on the result.
|
PASS/FAIL depending on the result.
|
|
|
|
|
|
|
EOP_ECHO
|
EOP_ECHO
|
|
|
(serial driver half-duplex receive and send test) As
|
(serial driver half-duplex receive and send test) As
|
NO_ECHO but the test echoes back the
|
NO_ECHO but the test echoes back the
|
data to the filter. The filter does a checksum on the
|
data to the filter. The filter does a checksum on the
|
received data and sends the result to the target. The test
|
received data and sends the result to the target. The test
|
PASS/FAIL depending on the result of both checksum
|
PASS/FAIL depending on the result of both checksum
|
verifications.
|
verifications.
|
|
|
|
|
|
|
DUPLEX_ECHO
|
DUPLEX_ECHO
|
|
|
(serial driver duplex receive and send test) Smaller
|
(serial driver duplex receive and send test) Smaller
|
packets of data are sent back and forth in a pattern that
|
packets of data are sent back and forth in a pattern that
|
ensures that the serial driver will be both sending and
|
ensures that the serial driver will be both sending and
|
receiving at the same time. Again, checksums are computed
|
receiving at the same time. Again, checksums are computed
|
and verified resulting in PASS/FAIL.
|
and verified resulting in PASS/FAIL.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TEXT
|
TEXT
|
|
|
This is a test of the text translations in the TTY layer.
|
This is a test of the text translations in the TTY layer.
|
Requests a transfer of text data from the target to the filter
|
Requests a transfer of text data from the target to the filter
|
and possibly back again. The filter treats this as a binary
|
and possibly back again. The filter treats this as a binary
|
transfer, while the target ma be doing translations on the
|
transfer, while the target ma be doing translations on the
|
data. The target provides the filter with checksums for what it
|
data. The target provides the filter with checksums for what it
|
should expect to see. This test is not implemented yet.
|
should expect to see. This test is not implemented yet.
|
|
|
|
|
|
|
|
|
|
|
The above commands may be extended, and new commands added, as
|
The above commands may be extended, and new commands added, as
|
required to test (new) parts of the serial drivers in
|
required to test (new) parts of the serial drivers in
|
eCos.
|
eCos.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The Serial Tests
|
The Serial Tests
|
|
|
|
|
The serial tests are built as any other eCos test. After running the
|
The serial tests are built as any other eCos test. After running the
|
make tests command, the tests can be found in
|
make tests command, the tests can be found in
|
install/tests/io_serial/
|
install/tests/io_serial/
|
|
|
|
|
|
|
serial1
|
serial1
|
A simple API test.
|
A simple API test.
|
|
|
|
|
serial2
|
serial2
|
|
|
A simple serial send test. It writes out two strings, one
|
A simple serial send test. It writes out two strings, one
|
raw and one encoded as a GDB
|
raw and one encoded as a GDB
|
O-packet
|
O-packet
|
|
|
|
|
|
|
serial3 [ requires the serial filter ]
|
serial3 [ requires the serial filter ]
|
|
|
This tests the half-duplex send and receive capabilities
|
This tests the half-duplex send and receive capabilities
|
of the serial driver.
|
of the serial driver.
|
|
|
|
|
|
|
serial4 [ requires the serial filter ]
|
serial4 [ requires the serial filter ]
|
|
|
This test attempts to use a few different serial
|
This test attempts to use a few different serial
|
configurations, testing the driver's configuration/setup
|
configurations, testing the driver's configuration/setup
|
functionality.
|
functionality.
|
|
|
|
|
|
|
serial5 [ requires the serial filter ]
|
serial5 [ requires the serial filter ]
|
|
|
This tests the duplex send and receive capabilities of the
|
This tests the duplex send and receive capabilities of the
|
serial driver.
|
serial driver.
|
|
|
|
|
|
|
|
|
All tests should complete in less than 30 seconds.
|
All tests should complete in less than 30 seconds.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Serial Filter Usage
|
Serial Filter Usage
|
|
|
Running the ser_filter program with no (or wrong) arguments results in
|
Running the ser_filter program with no (or wrong) arguments results in
|
the following output:
|
the following output:
|
|
|
|
|
|
|
Usage: ser_filter [-t -S] TcpIPport SerialPort BaudRate
|
Usage: ser_filter [-t -S] TcpIPport SerialPort BaudRate
|
or: ser_filter -n [-t -S] SerialPort BaudRate
|
or: ser_filter -n [-t -S] SerialPort BaudRate
|
-t: Enable tracing.
|
-t: Enable tracing.
|
-S: Output data read from serial line.
|
-S: Output data read from serial line.
|
-c: Output data on console instead of via GDB.
|
-c: Output data on console instead of via GDB.
|
-n: No GDB.
|
-n: No GDB.
|
|
|
|
|
The normal way to use it with GDB is to start the filter:
|
The normal way to use it with GDB is to start the filter:
|
|
|
|
|
$ ser_filter -t 9000 com1 38400
|
$ ser_filter -t 9000 com1 38400
|
|
|
|
|
|
|
In this case, the filter will be listening on port 9000 and connect to the
|
In this case, the filter will be listening on port 9000 and connect to the
|
target via the serial port COM1 at 38400 baud. On a UNIX
|
target via the serial port COM1 at 38400 baud. On a UNIX
|
host, replace "COM1" with a device such as
|
host, replace "COM1" with a device such as
|
"/dev/ttyS0".
|
"/dev/ttyS0".
|
|
|
|
|
|
|
The option enables tracing which will cause the
|
The option enables tracing which will cause the
|
filter to describe its actions on the console.
|
filter to describe its actions on the console.
|
|
|
|
|
Now start GDB with one of the tests as an
|
Now start GDB with one of the tests as an
|
argument:
|
argument:
|
|
|
|
|
|
|
$ mips-tx39-elf-gdb -nw install/tests/io_serial/serial3
|
$ mips-tx39-elf-gdb -nw install/tests/io_serial/serial3
|
|
|
|
|
Then connect to the filter:
|
Then connect to the filter:
|
|
|
|
|
(gdb) target remote localhost:9000
|
(gdb) target remote localhost:9000
|
|
|
|
|
|
|
This should result in a connection in exactly the same way as if you
|
This should result in a connection in exactly the same way as if you
|
had connected directly to the target on the serial line.
|
had connected directly to the target on the serial line.
|
|
|
|
|
|
|
(gdb) c
|
(gdb) c
|
|
|
|
|
|
|
Which should result in output similar to the below:
|
Which should result in output similar to the below:
|
|
|
|
|
|
|
Continuing.
|
Continuing.
|
INFO: <BINARY:16:1!>
|
INFO: <BINARY:16:1!>
|
PASS: <Binary test completed>
|
PASS: <Binary test completed>
|
INFO: <BINARY:128:1!>
|
INFO: <BINARY:128:1!>
|
PASS: <Binary test completed>
|
PASS: <Binary test completed>
|
INFO: <BINARY:256:1!>
|
INFO: <BINARY:256:1!>
|
PASS: <Binary test completed>
|
PASS: <Binary test completed>
|
INFO: <BINARY:1024:1!>
|
INFO: <BINARY:1024:1!>
|
PASS: <Binary test completed>
|
PASS: <Binary test completed>
|
INFO: <BINARY:512:0!>
|
INFO: <BINARY:512:0!>
|
PASS: <Binary test completed>
|
PASS: <Binary test completed>
|
...
|
...
|
PASS: <Binary test completed>
|
PASS: <Binary test completed>
|
INFO: <BINARY:16384:0!>
|
INFO: <BINARY:16384:0!>
|
PASS: <Binary test completed>
|
PASS: <Binary test completed>
|
PASS: <serial13 test OK>
|
PASS: <serial13 test OK>
|
EXIT: <done>
|
EXIT: <done>
|
|
|
|
|
|
|
If any of the individual tests fail the testing will terminate with a
|
If any of the individual tests fail the testing will terminate with a
|
FAIL.
|
FAIL.
|
|
|
|
|
|
|
With tracing enabled, you would also see the filter's status output:
|
With tracing enabled, you would also see the filter's status output:
|
|
|
|
|
|
|
The PING command sent from the target to determine the
|
The PING command sent from the target to determine the
|
presence of the filter:
|
presence of the filter:
|
|
|
|
|
|
|
[400 11:35:16] Dispatching command PING
|
[400 11:35:16] Dispatching command PING
|
[400 11:35:16] Responding with status OK
|
[400 11:35:16] Responding with status OK
|
|
|
|
|
Each of the binary commands result in output similar to:
|
Each of the binary commands result in output similar to:
|
|
|
|
|
[400 11:35:16] Dispatching command BINARY
|
[400 11:35:16] Dispatching command BINARY
|
[400 11:35:16] Binary data (Size:16, Flags:1).
|
[400 11:35:16] Binary data (Size:16, Flags:1).
|
[400 11:35:16] Sending CRC: '170231!', len: 7.
|
[400 11:35:16] Sending CRC: '170231!', len: 7.
|
[400 11:35:16] Reading 16 bytes from target.
|
[400 11:35:16] Reading 16 bytes from target.
|
[400 11:35:16] Done. in_crc 170231, out_crc 170231.
|
[400 11:35:16] Done. in_crc 170231, out_crc 170231.
|
[400 11:35:16] Responding with status OK
|
[400 11:35:16] Responding with status OK
|
[400 11:35:16] Received DONE from target.
|
[400 11:35:16] Received DONE from target.
|
|
|
|
|
|
|
This tracing output is normally sent as O-packets to GDB
|
This tracing output is normally sent as O-packets to GDB
|
which will display the tracing text. By using the
|
which will display the tracing text. By using the
|
option, the tracing text can be redirected to the
|
option, the tracing text can be redirected to the
|
console from which ser_filter was started.
|
console from which ser_filter was started.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A Note on Failures
|
A Note on Failures
|
|
|
|
|
A serial connection (especially when driven at a high baud rate) can garble the
|
A serial connection (especially when driven at a high baud rate) can garble the
|
transmitted data because of noise from the environment. It is not the job of
|
transmitted data because of noise from the environment. It is not the job of
|
the serial driver to ensure data integrity - that is the job of protocols
|
the serial driver to ensure data integrity - that is the job of protocols
|
layering on top of the serial driver.
|
layering on top of the serial driver.
|
|
|
In the current implementation the serial tests and the serial filter are
|
In the current implementation the serial tests and the serial filter are
|
not resilient to such data errors. This means that the test may crash or hang
|
not resilient to such data errors. This means that the test may crash or hang
|
(possibly without reporting a FAIL). It also
|
(possibly without reporting a FAIL). It also
|
means that you should be aware of random errors - a FAIL
|
means that you should be aware of random errors - a FAIL
|
is not necessarily caused by a bug in the serial driver.
|
is not necessarily caused by a bug in the serial driver.
|
|
|
|
|
Ideally, the serial testing infrastructure should be able to distinguish
|
Ideally, the serial testing infrastructure should be able to distinguish
|
random errors from consistent errors - the former are most likely due to noise
|
random errors from consistent errors - the former are most likely due to noise
|
in the transfer medium, while the latter are more likely to be caused by faulty
|
in the transfer medium, while the latter are more likely to be caused by faulty
|
drivers. The current implementation of the infrastructure does not have this
|
drivers. The current implementation of the infrastructure does not have this
|
capability.
|
capability.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Debugging
|
Debugging
|
|
|
If a test fails, the serial filter's output may provide some hints about
|
If a test fails, the serial filter's output may provide some hints about
|
what the problem is. If the option is used when starting
|
what the problem is. If the option is used when starting
|
the filter, data received from the target is printed out:
|
the filter, data received from the target is printed out:
|
|
|
|
|
|
|
[400 11:35:16] 0000 50 41 53 53 3a 3c 42 69 'PASS:<Bi'
|
[400 11:35:16] 0000 50 41 53 53 3a 3c 42 69 'PASS:<Bi'
|
[400 11:35:16] 0008 6e 61 72 79 20 74 65 73 'nary.tes'
|
[400 11:35:16] 0008 6e 61 72 79 20 74 65 73 'nary.tes'
|
[400 11:35:16] 0010 74 20 63 6f 6d 70 6c 65 't.comple'
|
[400 11:35:16] 0010 74 20 63 6f 6d 70 6c 65 't.comple'
|
[400 11:35:16] 0018 74 65 64 3e 0d 0a 49 4e 'ted>..IN'
|
[400 11:35:16] 0018 74 65 64 3e 0d 0a 49 4e 'ted>..IN'
|
[400 11:35:16] 0020 46 4f 3a 3c 42 49 4e 41 'FO:<BINA'
|
[400 11:35:16] 0020 46 4f 3a 3c 42 49 4e 41 'FO:<BINA'
|
[400 11:35:16] 0028 52 59 3a 31 32 38 3a 31 'RY:128:1'
|
[400 11:35:16] 0028 52 59 3a 31 32 38 3a 31 'RY:128:1'
|
[400 11:35:16] 0030 21 3e 0d 0a 40 42 49 4e '!..@BIN'
|
[400 11:35:16] 0030 21 3e 0d 0a 40 42 49 4e '!..@BIN'
|
[400 11:35:16] 0038 41 52 59 3a 31 32 38 3a 'ARY:128:'
|
[400 11:35:16] 0038 41 52 59 3a 31 32 38 3a 'ARY:128:'
|
[400 11:35:16] 0040 31 21 .. .. .. .. .. .. '1!'
|
[400 11:35:16] 0040 31 21 .. .. .. .. .. .. '1!'
|
|
|
|
|
In the case of an error during a testing command the data received by the
|
In the case of an error during a testing command the data received by the
|
filter will be printed out, as will the data that was expected. This allows
|
filter will be printed out, as will the data that was expected. This allows
|
the two data sets to be compared which may give some idea of what the problem
|
the two data sets to be compared which may give some idea of what the problem
|
is.
|
is.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Device Driver Interface to the Kernel
|
Device Driver Interface to the Kernel
|
|
|
|
|
This chapter describes the API that device drivers may use
|
This chapter describes the API that device drivers may use
|
to interact with the kernel and HAL. It is primarily concerned with
|
to interact with the kernel and HAL. It is primarily concerned with
|
the control and management of interrupts and the synchronization of
|
the control and management of interrupts and the synchronization of
|
ISRs, DSRs and threads.
|
ISRs, DSRs and threads.
|
|
|
|
|
|
|
The same API will be present in configurations where the kernel
|
The same API will be present in configurations where the kernel
|
is not present. In this case the functions will be supplied by code
|
is not present. In this case the functions will be supplied by code
|
acting directly on the HAL.
|
acting directly on the HAL.
|
|
|
|
|
|
|
|
|
|
|
|
|
Interrupt Model
|
Interrupt Model
|
|
|
|
|
eCos presents a three level interrupt model to
|
eCos presents a three level interrupt model to
|
device drivers. This consists of device drivers. This consists of Interrupt Service Routines (ISRs) that are invoked
|
-->Interrupt Service Routines (ISRs) that are invoked
|
in response to a hardware interrupt; Deferred
|
in response to a hardware interrupt; Deferred
|
Service Routines (DSRs) that are invoked in response to a request by
|
Service Routines (DSRs) that are invoked in response to a request by
|
an ISR; and threads that are the clients of the driver.
|
an ISR; and threads that are the clients of the driver.
|
|
|
|
|
Hardware interrupts are delivered with minimal intervention to an
|
Hardware interrupts are delivered with minimal intervention to an
|
ISR. The HAL decodes the hardware source of the interrupt and calls
|
ISR. The HAL decodes the hardware source of the interrupt and calls
|
the ISR of the attached interrupt object. This ISR may manipulate the
|
the ISR of the attached interrupt object. This ISR may manipulate the
|
hardware but is only allowed to make a restricted set of calls on the
|
hardware but is only allowed to make a restricted set of calls on the
|
driver API. When it returns, an ISR may request that its DSR should be
|
driver API. When it returns, an ISR may request that its DSR should be
|
scheduled to run.
|
scheduled to run.
|
|
|
|
|
|
|
A DSR will be run when it is safe to do so without interfering with
|
A DSR will be run when it is safe to do so without interfering with
|
the scheduler. Most of the time the DSR will run immediately after the
|
the scheduler. Most of the time the DSR will run immediately after the
|
ISR, but if the current thread is in the scheduler, it will be delayed
|
ISR, but if the current thread is in the scheduler, it will be delayed
|
until the thread is finished. A DSR is allowed to make a larger set of
|
until the thread is finished. A DSR is allowed to make a larger set of
|
driver API calls, including, in particular, being able to call
|
driver API calls, including, in particular, being able to call
|
cyg_drv_cond_signal() to wake up waiting
|
cyg_drv_cond_signal() to wake up waiting
|
threads.
|
threads.
|
|
|
|
|
|
|
Finally, threads are able to make all API calls and in particular are
|
Finally, threads are able to make all API calls and in particular are
|
allowed to wait on mutexes and condition variables.
|
allowed to wait on mutexes and condition variables.
|
|
|
|
|
|
|
For a device driver to receive interrupts it must first define ISR and
|
For a device driver to receive interrupts it must first define ISR and
|
DSR routines as shown below, and then call
|
DSR routines as shown below, and then call
|
cyg_drv_interrupt_create(). Using the handle
|
cyg_drv_interrupt_create(). Using the handle
|
returned, the driver must then call
|
returned, the driver must then call
|
cyg_drv_interrupt_attach() to actually attach the
|
cyg_drv_interrupt_attach() to actually attach the
|
interrupt to the hardware vector.
|
interrupt to the hardware vector.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Synchronization
|
Synchronization
|
|
|
There are three levels of synchronization supported:
|
There are three levels of synchronization supported:
|
|
|
|
|
|
|
|
|
Synchronization with ISRs. This normally means disabling
|
Synchronization with ISRs. This normally means disabling
|
interrupts to prevent the ISR running during a critical
|
interrupts to prevent the ISR running during a critical
|
section. In an SMP environment, this will also require the use of
|
section. In an SMP environment, this will also require the use of
|
a spinlock to synchronize with ISRs, DSRs or threads running on
|
a spinlock to synchronize with ISRs, DSRs or threads running on
|
other CPUs. This is implemented by the
|
other CPUs. This is implemented by the
|
cyg_drv_isr_lock() and
|
cyg_drv_isr_lock() and
|
cyg_drv_isr_unlock() functions. This
|
cyg_drv_isr_unlock() functions. This
|
mechanism should be used sparingly and for short periods only.
|
mechanism should be used sparingly and for short periods only.
|
For finer grained synchronization, individual spinlocks are also
|
For finer grained synchronization, individual spinlocks are also
|
supplied.
|
supplied.
|
|
|
|
|
|
|
|
|
|
|
Synchronization with DSRs. This will be implemented in the kernel
|
Synchronization with DSRs. This will be implemented in the kernel
|
by taking the scheduler lock to prevent DSRs running during
|
by taking the scheduler lock to prevent DSRs running during
|
critical sections. In non-kernel configurations it will be
|
critical sections. In non-kernel configurations it will be
|
implemented by non-kernel code. This is implemented by the
|
implemented by non-kernel code. This is implemented by the
|
cyg_drv_dsr_lock() and
|
cyg_drv_dsr_lock() and
|
cyg_drv_dsr_unlock() functions. As with ISR
|
cyg_drv_dsr_unlock() functions. As with ISR
|
synchronization, this mechanism should be used sparingly. Only
|
synchronization, this mechanism should be used sparingly. Only
|
DSRs and threads may use this synchronization mechanism, ISRs are
|
DSRs and threads may use this synchronization mechanism, ISRs are
|
not allowed to do this.
|
not allowed to do this.
|
|
|
|
|
|
|
|
|
Synchronization with threads. This is implemented with mutexes
|
Synchronization with threads. This is implemented with mutexes
|
and condition variables. Only threads may lock the mutexes and
|
and condition variables. Only threads may lock the mutexes and
|
wait on the condition variables, although DSRs may signal
|
wait on the condition variables, although DSRs may signal
|
condition variables.
|
condition variables.
|
|
|
|
|
|
|
|
|
|
|
Any data that is accessed from more than one level must be protected
|
Any data that is accessed from more than one level must be protected
|
against concurrent access. Data that is accessed by ISRs must be
|
against concurrent access. Data that is accessed by ISRs must be
|
protected with the ISR lock, or a spinlock at all times,
|
protected with the ISR lock, or a spinlock at all times,
|
even in ISRs. Data that is shared between DSRs
|
even in ISRs. Data that is shared between DSRs
|
and threads should be protected with the DSR lock. Data that is only
|
and threads should be protected with the DSR lock. Data that is only
|
accessed by threads must be protected with mutexes.
|
accessed by threads must be protected with mutexes.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SMP Support
|
SMP Support
|
|
|
|
|
Some eCos targets contain support for Symmetric Multi-Processing (SMP)
|
Some eCos targets contain support for Symmetric Multi-Processing (SMP)
|
configurations, where more than one CPU may be present. This option
|
configurations, where more than one CPU may be present. This option
|
has a number of ramifications for the way in which device drivers must
|
has a number of ramifications for the way in which device drivers must
|
be written if they are to be SMP-compatible.
|
be written if they are to be SMP-compatible.
|
|
|
|
|
|
|
Since it is possible for the ISR, DSR and thread components of a
|
Since it is possible for the ISR, DSR and thread components of a
|
device driver to execute on different CPUs, it is important that
|
device driver to execute on different CPUs, it is important that
|
SMP-compatible device drivers use the driver API routines correctly.
|
SMP-compatible device drivers use the driver API routines correctly.
|
|
|
|
|
|
|
Synchronization between threads and DSRs continues to require that the
|
Synchronization between threads and DSRs continues to require that the
|
thread-side code use cyg_drv_dsr_lock() and
|
thread-side code use cyg_drv_dsr_lock() and
|
cyg_drv_dsr_unlock() to protect access to shared
|
cyg_drv_dsr_unlock() to protect access to shared
|
data. While it is not strictly necessary for DSR code to claim the DSR
|
data. While it is not strictly necessary for DSR code to claim the DSR
|
lock, since DSRs are run with it claimed already, it is good practice
|
lock, since DSRs are run with it claimed already, it is good practice
|
to do so.
|
to do so.
|
|
|
|
|
|
|
Synchronization between ISRs and DSRs or threads requires that access
|
Synchronization between ISRs and DSRs or threads requires that access
|
to sensitive data be protected, in all places, by calls to
|
to sensitive data be protected, in all places, by calls to
|
cyg_drv_isr_lock() and
|
cyg_drv_isr_lock() and
|
cyg_drv_isr_unlock(). Disabling or masking
|
cyg_drv_isr_unlock(). Disabling or masking
|
interrupts is not adequate, since the thread or DSR may be running on
|
interrupts is not adequate, since the thread or DSR may be running on
|
a different CPU and interrupt enable/disable only work on the current
|
a different CPU and interrupt enable/disable only work on the current
|
CPU.
|
CPU.
|
|
|
|
|
|
|
The ISR lock, for SMP systems, not only disables local interrupts, but
|
The ISR lock, for SMP systems, not only disables local interrupts, but
|
also acquires a spinlock to protect against concurrent access from
|
also acquires a spinlock to protect against concurrent access from
|
other CPUs. This is necessary because ISRs are not run with the
|
other CPUs. This is necessary because ISRs are not run with the
|
scheduler lock claimed. Hence they can run in parallel with the other
|
scheduler lock claimed. Hence they can run in parallel with the other
|
components of the device driver.
|
components of the device driver.
|
|
|
|
|
|
|
The ISR lock provided by the driver API is just a shared spinlock that
|
The ISR lock provided by the driver API is just a shared spinlock that
|
is available for use by all drivers. If a driver needs to implement a
|
is available for use by all drivers. If a driver needs to implement a
|
finer grain of locking, it can use private spinlocks, accessed via the
|
finer grain of locking, it can use private spinlocks, accessed via the
|
cyg_drv_spinlock_*() functions.
|
cyg_drv_spinlock_*() functions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Device Driver Models
|
Device Driver Models
|
|
|
|
|
There are several ways in which device drivers
|
There are several ways in which device drivers
|
may be built. The exact model chosen will depend on the properties of
|
may be built. The exact model chosen will depend on the properties of
|
the device and the behavior desired. There are three basic models that
|
the device and the behavior desired. There are three basic models that
|
may be adopted.
|
may be adopted.
|
|
|
|
|
|
|
The first model is to do all device processing in the ISR. When it is
|
The first model is to do all device processing in the ISR. When it is
|
invoked the ISR programs the device hardware directly and accesses
|
invoked the ISR programs the device hardware directly and accesses
|
data to be transferred directly in memory. The ISR should also call
|
data to be transferred directly in memory. The ISR should also call
|
cyg_drv_interrupt_acknowledge(). When it is
|
cyg_drv_interrupt_acknowledge(). When it is
|
finished it may optionally request that its DSR be invoked. The DSR
|
finished it may optionally request that its DSR be invoked. The DSR
|
does nothing but call cyg_drv_cond_signal() to
|
does nothing but call cyg_drv_cond_signal() to
|
cause a thread to be woken up. Thread level code must call
|
cause a thread to be woken up. Thread level code must call
|
cyg_drv_isr_lock(), or
|
cyg_drv_isr_lock(), or
|
cyg_drv_interrupt_mask() to prevent ISRs running
|
cyg_drv_interrupt_mask() to prevent ISRs running
|
while it manipulates shared memory.
|
while it manipulates shared memory.
|
|
|
|
|
|
|
The second model is to defer device processing to the DSR. The ISR
|
The second model is to defer device processing to the DSR. The ISR
|
simply prevents further delivery of interrupts by either programming
|
simply prevents further delivery of interrupts by either programming
|
the device, or by calling
|
the device, or by calling
|
cyg_drv_interrupt_mask(). It must then call
|
cyg_drv_interrupt_mask(). It must then call
|
cyg_drv_interrupt_acknowledge() to allow other
|
cyg_drv_interrupt_acknowledge() to allow other
|
interrupts to be delivered and then request that its DSR be
|
interrupts to be delivered and then request that its DSR be
|
called. When the DSR runs it does the majority of the device handling,
|
called. When the DSR runs it does the majority of the device handling,
|
optionally signals a condition variable to wake a thread, and finishes
|
optionally signals a condition variable to wake a thread, and finishes
|
by calling cyg_drv_interrupt_unmask() to re-allow
|
by calling cyg_drv_interrupt_unmask() to re-allow
|
device interrupts. Thread level code uses
|
device interrupts. Thread level code uses
|
cyg_drv_dsr_lock() to prevent DSRs running while
|
cyg_drv_dsr_lock() to prevent DSRs running while
|
it manipulates shared memory. The eCos serial device drivers use this
|
it manipulates shared memory. The eCos serial device drivers use this
|
approach.
|
approach.
|
|
|
|
|
|
|
The third model is to defer device processing even further to a
|
The third model is to defer device processing even further to a
|
thread. The ISR behaves exactly as in the previous model and simply
|
thread. The ISR behaves exactly as in the previous model and simply
|
blocks and acknowledges the interrupt before request that the DSR
|
blocks and acknowledges the interrupt before request that the DSR
|
run. The DSR itself only calls
|
run. The DSR itself only calls
|
cyg_drv_cond_signal() to wake the thread. When
|
cyg_drv_cond_signal() to wake the thread. When
|
the thread awakens it performs all device processing, and has full
|
the thread awakens it performs all device processing, and has full
|
access to all kernel facilities while it does so. It should finish by
|
access to all kernel facilities while it does so. It should finish by
|
calling cyg_drv_interrupt_unmask() to re-allow
|
calling cyg_drv_interrupt_unmask() to re-allow
|
device interrupts. The eCos ethernet device drivers are written to
|
device interrupts. The eCos ethernet device drivers are written to
|
this model.
|
this model.
|
|
|
|
|
|
|
The first model is good for devices that need immediate processing and
|
The first model is good for devices that need immediate processing and
|
interact infrequently with thread level. The second model trades a
|
interact infrequently with thread level. The second model trades a
|
little latency in dealing with the device for a less intrusive
|
little latency in dealing with the device for a less intrusive
|
synchronization mechanism. The last model allows device processing to
|
synchronization mechanism. The last model allows device processing to
|
be scheduled with other threads and permits more complex device
|
be scheduled with other threads and permits more complex device
|
handling.
|
handling.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Synchronization Levels
|
Synchronization Levels
|
|
|
|
|
Since it would be dangerous for an ISR or DSR to make a call
|
Since it would be dangerous for an ISR or DSR to make a call
|
that might reschedule the current thread (by trying to lock a mutex
|
that might reschedule the current thread (by trying to lock a mutex
|
for example) all functions in this API have an associated synchronization
|
for example) all functions in this API have an associated synchronization
|
level. These levels are:
|
level. These levels are:
|
|
|
|
|
|
|
|
|
Thread
|
Thread
|
|
|
|
|
This function may only be called from within threads. This is
|
This function may only be called from within threads. This is
|
usually the client code that makes calls into the device driver.
|
usually the client code that makes calls into the device driver.
|
In a non-kernel configuration, this will be code running at the
|
In a non-kernel configuration, this will be code running at the
|
default non-interrupt level.
|
default non-interrupt level.
|
|
|
|
|
|
|
|
|
|
|
DSR
|
DSR
|
|
|
|
|
This function may be called by either DSR or thread code.
|
This function may be called by either DSR or thread code.
|
|
|
|
|
|
|
|
|
|
|
ISR
|
ISR
|
|
|
|
|
This function may be called from ISR, DSR or thread code.
|
This function may be called from ISR, DSR or thread code.
|
|
|
|
|
|
|
|
|
|
|
|
|
The following table shows, for each API function, the levels
|
The following table shows, for each API function, the levels
|
at which is may be called:
|
at which is may be called:
|
|
|
|
|
|
|
Callable from:
|
Callable from:
|
Function ISR DSR Thread
|
Function ISR DSR Thread
|
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
|
|
cyg_drv_isr_lock X X X
|
cyg_drv_isr_lock X X X
|
cyg_drv_isr_unlock X X X
|
cyg_drv_isr_unlock X X X
|
cyg_drv_spinlock_init X
|
cyg_drv_spinlock_init X
|
cyg_drv_spinlock_destroy X
|
cyg_drv_spinlock_destroy X
|
cyg_drv_spinlock_spin X X X
|
cyg_drv_spinlock_spin X X X
|
cyg_drv_spinlock_clear X X X
|
cyg_drv_spinlock_clear X X X
|
cyg_drv_spinlock_try X X X
|
cyg_drv_spinlock_try X X X
|
cyg_drv_spinlock_test X X X
|
cyg_drv_spinlock_test X X X
|
cyg_drv_spinlock_spin_intsave X X X
|
cyg_drv_spinlock_spin_intsave X X X
|
cyg_drv_spinlock_clear_intsave X X X
|
cyg_drv_spinlock_clear_intsave X X X
|
cyg_drv_dsr_lock X X
|
cyg_drv_dsr_lock X X
|
cyg_drv_dsr_unlock X X
|
cyg_drv_dsr_unlock X X
|
cyg_drv_mutex_init X
|
cyg_drv_mutex_init X
|
cyg_drv_mutex_destroy X
|
cyg_drv_mutex_destroy X
|
cyg_drv_mutex_lock X
|
cyg_drv_mutex_lock X
|
cyg_drv_mutex_trylock X
|
cyg_drv_mutex_trylock X
|
cyg_drv_mutex_unlock X
|
cyg_drv_mutex_unlock X
|
cyg_drv_mutex_release X
|
cyg_drv_mutex_release X
|
cyg_drv_cond_init X
|
cyg_drv_cond_init X
|
cyg_drv_cond_destroy X
|
cyg_drv_cond_destroy X
|
cyg_drv_cond_wait X
|
cyg_drv_cond_wait X
|
cyg_drv_cond_signal X X
|
cyg_drv_cond_signal X X
|
cyg_drv_cond_broadcast X X
|
cyg_drv_cond_broadcast X X
|
cyg_drv_interrupt_create X
|
cyg_drv_interrupt_create X
|
cyg_drv_interrupt_delete X
|
cyg_drv_interrupt_delete X
|
cyg_drv_interrupt_attach X X X
|
cyg_drv_interrupt_attach X X X
|
cyg_drv_interrupt_detach X X X
|
cyg_drv_interrupt_detach X X X
|
cyg_drv_interrupt_mask X X X
|
cyg_drv_interrupt_mask X X X
|
cyg_drv_interrupt_unmask X X X
|
cyg_drv_interrupt_unmask X X X
|
cyg_drv_interrupt_acknowledge X X X
|
cyg_drv_interrupt_acknowledge X X X
|
cyg_drv_interrupt_configure X X X
|
cyg_drv_interrupt_configure X X X
|
cyg_drv_interrupt_level X X X
|
cyg_drv_interrupt_level X X X
|
cyg_drv_interrupt_set_cpu X X X
|
cyg_drv_interrupt_set_cpu X X X
|
cyg_drv_interrupt_get_cpu X X X
|
cyg_drv_interrupt_get_cpu X X X
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The API
|
The API
|
|
|
|
|
This section details the Driver Kernel
|
This section details the Driver Kernel
|
Interface. Note that most of these functions are identical to Kernel C
|
Interface. Note that most of these functions are identical to Kernel C
|
API calls, and will in most configurations be wrappers for them. In
|
API calls, and will in most configurations be wrappers for them. In
|
non-kernel configurations they will be supported directly by the HAL,
|
non-kernel configurations they will be supported directly by the HAL,
|
or by code to emulate the required behavior.
|
or by code to emulate the required behavior.
|
|
|
|
|
This API is defined in the header file
|
This API is defined in the header file
|
<cyg/hal/drv_api.h>.
|
<cyg/hal/drv_api.h>.
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_isr_lock
|
cyg_drv_isr_lock
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_isr_lock()
|
void cyg_drv_isr_lock()
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
None
|
None
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
Disables delivery of interrupts, preventing all ISRs running. This
|
Disables delivery of interrupts, preventing all ISRs running. This
|
function maintains a counter of the number of times it is
|
function maintains a counter of the number of times it is
|
called.
|
called.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_isr_unlock
|
cyg_drv_isr_unlock
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_isr_unlock()
|
void cyg_drv_isr_unlock()
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
None
|
None
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Re-enables delivery of interrupts, allowing ISRs to
|
Re-enables delivery of interrupts, allowing ISRs to
|
run. This function decrements the counter maintained by
|
run. This function decrements the counter maintained by
|
cyg_drv_isr_lock(), and only re-allows
|
cyg_drv_isr_lock(), and only re-allows
|
interrupts when it goes to zero.
|
interrupts when it goes to zero.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_spinlock_init
|
cyg_drv_spinlock_init
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
void cyg_drv_spinlock_init(cyg_spinlock_t *lock, cyg_bool_t locked )
|
void cyg_drv_spinlock_init(cyg_spinlock_t *lock, cyg_bool_t locked )
|
|
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
lock - pointer to spinlock to initialize
|
lock - pointer to spinlock to initialize
|
locked - initial state of lock
|
locked - initial state of lock
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
Initialize a spinlock. The locked
|
Initialize a spinlock. The locked
|
argument indicates how the spinlock should be initialized:
|
argument indicates how the spinlock should be initialized:
|
TRUE for locked or FALSE
|
TRUE for locked or FALSE
|
for unlocked state.
|
for unlocked state.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_spinlock_destroy
|
cyg_drv_spinlock_destroy
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_spinlock_destroy(cyg_spinlock_t *lock )
|
void cyg_drv_spinlock_destroy(cyg_spinlock_t *lock )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
lock - pointer to spinlock destroy
|
lock - pointer to spinlock destroy
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
Destroy a spinlock that is no longer of use. There should be no
|
Destroy a spinlock that is no longer of use. There should be no
|
CPUs attempting to claim the lock at the time this function is
|
CPUs attempting to claim the lock at the time this function is
|
called, otherwise the behavior is undefined.
|
called, otherwise the behavior is undefined.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_spinlock_spin
|
cyg_drv_spinlock_spin
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_spinlock_spin(cyg_spinlock_t *lock )
|
void cyg_drv_spinlock_spin(cyg_spinlock_t *lock )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
lock - pointer to spinlock to claim
|
lock - pointer to spinlock to claim
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
Claim a spinlock, waiting in a busy loop until it is
|
Claim a spinlock, waiting in a busy loop until it is
|
available. Wherever this is called from, this operation
|
available. Wherever this is called from, this operation
|
effectively pauses the CPU until it succeeds. This operations
|
effectively pauses the CPU until it succeeds. This operations
|
should therefore be used sparingly, and in situations where
|
should therefore be used sparingly, and in situations where
|
deadlocks/livelocks cannot occur. Also see
|
deadlocks/livelocks cannot occur. Also see
|
cyg_drv_spinlock_spin_intsave().
|
cyg_drv_spinlock_spin_intsave().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_spinlock_clear
|
cyg_drv_spinlock_clear
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_spinlock_clear(cyg_spinlock_t *lock )
|
void cyg_drv_spinlock_clear(cyg_spinlock_t *lock )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
lock - pointer to spinlock to clear
|
lock - pointer to spinlock to clear
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
Clear a spinlock. This clears the spinlock and allows another
|
Clear a spinlock. This clears the spinlock and allows another
|
CPU to claim it. If there is more than one CPU waiting in
|
CPU to claim it. If there is more than one CPU waiting in
|
cyg_drv_spinlock_spin() then just one of
|
cyg_drv_spinlock_spin() then just one of
|
them will be allowed to proceed.
|
them will be allowed to proceed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_spinlock_try
|
cyg_drv_spinlock_try
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
cyg_bool_t cyg_drv_spinlock_try(cyg_spinlock_t *lock )
|
cyg_bool_t cyg_drv_spinlock_try(cyg_spinlock_t *lock )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
lock - pointer to spinlock to try
|
lock - pointer to spinlock to try
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
TRUE if the spinlock was claimed,
|
TRUE if the spinlock was claimed,
|
FALSE otherwise.
|
FALSE otherwise.
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
Try to claim the spinlock without waiting. If the spinlock could
|
Try to claim the spinlock without waiting. If the spinlock could
|
be claimed immediately then TRUE is
|
be claimed immediately then TRUE is
|
returned. If the spinlock is already claimed then the result is
|
returned. If the spinlock is already claimed then the result is
|
FALSE.
|
FALSE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_spinlock_test
|
cyg_drv_spinlock_test
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
cyg_bool_t cyg_drv_spinlock_test(cyg_spinlock_t *lock )
|
cyg_bool_t cyg_drv_spinlock_test(cyg_spinlock_t *lock )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
lock - pointer to spinlock to test
|
lock - pointer to spinlock to test
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
TRUE if the spinlock is available,
|
TRUE if the spinlock is available,
|
FALSE otherwise.
|
FALSE otherwise.
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
Inspect the state of the spinlock. If the spinlock is not locked
|
Inspect the state of the spinlock. If the spinlock is not locked
|
then the result is TRUE. If it is locked then
|
then the result is TRUE. If it is locked then
|
the result will be FALSE.
|
the result will be FALSE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_spinlock_spin_intsave
|
cyg_drv_spinlock_spin_intsave
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
void cyg_drv_spinlock_spin_intsave(cyg_spinlock_t *lock,
|
void cyg_drv_spinlock_spin_intsave(cyg_spinlock_t *lock,
|
cyg_addrword_t *istate )
|
cyg_addrword_t *istate )
|
|
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
lock - pointer to spinlock to claim
|
lock - pointer to spinlock to claim
|
istate - pointer to interrupt state save location
|
istate - pointer to interrupt state save location
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
This function behaves exactly like
|
This function behaves exactly like
|
cyg_drv_spinlock_spin() except that it also
|
cyg_drv_spinlock_spin() except that it also
|
disables interrupts before attempting to claim the lock. The
|
disables interrupts before attempting to claim the lock. The
|
current interrupt enable state is saved in
|
current interrupt enable state is saved in
|
*istate. Interrupts remain disabled once
|
*istate. Interrupts remain disabled once
|
the spinlock had been claimed and must be restored by calling
|
the spinlock had been claimed and must be restored by calling
|
cyg_drv_spinlock_clear_intsave().
|
cyg_drv_spinlock_clear_intsave().
|
|
|
|
|
In general, device drivers should use this function to claim and
|
In general, device drivers should use this function to claim and
|
release spinlocks rather than the
|
release spinlocks rather than the
|
non-_intsave() variants, to ensure proper
|
non-_intsave() variants, to ensure proper
|
exclusion with code running on both other CPUs and this CPU.
|
exclusion with code running on both other CPUs and this CPU.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_spinlock_clear_intsave
|
cyg_drv_spinlock_clear_intsave
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
void cyg_drv_spinlock_clear_intsave( cyg_spinlock_t *lock,
|
void cyg_drv_spinlock_clear_intsave( cyg_spinlock_t *lock,
|
cyg_addrword_t istate )
|
cyg_addrword_t istate )
|
|
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
lock - pointer to spinlock to clear
|
lock - pointer to spinlock to clear
|
istate - interrupt state to restore
|
istate - interrupt state to restore
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
This function behaves exactly like
|
This function behaves exactly like
|
cyg_drv_spinlock_clear() except that it
|
cyg_drv_spinlock_clear() except that it
|
also restores an interrupt state saved by
|
also restores an interrupt state saved by
|
cyg_drv_spinlock_spin_intsave(). The
|
cyg_drv_spinlock_spin_intsave(). The
|
istate argument must have been
|
istate argument must have been
|
initialized by a previous call to
|
initialized by a previous call to
|
cyg_drv_spinlock_spin_intsave().
|
cyg_drv_spinlock_spin_intsave().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_dsr_lock
|
cyg_drv_dsr_lock
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_dsr_lock()
|
void cyg_drv_dsr_lock()
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
None
|
None
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
DSR
|
DSR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Disables scheduling of DSRs. This function maintains a
|
Disables scheduling of DSRs. This function maintains a
|
counter of the number of times it has been called.
|
counter of the number of times it has been called.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_dsr_unlock
|
cyg_drv_dsr_unlock
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_dsr_unlock()
|
void cyg_drv_dsr_unlock()
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
None
|
None
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
DSR
|
DSR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Re-enables scheduling of DSRs. This function decrements
|
Re-enables scheduling of DSRs. This function decrements
|
the counter incremented by
|
the counter incremented by
|
cyg_drv_dsr_lock(). DSRs are only allowed
|
cyg_drv_dsr_lock(). DSRs are only allowed
|
to be delivered when the counter goes to zero.
|
to be delivered when the counter goes to zero.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_mutex_init
|
cyg_drv_mutex_init
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_mutex_init(cyg_drv_mutex *mutex)
|
void cyg_drv_mutex_init(cyg_drv_mutex *mutex)
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
mutex - pointer to mutex to initialize
|
mutex - pointer to mutex to initialize
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Initialize the mutex pointed to by the
|
Initialize the mutex pointed to by the
|
mutex argument.
|
mutex argument.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_mutex_destroy
|
cyg_drv_mutex_destroy
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_mutex_destroy( cyg_drv_mutex *mutex )
|
void cyg_drv_mutex_destroy( cyg_drv_mutex *mutex )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
mutex - pointer to mutex to destroy
|
mutex - pointer to mutex to destroy
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Destroy the mutex pointed to by the
|
Destroy the mutex pointed to by the
|
mutex argument. The mutex should be unlocked
|
mutex argument. The mutex should be unlocked
|
and there should be no threads waiting to lock it when this call
|
and there should be no threads waiting to lock it when this call
|
in made.
|
in made.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_mutex_lock
|
cyg_drv_mutex_lock
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
cyg_bool cyg_drv_mutex_lock( cyg_drv_mutex *mutex )
|
cyg_bool cyg_drv_mutex_lock( cyg_drv_mutex *mutex )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
mutex - pointer to mutex to lock
|
mutex - pointer to mutex to lock
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
TRUE it the thread has claimed the
|
TRUE it the thread has claimed the
|
lock, FALSE otherwise.
|
lock, FALSE otherwise.
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Attempt to lock the mutex pointed to by the
|
Attempt to lock the mutex pointed to by the
|
mutex argument. If the mutex is already
|
mutex argument. If the mutex is already
|
locked by another thread then this thread will wait until that
|
locked by another thread then this thread will wait until that
|
thread is finished. If the result from this function is
|
thread is finished. If the result from this function is
|
FALSE then the thread was broken out of its
|
FALSE then the thread was broken out of its
|
wait by some other thread. In this case the mutex will not have
|
wait by some other thread. In this case the mutex will not have
|
been locked.
|
been locked.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_mutex_trylock
|
cyg_drv_mutex_trylock
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
cyg_bool cyg_drv_mutex_trylock( cyg_drv_mutex *mutex )
|
cyg_bool cyg_drv_mutex_trylock( cyg_drv_mutex *mutex )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
mutex - pointer to mutex to lock
|
mutex - pointer to mutex to lock
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
TRUE if the mutex has been locked,
|
TRUE if the mutex has been locked,
|
FALSE otherwise.
|
FALSE otherwise.
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Attempt to lock the mutex pointed to by the
|
Attempt to lock the mutex pointed to by the
|
mutex argument without waiting. If the
|
mutex argument without waiting. If the
|
mutex is already locked by some other thread then this function
|
mutex is already locked by some other thread then this function
|
returns FALSE. If the function can lock the
|
returns FALSE. If the function can lock the
|
mutex without waiting, then TRUE is
|
mutex without waiting, then TRUE is
|
returned.
|
returned.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_mutex_unlock
|
cyg_drv_mutex_unlock
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_mutex_unlock( cyg_drv_mutex *mutex )
|
void cyg_drv_mutex_unlock( cyg_drv_mutex *mutex )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
mutex - pointer to mutex to unlock
|
mutex - pointer to mutex to unlock
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Unlock the mutex pointed to by the
|
Unlock the mutex pointed to by the
|
mutex argument. If there are any threads
|
mutex argument. If there are any threads
|
waiting to claim the lock, one of them is woken up to try and
|
waiting to claim the lock, one of them is woken up to try and
|
claim it.
|
claim it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_mutex_release
|
cyg_drv_mutex_release
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_mutex_release( cyg_drv_mutex *mutex )
|
void cyg_drv_mutex_release( cyg_drv_mutex *mutex )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
mutex - pointer to mutex to release
|
mutex - pointer to mutex to release
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Release all threads waiting on the mutex pointed to by the
|
Release all threads waiting on the mutex pointed to by the
|
mutex argument. These threads will return
|
mutex argument. These threads will return
|
from cyg_drv_mutex_lock() with a
|
from cyg_drv_mutex_lock() with a
|
FALSE result and will not have claimed the
|
FALSE result and will not have claimed the
|
mutex. This function has no effect on any thread that may have
|
mutex. This function has no effect on any thread that may have
|
the mutex claimed.
|
the mutex claimed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_cond_init
|
cyg_drv_cond_init
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_cond_init( cyg_drv_cond *cond, cyg_drv_mutex *mutex )
|
void cyg_drv_cond_init( cyg_drv_cond *cond, cyg_drv_mutex *mutex )
|
|
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
cond - condition variable to initialize
|
cond - condition variable to initialize
|
mutex - mutex to associate with this condition variable
|
mutex - mutex to associate with this condition variable
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Initialize the condition variable pointed to by the
|
Initialize the condition variable pointed to by the
|
cond argument. The
|
cond argument. The
|
mutex argument must point to a mutex with
|
mutex argument must point to a mutex with
|
which this condition variable is associated. A thread may only
|
which this condition variable is associated. A thread may only
|
wait on this condition variable when it has already locked the
|
wait on this condition variable when it has already locked the
|
associated mutex. Waiting will cause the mutex to be unlocked,
|
associated mutex. Waiting will cause the mutex to be unlocked,
|
and when the thread is reawakened, it will automatically claim
|
and when the thread is reawakened, it will automatically claim
|
the mutex before continuing.
|
the mutex before continuing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_cond_destroy
|
cyg_drv_cond_destroy
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_cond_destroy( cyg_drv_cond *cond )
|
void cyg_drv_cond_destroy( cyg_drv_cond *cond )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
cond - condition variable to destroy
|
cond - condition variable to destroy
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Destroy the condition variable pointed to by the
|
Destroy the condition variable pointed to by the
|
cond argument.
|
cond argument.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_cond_wait
|
cyg_drv_cond_wait
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_cond_wait( cyg_drv_cond *cond )
|
void cyg_drv_cond_wait( cyg_drv_cond *cond )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
cond - condition variable to wait on
|
cond - condition variable to wait on
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Wait for a signal on the condition variable pointed to by
|
Wait for a signal on the condition variable pointed to by
|
the cond argument. The thread must have
|
the cond argument. The thread must have
|
locked the associated mutex, supplied in
|
locked the associated mutex, supplied in
|
cyg_drv_cond_init(), before waiting on this
|
cyg_drv_cond_init(), before waiting on this
|
condition variable. While the thread waits, the mutex will be
|
condition variable. While the thread waits, the mutex will be
|
unlocked, and will be re-locked before this function returns. It
|
unlocked, and will be re-locked before this function returns. It
|
is possible for threads waiting on a condition variable to
|
is possible for threads waiting on a condition variable to
|
occasionally wake up spuriously. For this reason it is necessary
|
occasionally wake up spuriously. For this reason it is necessary
|
to use this function in a loop that re-tests the condition each
|
to use this function in a loop that re-tests the condition each
|
time it returns. Note that this function performs an implicit
|
time it returns. Note that this function performs an implicit
|
scheduler unlock/relock sequence, so that it may be used within
|
scheduler unlock/relock sequence, so that it may be used within
|
an explicit
|
an explicit
|
cyg_drv_dsr_lock()...cyg_drv_dsr_unlock()
|
cyg_drv_dsr_lock()...cyg_drv_dsr_unlock()
|
structure.
|
structure.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_cond_signal
|
cyg_drv_cond_signal
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_cond_signal( cyg_drv_cond *cond )
|
void cyg_drv_cond_signal( cyg_drv_cond *cond )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
cond - condition variable to signal
|
cond - condition variable to signal
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
DSR
|
DSR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Signal the condition variable pointed to by the cond
|
Signal the condition variable pointed to by the cond
|
argument. If there are any threads waiting on this variable at
|
argument. If there are any threads waiting on this variable at
|
least one of them will be awakened. Note that in some
|
least one of them will be awakened. Note that in some
|
configurations there may not be any difference between this
|
configurations there may not be any difference between this
|
function and cyg_drv_cond_broadcast().
|
function and cyg_drv_cond_broadcast().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_cond_broadcast
|
cyg_drv_cond_broadcast
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_cond_broadcast( cyg_drv_cond *cond )
|
void cyg_drv_cond_broadcast( cyg_drv_cond *cond )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
cond - condition variable to broadcast to
|
cond - condition variable to broadcast to
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
DSR
|
DSR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Signal the condition variable pointed to by the
|
Signal the condition variable pointed to by the
|
cond argument. If there are any threads
|
cond argument. If there are any threads
|
waiting on this variable they will all be awakened.
|
waiting on this variable they will all be awakened.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_create
|
cyg_drv_interrupt_create
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
void cyg_drv_interrupt_create( cyg_vector_t vector,
|
void cyg_drv_interrupt_create( cyg_vector_t vector,
|
cyg_priority_t priority,
|
cyg_priority_t priority,
|
cyg_addrword_t data,
|
cyg_addrword_t data,
|
cyg_ISR_t *isr,
|
cyg_ISR_t *isr,
|
cyg_DSR_t *dsr,
|
cyg_DSR_t *dsr,
|
cyg_handle_t *handle,
|
cyg_handle_t *handle,
|
cyg_interrupt *intr
|
cyg_interrupt *intr
|
)
|
)
|
|
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - vector to attach to
|
vector - vector to attach to
|
priority - queuing priority
|
priority - queuing priority
|
data - data pointer
|
data - data pointer
|
isr - interrupt service routine
|
isr - interrupt service routine
|
dsr - deferred service routine
|
dsr - deferred service routine
|
handle - returned handle
|
handle - returned handle
|
intr - put interrupt object here
|
intr - put interrupt object here
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Create an interrupt object and returns a handle to it. The
|
Create an interrupt object and returns a handle to it. The
|
object contains information about which interrupt vector to use
|
object contains information about which interrupt vector to use
|
and the ISR and DSR that will be called after the interrupt
|
and the ISR and DSR that will be called after the interrupt
|
object is attached to the vector. The interrupt object will be
|
object is attached to the vector. The interrupt object will be
|
allocated in the memory passed in the
|
allocated in the memory passed in the
|
intr parameter. The interrupt object is
|
intr parameter. The interrupt object is
|
not immediately attached; it must be attached with the
|
not immediately attached; it must be attached with the
|
cyg_interrupt_attach() call.
|
cyg_interrupt_attach() call.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_delete
|
cyg_drv_interrupt_delete
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_interrupt_delete( cyg_handle_t interrupt )
|
void cyg_drv_interrupt_delete( cyg_handle_t interrupt )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
interrupt - interrupt to delete
|
interrupt - interrupt to delete
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
Thread
|
Thread
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Detach the interrupt from the vector and free the memory
|
Detach the interrupt from the vector and free the memory
|
passed in the intr argument to
|
passed in the intr argument to
|
cyg_drv_interrupt_create() for
|
cyg_drv_interrupt_create() for
|
reuse.
|
reuse.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_attach
|
cyg_drv_interrupt_attach
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_interrupt_attach( cyg_handle_t interrupt )
|
void cyg_drv_interrupt_attach( cyg_handle_t interrupt )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
interrupt - interrupt to attach
|
interrupt - interrupt to attach
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Attach the interrupt to the vector so that interrupts will
|
Attach the interrupt to the vector so that interrupts will
|
be delivered to the ISR when the interrupt occurs.
|
be delivered to the ISR when the interrupt occurs.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_detach
|
cyg_drv_interrupt_detach
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_interrupt_detach( cyg_handle_t interrupt )
|
void cyg_drv_interrupt_detach( cyg_handle_t interrupt )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
interrupt - interrupt to detach
|
interrupt - interrupt to detach
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Detach the interrupt from the vector so that interrupts
|
Detach the interrupt from the vector so that interrupts
|
will no longer be delivered to the ISR.
|
will no longer be delivered to the ISR.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_mask
|
cyg_drv_interrupt_mask
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_interrupt_mask(cyg_vector_t vector )
|
void cyg_drv_interrupt_mask(cyg_vector_t vector )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - vector to mask
|
vector - vector to mask
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Program the interrupt controller to stop delivery of
|
Program the interrupt controller to stop delivery of
|
interrupts on the given vector. On architectures which implement
|
interrupts on the given vector. On architectures which implement
|
interrupt priority levels this may also disable all lower
|
interrupt priority levels this may also disable all lower
|
priority interrupts.
|
priority interrupts.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_mask_intunsafe
|
cyg_drv_interrupt_mask_intunsafe
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_interrupt_mask_intunsafe(cyg_vector_t vector )
|
void cyg_drv_interrupt_mask_intunsafe(cyg_vector_t vector )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - vector to mask
|
vector - vector to mask
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Program the interrupt controller to stop delivery of
|
Program the interrupt controller to stop delivery of
|
interrupts on the given vector. On architectures which implement
|
interrupts on the given vector. On architectures which implement
|
interrupt priority levels this may also disable all lower
|
interrupt priority levels this may also disable all lower
|
priority interrupts. This version differs from
|
priority interrupts. This version differs from
|
cyg_drv_interrupt_mask() in not being
|
cyg_drv_interrupt_mask() in not being
|
interrupt safe. So in situations where, for example, interrupts
|
interrupt safe. So in situations where, for example, interrupts
|
are already known to be disabled, this may be called to avoid
|
are already known to be disabled, this may be called to avoid
|
the extra overhead.
|
the extra overhead.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_unmask
|
cyg_drv_interrupt_unmask
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_interrupt_unmask(cyg_vector_t vector )
|
void cyg_drv_interrupt_unmask(cyg_vector_t vector )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - vector to unmask
|
vector - vector to unmask
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Program the interrupt controller to re-allow delivery of
|
Program the interrupt controller to re-allow delivery of
|
interrupts on the given vector.
|
interrupts on the given vector.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_unmask_intunsafe
|
cyg_drv_interrupt_unmask_intunsafe
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_interrupt_unmask_intunsafe(cyg_vector_t vector )
|
void cyg_drv_interrupt_unmask_intunsafe(cyg_vector_t vector )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - vector to unmask
|
vector - vector to unmask
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Program the interrupt controller to re-allow delivery of
|
Program the interrupt controller to re-allow delivery of
|
interrupts on the given vector. This
|
interrupts on the given vector. This
|
version differs from
|
version differs from
|
cyg_drv_interrupt_unmask() in not being
|
cyg_drv_interrupt_unmask() in not being
|
interrupt safe.
|
interrupt safe.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_acknowledge
|
cyg_drv_interrupt_acknowledge
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
void cyg_drv_interrupt_acknowledge( cyg_vector_t vector )
|
void cyg_drv_interrupt_acknowledge( cyg_vector_t vector )
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - vector to acknowledge
|
vector - vector to acknowledge
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Perform any processing required at the interrupt
|
Perform any processing required at the interrupt
|
controller and in the CPU to cancel the current interrupt
|
controller and in the CPU to cancel the current interrupt
|
request on the vector. An ISR may also
|
request on the vector. An ISR may also
|
need to program the hardware of the device to prevent an
|
need to program the hardware of the device to prevent an
|
immediate re-triggering of the interrupt.
|
immediate re-triggering of the interrupt.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_configure
|
cyg_drv_interrupt_configure
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
void cyg_drv_interrupt_configure( cyg_vector_t vector,
|
void cyg_drv_interrupt_configure( cyg_vector_t vector,
|
cyg_bool_t level,
|
cyg_bool_t level,
|
cyg_bool_t up
|
cyg_bool_t up
|
)
|
)
|
|
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - vector to configure
|
vector - vector to configure
|
level - level or edge triggered
|
level - level or edge triggered
|
up - rising/falling edge, high/low level
|
up - rising/falling edge, high/low level
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Program the interrupt controller with the characteristics
|
Program the interrupt controller with the characteristics
|
of the interrupt source. The level
|
of the interrupt source. The level
|
argument chooses between level- or edge-triggered
|
argument chooses between level- or edge-triggered
|
interrupts. The up argument chooses
|
interrupts. The up argument chooses
|
between high and low level for level triggered interrupts or
|
between high and low level for level triggered interrupts or
|
rising and falling edges for edge triggered interrupts. This
|
rising and falling edges for edge triggered interrupts. This
|
function only works with interrupt controllers that can control
|
function only works with interrupt controllers that can control
|
these parameters.
|
these parameters.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_level
|
cyg_drv_interrupt_level
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
void cyg_drv_interrupt_level( cyg_vector_t vector,
|
void cyg_drv_interrupt_level( cyg_vector_t vector,
|
cyg_priority_t level
|
cyg_priority_t level
|
)
|
)
|
|
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - vector to configure
|
vector - vector to configure
|
level - level to set
|
level - level to set
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Program the interrupt controller to deliver the given
|
Program the interrupt controller to deliver the given
|
interrupt at the supplied priority level. This function only
|
interrupt at the supplied priority level. This function only
|
works with interrupt controllers that can control this
|
works with interrupt controllers that can control this
|
parameter.
|
parameter.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_set_cpu
|
cyg_drv_interrupt_set_cpu
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
void cyg_drv_interrupt_set_cpu( cyg_vector_t vector,
|
void cyg_drv_interrupt_set_cpu( cyg_vector_t vector,
|
cyg_cpu_t cpu
|
cyg_cpu_t cpu
|
)
|
)
|
|
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - interrupt vector to route
|
vector - interrupt vector to route
|
cpu - destination CPU
|
cpu - destination CPU
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
This function causes all interrupts on the given vector to be
|
This function causes all interrupts on the given vector to be
|
routed to the specified CPU. Subsequently, all such interrupts
|
routed to the specified CPU. Subsequently, all such interrupts
|
will be handled by that CPU. This only works if the underlying
|
will be handled by that CPU. This only works if the underlying
|
hardware is capable of performing this kind of routing. This
|
hardware is capable of performing this kind of routing. This
|
function does nothing on a single CPU system.
|
function does nothing on a single CPU system.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_drv_interrupt_get_cpu
|
cyg_drv_interrupt_get_cpu
|
|
|
|
|
|
|
Function:
|
Function:
|
|
|
|
|
cyg_cpu_t cyg_drv_interrupt_set_cpu( cyg_vector_t vector )
|
cyg_cpu_t cyg_drv_interrupt_set_cpu( cyg_vector_t vector )
|
|
|
|
|
|
|
|
|
Arguments:
|
Arguments:
|
|
|
vector - interrupt vector to query
|
vector - interrupt vector to query
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
The CPU to which this vector is routed
|
The CPU to which this vector is routed
|
|
|
|
|
|
|
Level:
|
Level:
|
|
|
ISR
|
ISR
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
|
|
In multi-processor systems this function returns the id of the
|
In multi-processor systems this function returns the id of the
|
CPU to which interrupts on the given vector are current being
|
CPU to which interrupts on the given vector are current being
|
delivered. In single CPU systems this function returns zero.
|
delivered. In single CPU systems this function returns zero.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_ISR_t
|
cyg_ISR_t
|
|
|
|
|
|
|
Type:
|
Type:
|
|
|
|
|
typedef cyg_uint32 cyg_ISR_t( cyg_vector_t vector,
|
typedef cyg_uint32 cyg_ISR_t( cyg_vector_t vector,
|
cyg_addrword_t data
|
cyg_addrword_t data
|
)
|
)
|
|
|
|
|
|
|
|
|
Fields:
|
Fields:
|
|
|
vector - vector being delivered
|
vector - vector being delivered
|
data - data value supplied by client
|
data - data value supplied by client
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
Bit mask indicating whether interrupt was handled and
|
Bit mask indicating whether interrupt was handled and
|
whether the DSR should be called.
|
whether the DSR should be called.
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Interrupt Service Routine definition. A pointer to a
|
Interrupt Service Routine definition. A pointer to a
|
function with this prototype is passed to
|
function with this prototype is passed to
|
cyg_interrupt_create() when an interrupt
|
cyg_interrupt_create() when an interrupt
|
object is created. When an interrupt is delivered the function
|
object is created. When an interrupt is delivered the function
|
will be called with the vector number and the data value that
|
will be called with the vector number and the data value that
|
was passed to cyg_interrupt_create().
|
was passed to cyg_interrupt_create().
|
|
|
The return value is a bit mask containing one or both of the
|
The return value is a bit mask containing one or both of the
|
following bits:
|
following bits:
|
|
|
|
|
CYG_ISR_HANDLED
|
CYG_ISR_HANDLED
|
|
|
indicates that the interrupt was handled by this
|
indicates that the interrupt was handled by this
|
ISR. It is a configuration option whether this will
|
ISR. It is a configuration option whether this will
|
prevent further ISR being run.
|
prevent further ISR being run.
|
|
|
|
|
|
|
CYG_ISR_CALL_DSR
|
CYG_ISR_CALL_DSR
|
|
|
causes the DSR that was passed to
|
causes the DSR that was passed to
|
cyg_interrupt_create() to be
|
cyg_interrupt_create() to be
|
scheduled to be called.
|
scheduled to be called.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cyg_DSR_t
|
cyg_DSR_t
|
|
|
|
|
|
|
Type:
|
Type:
|
|
|
|
|
typedef void cyg_DSR_t( cyg_vector_t vector,
|
typedef void cyg_DSR_t( cyg_vector_t vector,
|
cyg_ucount32 count,
|
cyg_ucount32 count,
|
cyg_addrword_t data
|
cyg_addrword_t data
|
)
|
)
|
|
|
|
|
|
|
|
|
Fields:
|
Fields:
|
|
|
vector - vector being delivered
|
vector - vector being delivered
|
count - number of times DSR has been scheduled
|
count - number of times DSR has been scheduled
|
data - data value supplied by client
|
data - data value supplied by client
|
|
|
|
|
|
|
Result:
|
Result:
|
|
|
None
|
None
|
|
|
|
|
|
|
Description:
|
Description:
|
|
|
Deferred Service Routine prototype. A pointer to a
|
Deferred Service Routine prototype. A pointer to a
|
function with this prototype is passed to
|
function with this prototype is passed to
|
cyg_interrupt_create() when an interrupt
|
cyg_interrupt_create() when an interrupt
|
object is created. When the ISR requests the scheduling of its
|
object is created. When the ISR requests the scheduling of its
|
DSR, this function will be called at some later point. In
|
DSR, this function will be called at some later point. In
|
addition to the vector and
|
addition to the vector and
|
data arguments, which will be the same as
|
data arguments, which will be the same as
|
those passed to the ISR, this routine is also passed a
|
those passed to the ISR, this routine is also passed a
|
count of the number of times the ISR has
|
count of the number of times the ISR has
|
requested that this DSR be scheduled. This counter is zeroed
|
requested that this DSR be scheduled. This counter is zeroed
|
each time the DSR actually runs, so it indicates how many
|
each time the DSR actually runs, so it indicates how many
|
interrupts have occurred since it last ran.
|
interrupts have occurred since it last ran.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|