Search
   

CAN Interface

Name

CAN Functions -- allow applications and other packages to access CAN devices

Synopsis

#include <cyg/io/can.h>
      

int cyg_can_init(void);

int cyg_can_open(char* devname, cyg_can_dev* dev);

int cyg_can_close(cyg_can_dev dev);

cyg_can_msg* cyg_can_msg_alloc(void);

void cyg_can_msg_free(cyg_can_msg* msg);

int cyg_can_send(cyg_can_dev dev, cyg_can_msg* msg);

int cyg_can_send_nowait(cyg_can_dev dev, cyg_can_msg* msg);

int cyg_can_recv(cyg_can_dev dev, cyg_can_msg** msg);

int cyg_can_recv_poll(cyg_can_dev dev, cyg_can_msg** msg);

int cyg_can_recv_timeout(cyg_can_dev dev, cyg_can_msg** msg, cyg_tick_count_t timeout);

void cyg_can_poll(void);

int cyg_can_filter_set(cyg_can_dev dev, cyg_bool ide, cyg_uint32 match, cyg_uint32 mask);

int cyg_can_filter_get(cyg_can_dev dev, cyg_bool* ide, cyg_uint32* match, cyg_uint32* mask);

int cyg_can_baud_set(cyg_can_dev dev, cyg_uint32 baud);

int cyg_can_baud_get(cyg_can_dev dev, cyg_uint32* baud);

const char cyg_can_error_string(int code);

Initialization and Device Access

Before performing any CAN system operations, the application must call cyg_can_init(). This function causes the CAN subsystem to be initialized and causes all the configured devices to initialize themselves. Only the first call to this function will initialize the subsystem, subsequent calls will do nothing, so libraries and independent systems may call it in their initialization routines without needing to ensure it is called only once.

To gain access to a specific CAN channel, the application must call cyg_can_open(). Channel names are defined in the configuration and are typically "can0" "can1" and so on. If the channel is not found this function will return CYG_CAN_NOTFOUND; it may also return errors generated by the device driver. If the channel is found the call will return CYG_CAN_NOERROR and the location pointed to by the dev parameter will be initialized with a handle on the channel. This handle must be used in all subsequent calls to access this channel.

When the application has finished with a channel it must call cyg_can_close() on the handle.

Buffer Management

The CAN subsystem uses buffers to pass messages between the application and the CAN subsystem. These buffers are allocated and managed by the CAN subsystem. The exact number of buffers is controllable in the configuration.

Each buffer contains the following fields:

cyg_can_msg * next

This field is used within the CAN subsystem to link this message buffer into lists. When the buffer is in the possession of the user (state is CYG_CAN_MSG_STATE_USER) then this may be used for application purposes.

unsigned int rtr

Remote Transmission Request. If this field is set in a transmitted message buffer, then the RTR bit on the message will be set and the data field will be ignored. On reception this field reflects the state of the RTR bit in the received message.

unsigned int ide

Extended ID. If this field is set then the id field contains a 29 bit extended ID. If it is clear then the ID is 11 bits.

unsigned int state

This field is used within the CAN subsystem to track the current state of the buffer. The following states are supported:

CYG_CAN_MSG_STATE_FREE

The message buffer is not currently being used and is on the CAN subsystem's free list.

CYG_CAN_MSG_STATE_USER

The message buffer is currently in the possession of the application code and is outside the control of the CAN subsystem.

CYG_CAN_MSG_STATE_TX

The message buffer is either currently being transmitted, or is in a queue of buffers awaiting transmission.

CYG_CAN_MSG_STATE_RX

The message buffer is the current pending receive buffer for a CAN channel. The next message from that channel will be received into this buffer.

CYG_CAN_MSG_STATE_RXQ

The message buffer is currently on a channel's receive queue. A message has been received into it but not yet been passed on to the user.

unsigned int len

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.

int result

An error code. For normal successful receptions of messages this will be CYG_CAN_NOERROR. Message buffers are also used to report special events on the channel such as transitions to passive error and bus off states. In these cases, the event will be reported using a message buffer with this field set to the appropriate error code.

cyg_uint32 timestamp

Some CAN channels contain a timer that can be used to timestamp received packets. If that is the case, then the timestamp will be stored in this field. If the channel does not have any hardware timing facility, this field will not be used. This field is used for internal purposes during message transmission.

cyg_uint32 id

Message ID. This is the ID to be transmitted with the message, or the ID received. If the ide field is set, then this will contain a 29 bit ID, otherwise it will contain an 11 bit ID.

cyg_uint8 data[8]

Message data. Only the first len bytes of data are valid. If the rtr field is set, then the contents of this field are ignored.

A message buffer may be allocated by calling cyg_can_msg_alloc() and freed by calling cyg_can_msg_free().

Transmit and Receive

To transmit a message an application must acquire a message buffer from the CAN subsystem, fill it in with the message to be sent and call cyg_can_send(). Following a successful call the buffer becomes the property of the CAN subsystem and will be returned to the free pool when the message has been transmitted. If an error is detected then the call will return an error code and the message buffer will be returned to the user for reuse or retransmission.

To send a message without waiting for it to complete, the application can call cyg_can_send_nowait().

To receive a message the application calls cyg_can_recv(). If there is a message waiting, then a pointer to the message buffer will be installed in the location pointed to by the msg argument and CYG_CAN_NOERROR is returned.

If the application does no want to wait for a message to arrive, it can call cyg_can_recv_poll() which will just test for a message and return. If a message is present then CYG_CAN_NOERROR is returned and the msg filled in with a pointer to a message buffer. If no message is present then the function will return CYG_CAN_AGAIN.

The application can also wait for a defined length of time for a message to arrive by calling cyg_can_recv_timeout(). The additional timeout argument supplies an absolute timeout in system ticks. If a message is present then CYG_CAN_NOERROR is returned and the msg filled in with a pointer to a message buffer. If no message arrives before the timeout expires then the function will return CYG_CAN_TIMEOUT.

Regardless of which receive function is used, a successful return results in a message buffer being passed back to the caller. The result field of this message buffer will either contain CYG_CAN_NOERROR for a normal message, or it will contain an error code indicating an event that has occurred on the channel. When the application has finished with the buffer it must return it to the CAN subsystem by calling cyg_can_msg_free().

The function cyg_can_poll() may be called to force all channels to check for transmission completion or pending receptions. When using interrupt driven devices it is unnecessary to call this. However, if there are any polled devices, this is the only way to ensure timely processing of received messages. This function should therefore be called from the application main loop, or from a separate timer driven thread, or by any other appropriate means to ensure communication proceeds in a timely fashion.

Filtering

The functions cyg_can_filter_set() and cyg_can_filter_get() allow the hardware filter to be set and queried. The standard filter model consists of a mask and a match value such that if an ID when bitwise ANDed with the mask equals the match value, then the message is accepted. If the hardware does not support a filter that conforms to this model then no hardware filtering is done, but the filter will still be applied by the CAN subsystem to all incoming packets.

In cyg_can_filter_set(), the match and mask arguments define the filter. The ide indicates whether the filter is for normal or extended IDs. It is hardware dependent what happens when the filter ID size does not match the ID size being used on the network.

Baud Rate

The functions cyg_can_baud_set() and cyg_can_baud_get() allow the channel baud rate to be set and queried. Baud rates from 10kb/s to 1Mb/s may be set, although not all device drivers will necessarily support all rates, many will only support a subset. Also, due to interactions between the input clock to the device and the divider granularity, it may not be possible to set some baud rates accurately at some system clock rates; it may be necessary to alter the system clock speed to enable communication.

Errors

Many of the CAN API calls return error codes. The result field of the message buffer structure may also contain an error code from this set. The following error codes may be returned by API calls:

CYG_CAN_NOERROR

No error, the operation completed successfully.

CYG_CAN_NOTFOUND

When returned from cyg_can_open() this error code means that the named CAN channel could not be found.

CYG_CAN_INVALID

When returned from cyg_can_filter_set() this error code means that the filter is invalid. When returned from cyg_can_baud_get() this error code means that the baud rate is invalid or the hardware cannot support it with sufficient accuracy in the current system configuration.

CYG_CAN_TIMEOUT

When returned from cyg_can_recv_timeout() this error code means that the timeout has expired with no message being received.

The following error codes may be passed back in the result field of a message buffer acquired from one of the receive functions. Refer to the CAN specification for details of what these events actually mean.

CYG_CAN_NOERROR

The message buffer contains a CAN message that was received from the channel.

CYG_CAN_WARN_TX

This error code indicates that the CAN channel's transmit error counter has exceeded its warning limit, which is usually 96.

CYG_CAN_WARN_RX

This error code indicates that the CAN channel's receive error counter has exceeded its warning limit, which is usually 96.

CYG_CAN_PASSIVE

This error code indicates that the CAN channel has gone into "error passive" mode.

CYG_CAN_BUSOFF

This error code indicates that the CAN channel had gone into "bus off" mode.

CYG_CAN_OVERRUN

This error code indicates that the CAN channel has lost one or more CAN messages due to all the hardware buffers being full.

The cyg_can_error_string() translates these error codes into strings for diagnostic purposes.

   
         
 
  Copyright © 2003-2008 eCosCentric Limited Privacy & Legal Statements