cyg_io_write(handle, buf, len) |
To transmit a message an application must fill a cyg_can_message
buffer and call cyg_io_write()
.
This function sends one single CAN message (not a buffer of CAN messages)
to a device. The size of data to send is contained in *len
and the actual size sent will be returned in the same place. A pointer to a
cyg_can_message is contained in *buf
.
The driver maintains a buffer to hold the data. The size of the intermediate
buffer is configurable within the interface module. The data is not modified
at all while it is being buffered. On return, *len
contains the amount of characters actually consumed - that means
*len
always contains
sizeof(cyg_can_message)
.
It is possible to configure the write call to be blocking (default) or
non-blocking. Non-blocking mode requires both the configuration option
CYGOPT_IO_CAN_SUPPORT_NONBLOCKING
to be enabled, and
the specific device to be set to non-blocking mode for writes
(see cyg_io_set_config()
). In blocking mode, the
call will not return until there is space in the buffer and the content
of the CAN message has been consumed. In non-blocking mode, if there is
no space in buffer for the CAN message, -EAGAIN
is
returned and the caller must try again.
It is possible to configure the write call to be non-blocking with timeout.
None-blocking mode with timeout requires the configuration option
CYGOPT_IO_CAN_SUPPORT_NONBLOCKING
and
CYGOPT_IO_CAN_SUPPORT_TIMEOUTS
to be enabled, requires
the eCos kernel package to be included and the specific device to be set
to non-blocking mode for writes (see cyg_io_set_config()
).
In non-blocking mode with timeouts, if there is no space in buffer for the
CAN message, the driver waits a certain amount of time (the timeout time)
for space in the buffer. If there is still no space in buffer after
expiration of the timeout time, -EINTR
is returned and
the caller must try again.
If a message was successfully sent, the function returns ENOERR
.
The CAN driver uses cyg_can_message
structures to
pass messages between the application and the CAN driver. The type
cyg_can_message provides a device independent type of CAN message.
Before calling the write function this message should be setup properly.
typedef struct can_message { cyg_uint32 id; cyg_uint8 data[8]; cyg_can_id_type ext; cyg_can_frame_type rtr; cyg_uint8 dlc; } cyg_can_message; |
The structure contains the following fields:
id
Message ID. This is the ID to be transmitted with the message, or the
ID received. If the ext
field is set, then
this will contain a 29 bit ID, otherwise it will contain an 11 bit ID.
data
Message data. Only the first dlc
bytes of
data are valid. If the rtr
field is set,
then the contents of this field are ignored.
ext
Extended ID. If this field is CYGNUM_CAN_ID_EXT
then the
id
field contains a 29 bit extended ID. If it
contains CYGNUM_CAN_ID_STD
then the ID is 11 bits.
rtr
Remote Transmission Request. If this field contains
CYGNUM_CAN_FRAME_RTR
then the RTR bit on the message
will be set and the data
field will be ignored.
If the field contains CYGNUM_CAN_FRAME_DATA
then a
normal data frame will be send.
dlc
The length of the data carried in the message. This can range from
zero to 8. In a message with the rtr
field set,
this indicates the size of data being requested.
Example code for sending one single CAN message:
cyg_can_message tx_msg; cyg_uint32 len; Cyg_ErrNo ret; tx_msg.id = 0x100; tx_msg.ext = CYGNUM_CAN_ID_EXT; tx_msg.rtr = CYGNUM_CAN_FRAME_DATA; tx_msg.dlc = 1; tx_msg.data[0] = 0xF1; len = sizeof(tx_msg); ret = cyg_io_write(hDrvCAN, &tx_msg, &len); |
cyg_io_read(handle, buf, len) |
To receive a message the application calls cyg_io_read()
.
This function receives one single event from a device. The desired size
of data to receive is contained in *len
and the
actual size obtained will be returned in the same place. A pointer to
a cyg_can_event is contained in *buf
.
No manipulation of the data is performed before being transferred.
Again, this buffering is completely configurable. On return,
*len
contains sizeof(cyg_can_event)
.
It is possible to configure the read call to be blocking (default) or
non-blocking. Non-blocking mode requires both the configuration option
CYGOPT_IO_CAN_SUPPORT_NONBLOCKING
to be enabled,
and the specific device to be set to non-blocking mode for reads
(see cyg_io_set_config()
). In blocking mode,
the call will not return until one single CAN event has been read.
In non-blocking mode, if there is no CAN event in buffer, the call
returns immediately with -EAGAIN
and the caller must
try again.
It is possible to configure the read call to be non-blocking with timeout.
None-blocking mode with timeout requires the configuration option
CYGOPT_IO_CAN_SUPPORT_NONBLOCKING
and
CYGOPT_IO_CAN_SUPPORT_TIMEOUTS
to be enabled,
requires the eCos kernel package to be included and the specific device
to be set to non-blocking mode for reads (see
cyg_io_set_config()
). In non-blocking mode with timeouts,
if there is no CAN event in receive buffer, the driver waits a certain amount
of time (the timeout time) for a CAN event to arrive. If there is still no
CAN event in buffer after expiration of the timeout time, -EINTR
is returned and the caller must try again.
If an event was successfully received, the function returns ENOERR
.
The CAN driver uses cyg_can_event
structures to
pass events from hardware device driver to the generic CAN driver.
A cyg_can_event
provides a generic device
independent type for handling CAN events that may occur.
typedef struct cyg_can_event_st { cyg_uint32 timestamp; cyg_can_event_flags_t flags; cyg_can_message msg; } cyg_can_event; |
The structure contains the following fields:
timestamp
If the hardware CAN device driver supports timestamps then this field may contain a timestamp value for an event that occured.
flags
Event flags. The flags
field contains bits that
indicate which kind of events occured. More than one flag can be raised
in a single event.
msg
CAN message. The msg field contains a CAN message if an RX or TX event
occured. If another type of event occured,
the data
field of
the msg
may contain additional event
specific data.
The following events are supported and after receiving an event the
application should check the flags
field against these values:
CYGNUM_CAN_EVENT_RX 0x00000001 // message received CYGNUM_CAN_EVENT_TX 0x00000002 // mesage transmitted CYGNUM_CAN_EVENT_WARNING_RX 0x00000004 // tx error counter (TEC) reached warning level (>96) CYGNUM_CAN_EVENT_WARNING_TX 0x00000008 // rx error counter (REC) reached warning level (>96) CYGNUM_CAN_EVENT_ERR_PASSIVE 0x00000010 // CAN "error passive" occured CYGNUM_CAN_EVENT_BUS_OFF 0x00000020 // CAN "bus off" error occured CYGNUM_CAN_EVENT_OVERRUN_RX 0x00000040 // overrun in RX queue occured CYGNUM_CAN_EVENT_OVERRUN_TX 0x00000080 // overrun in TX queue occured CYGNUM_CAN_EVENT_CAN_ERR 0x00000100 // a CAN bit or frame error occured CYGNUM_CAN_EVENT_LEAVING_STANDBY 0x00000200 // CAN hardware leaves standby / power down mode or is waked up CYGNUM_CAN_EVENT_ENTERING_STANDBY 0x00000400 // CAN hardware enters standby / power down mode CYGNUM_CAN_EVENT_ARBITRATION_LOST 0x00000800 // arbitration lost CYGNUM_CAN_EVENT_FILTER_ERR 0x00001000 // CAN message filter / acceptance filter error CYGNUM_CAN_EVENT_PHY_FAULT 0x00002000 // General failure of physical layer detected CYGNUM_CAN_EVENT_PHY_H 0x00004000 // Fault on CAN-H detected (Low Speed CAN) CYGNUM_CAN_EVENT_PHY_L 0x00008000 // Fault on CAN-L detected (Low Speed CAN) CYGNUM_CAN_EVENT_ERR_ACTIVE 0x00010000 // CAN controller now "error active" CYGNUM_CAN_EVENT_OVERRUN_RX_HW 0x00020000 // CAN controller reports a RX overrun |
Often the flags field will contain only one single set flag. But it is possible that a number of flags is set and so the flag field should always be checked by a receiver. Most of the flags are independent from each other and the receiver has to handle each of them separately.
The internal receive buffers of the CAN device driver are circular
buffers. That means that even if the buffers are completely filled
new messages will be received. In this case the newest message will
always overwrite the oldest message in the receive buffer. If this
happens the
CYGNUM_CAN_EVENT_OVERRUN_RX
flag will be set for
this new message that caused overwriting of the old one. However if an
overrun occurs in the hardware message buffers of the CAN controller,
the flag CYGNUM_CAN_EVENT_OVERRUN_RX_HW
is raised
instead.
Example code for receiving one single CAN event:
cyg_can_event rx_event; cyg_uint32 len; Cyg_ErrNo ret; len = sizeof(rx_event); ret = cyg_io_read(hDrvCAN, &rx_event, &len); if (ENOERR == ret) { if (rx_event.flags & CYGNUM_CAN_EVENT_RX) { // handle RX event } if (rx_event.flags & ~CYGNUM_CAN_EVENT_RX) { // handle other events } } else if (-EINTR == ret) { // handle timeout } |
cyg_io_get_config(handle, key, buf, len) |
This function is used to obtain run-time configuration about a device.
The type of information retrieved is specified by the key
.
The data will be returned in the given buffer. The value of
*len
should contain the 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 placed
in *len
. The appropriate key values are all listed
in the file <cyg/io/config_keys.h>.
The following config keys are currently supported:
CYG_IO_GET_CONFIG_READ_BLOCKING CYG_IO_GET_CONFIG_WRITE_BLOCKING CYG_IO_GET_CONFIG_CAN_INFO CYG_IO_GET_CONFIG_CAN_BUFFER_INFO CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO CYG_IO_GET_CONFIG_CAN_TIMEOUT CYG_IO_GET_CONFIG_CAN_HDI CYG_IO_GET_CONFIG_CAN_STATE CYG_IO_GET_CONFIG_CAN_ERR_COUNTERS |
cyg_io_set_config(handle, key, buf, len) |
This function is used to manipulate or change the run-time configuration
of a device. The type of information is specified by the key
.
The data will be obtained from the given buffer. The value of
*len
should contain the amount of data provided,
which must match the size appropriate to the selected key
.
The appropriate key values are all listed in the file
<cyg/io/config_keys.h>.
The following config keys are currently supported:
CYG_IO_SET_CONFIG_READ_BLOCKING CYG_IO_SET_CONFIG_WRITE_BLOCKING CYG_IO_SET_CONFIG_CAN_INFO CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH CYG_IO_SET_CONFIG_CAN_TIMEOUT CYG_IO_SET_CONFIG_CAN_MSGBUF CYG_IO_SET_CONFIG_CAN_MODE CYG_IO_SET_CONFIG_CAN_ABORT CYG_IO_SET_CONFIG_CAN_CALLBACK CYG_IO_SET_CONFIG_CAN_RANGE_FILTER CYG_IO_SET_CONFIG_CAN_MASK_FILTER |