PRELIMINARY CAN driver interface
WARNING These APIs are PRELIMINARY, and subject to change in the next few months.
To use the CAN driver, ensure that the correct driver library for your device is linked in and include this header file as follows:
This module serves as the main interface for applications. Its purpose is to redirect the CAN APIs to specific driver implementations which are specified using a pointer to a CAN_FxnTable.
The Controller Area Network (CAN) driver is a generic driver that allows for communication on a CAN bus. It is a two-wire, half-duplex, LAN system that is collision free. The main method of transfer is by broadcasting. The CAN protocol defines the format of data transfer, and this CAN driver allows full functionality as a transmitting and receiving node on a bus. However, there can be higher-level software layers and stacks that use this driver to enable more advanced features. Functional modes available in this driver include blocking and non-blocking.
The APIs in this driver serve as an interface to a typical RTOS application. The specific peripheral implementations are responsible for creating all the RTOS specific primitives to allow for thread-safe operation.
The CAN driver interface provides device independent APIs, data types, and macros.
The following code example opens a CAN instance, creates an incrementing CAN frame, and continually writes them to the CAN bus. NOTE: a CAN receiver on this bus is needed, or else this transmitter will continually throw an error if it does not detect an ACK.
Details for the example code above are described in the following subsections.
In order to use the CAN APIs, the application is required to provide device-specific CAN configuration in the ti_drivers_config.c file. The CAN driver interface defines a configuration data structure:
You will need to check the device-specific CAN driver implementation's header file for example configuration. Please also refer to the ti_drivers_config.c file to see the CAN configuration.
CAN_init() must be called before any other CAN APIs. This function calls the device implementation's CAN initialization function, for each element of CAN_config[].
Opening a CAN requires four steps:
Only one CAN index can be used at a time; calling CAN_open() a second time with the same index previously passed to CAN_open() will result in an error. You can, though, re-use the index if the instance is closed via CAN_close(). In the example code, CONFIG_CAN0 is passed to CAN_open(). This macro is defined in the applications "ti_drivers_config.h" file.
The CAN driver can operate in blocking mode or nonblocking mode, by setting the mode parameters passed to CAN_open(). If these parameters are not set, as in the example code, the CAN driver defaults to blocking mode. Options for the mode parameter are CAN_MODE_BLOCKING and CAN_MODE_NONBLOCKING:
The example code reads one CAN frame from the CAN instance, and then writes one CAN frame back to the same instance:
The CAN driver allows CAN_read() and CAN_write() calls to happen for any node at any time from the CAN bus. Please see the CAN protocol for how it handles collisions. The ability to filter incoming messages are also available through CAN_Params.
The CAN driver interface module is joined (at link time) to an array of CAN_Config data structures named CAN_config. CAN_config is implemented in the application with each entry being an instance of a CAN peripheral. Each entry in CAN_config contains a:
The CAN APIs are redirected to the device specific implementations using the CAN_FxnTable pointer of the CAN_config entry. In order to use device specific functions of the CAN driver directly, link in the correct driver library for your device and include the device specific CAN driver header file (which in turn includes CAN.h). For example, for the MSP432 family of devices, you would include the following header file:
Go to the source code of this file.
Data Structures | |
struct | CAN_Params |
CAN Parameters. More... | |
struct | CAN_FxnTable |
The definition of a CAN function table that contains the required set of functions to control a specific CAN driver implementation. More... | |
struct | CAN_Config_ |
CAN Global configuration. More... | |
Macros | |
#define | CAN_CMD_RESERVED (32) |
#define | CAN_STATUS_RESERVED (-32) |
#define | CAN_STATUS_SUCCESS (0) |
Successful status code returned by CAN_control(). More... | |
#define | CAN_STATUS_ERROR (-1) |
Generic error status code returned by CAN_control(). More... | |
#define | CAN_STATUS_UNDEFINEDCMD (-2) |
An error status code returned by CAN_control() for undefined command codes. More... | |
#define | CAN_WAIT_FOREVER (~(0U)) |
Wait forever define. More... | |
Typedefs | |
typedef struct CAN_Config_ * | CAN_Handle |
A handle that is returned from a CAN_open() call. More... | |
typedef struct can_frame | CAN_Frame |
CAN frame structure. More... | |
typedef void(* | CAN_CloseFxn) (CAN_Handle handle) |
A function pointer to a driver specific implementation of CAN_CloseFxn(). More... | |
typedef int_fast16_t(* | CAN_ControlFxn) (CAN_Handle handle, uint_fast16_t cmd, void *arg) |
A function pointer to a driver specific implementation of CAN_ControlFxn(). More... | |
typedef void(* | CAN_InitFxn) (CAN_Handle handle) |
A function pointer to a driver specific implementation of CAN_InitFxn(). More... | |
typedef CAN_Handle(* | CAN_OpenFxn) (CAN_Handle handle, CAN_Params *params) |
A function pointer to a driver specific implementation of CAN_OpenFxn(). More... | |
typedef int_fast32_t(* | CAN_ReadFxn) (CAN_Handle handle, void *buffer, size_t size) |
A function pointer to a driver specific implementation of CAN_ReadFxn(). More... | |
typedef int_fast32_t(* | CAN_WriteFxn) (CAN_Handle handle, const void *buffer, size_t size) |
A function pointer to a driver specific implementation of CAN_WriteFxn(). More... | |
typedef void(* | CAN_TxMsgFxn) (CAN_Handle handle) |
A function pointer to a driver specific implementation of CAN_TxMsgFxn(). More... | |
typedef struct CAN_Config_ | CAN_Config |
CAN Global configuration. More... | |
Enumerations | |
enum | CAN_Mode { CAN_MODE_BLOCKING, CAN_MODE_NONBLOCKING } |
CAN mode settings. More... | |
enum | CAN_Direction { CAN_DIRECTION_READ = 0x1, CAN_DIRECTION_WRITE = 0x2, CAN_DIRECTION_READWRITE = 0x3 } |
CAN communication mode. More... | |
Functions | |
void | CAN_close (CAN_Handle handle) |
Function to close a CAN peripheral specified by the CAN handle. More... | |
void | CAN_init (void) |
Function to initialize the CAN module. More... | |
int_fast16_t | CAN_control (CAN_Handle handle, uint_fast16_t cmd, void *arg) |
Function performs implementation specific features on a given CAN_Handle. More... | |
CAN_Handle | CAN_open (uint_least8_t index, CAN_Params *params) |
Function to initialize a given CAN peripheral. More... | |
void | CAN_Params_init (CAN_Params *params) |
Function to initialize the CAN_Params struct to its defaults. More... | |
int_fast32_t | CAN_write (CAN_Handle handle, const void *buffer, size_t size) |
Function that writes data to a CAN with interrupts enabled. More... | |
int_fast32_t | CAN_read (CAN_Handle handle, void *buffer, size_t size) |
Function that reads data from a CAN with interrupt enabled. More... | |
#define CAN_WAIT_FOREVER (~(0U)) |
Wait forever define.
typedef struct CAN_Config_* CAN_Handle |
A handle that is returned from a CAN_open() call.
CAN frame structure.
The structure that makes up a CAN message. The unions are provided in order for there to be structural naming compatibility with SocketCAN while at the same time providing an alternative easier to use naming convention. We diverge a bit with TI structural naming convention of the struct in order to provide an option to be compatible with SocketCAN conventions.
typedef void(* CAN_CloseFxn) (CAN_Handle handle) |
A function pointer to a driver specific implementation of CAN_CloseFxn().
typedef int_fast16_t(* CAN_ControlFxn) (CAN_Handle handle, uint_fast16_t cmd, void *arg) |
A function pointer to a driver specific implementation of CAN_ControlFxn().
typedef void(* CAN_InitFxn) (CAN_Handle handle) |
A function pointer to a driver specific implementation of CAN_InitFxn().
typedef CAN_Handle(* CAN_OpenFxn) (CAN_Handle handle, CAN_Params *params) |
A function pointer to a driver specific implementation of CAN_OpenFxn().
typedef int_fast32_t(* CAN_ReadFxn) (CAN_Handle handle, void *buffer, size_t size) |
A function pointer to a driver specific implementation of CAN_ReadFxn().
typedef int_fast32_t(* CAN_WriteFxn) (CAN_Handle handle, const void *buffer, size_t size) |
A function pointer to a driver specific implementation of CAN_WriteFxn().
typedef void(* CAN_TxMsgFxn) (CAN_Handle handle) |
A function pointer to a driver specific implementation of CAN_TxMsgFxn().
typedef struct CAN_Config_ CAN_Config |
CAN Global configuration.
The CAN_Config structure contains a set of pointers used to characterize the CAN driver implementation.
This structure needs to be defined before calling CAN_init() and it must not be changed thereafter.
enum CAN_Mode |
CAN mode settings.
This enum defines the read, write, and blocking modes for the configured CAN.
Enumerator | |
---|---|
CAN_MODE_BLOCKING | Blocking and will return only when at least one CAN frame has been processed by CAN_write() or CAN_read() data, or if the optional timeout occurs. |
CAN_MODE_NONBLOCKING | Non-blocking and will return immediately with or without write or read data. Error flags could be thrown if invalid CAN_write() or CAN_read(). |
enum CAN_Direction |
CAN communication mode.
This enum defines read or write communication direction for the configured CAN.
void CAN_close | ( | CAN_Handle | handle | ) |
Function to close a CAN peripheral specified by the CAN handle.
handle | A CAN_Handle returned from CAN_open() |
void CAN_init | ( | void | ) |
Function to initialize the CAN module.
int_fast16_t CAN_control | ( | CAN_Handle | handle, |
uint_fast16_t | cmd, | ||
void * | arg | ||
) |
Function performs implementation specific features on a given CAN_Handle.
Commands for CAN_control() can originate from CAN.h or from implementation specific CAN*.h (CANTCAN2550.h, CANMSP432.h, etc.. ) files. While commands from CAN.h are API portable across driver implementations, not all implementations may support all these commands. Conversely, commands from driver implementation specific CAN*.h files add unique driver capabilities but are not API portable across all CAN driver implementations.
Commands supported by CAN.h follow a CAN_CMD_<cmd> naming convention.
Commands supported by CAN*.h follow a CAN*_CMD_<cmd> naming convention.
Each control command defines arg differently. The types of arg are documented with each command.
handle | A CAN handle returned from CAN_open() |
cmd | CAN.h or CAN*.h commands. |
arg | An optional R/W (read/write) command argument accompanied with cmd |
CAN_Handle CAN_open | ( | uint_least8_t | index, |
CAN_Params * | params | ||
) |
Function to initialize a given CAN peripheral.
Function to initialize a given CAN peripheral specified by the particular index value.
index | Logical peripheral number for the CAN indexed into the CAN_config table |
params | Pointer to a parameter block. If NULL, default parameter values will be used. All the fields in this structure are RO (read-only). |
void CAN_Params_init | ( | CAN_Params * | params | ) |
Function to initialize the CAN_Params struct to its defaults.
params | An pointer to CAN_Params structure for initialization |
Defaults values are: mode = CAN_MODE_BLOCKING; direction = CAN_DIRECTION_READWRITE; readTimeout = CAN_WAIT_FOREVER; writeTimeout = CAN_WAIT_FOREVER; baudRate = 125000;
int_fast32_t CAN_write | ( | CAN_Handle | handle, |
const void * | buffer, | ||
size_t | size | ||
) |
Function that writes data to a CAN with interrupts enabled.
CAN_write() writes data from a memory buffer to the CAN interface. The source is specified by buffer and the number of bytes to write is given by size.
In CAN_MODE_BLOCKING, CAN_write() blocks task execution until at least one CAN frame data in buffer has been written.
In CAN_MODE_NONBLOCKING, CAN_write() returns immediately with the number of bytes (in frame size chunks) that were able to be immediately written.
handle | A CAN_Handle returned by CAN_open() |
buffer | A read-only pointer to buffer containing CAN frames to be written to the CAN interface (CAN_Frame, struct can_frame) |
size | The number of bytes in the buffer that should be written to the CAN interface, sizeof(CAN_frame) |
int_fast32_t CAN_read | ( | CAN_Handle | handle, |
void * | buffer, | ||
size_t | size | ||
) |
Function that reads data from a CAN with interrupt enabled.
CAN_read() reads data into a memory buffer from the CAN interface. The destination is specified by buffer and the number of bytes to read is given by size.
In CAN_MODE_BLOCKING, CAN_read() blocks task execution until at least one CAN frame data can be received.
In CAN_MODE_NONBLOCKING, CAN_write() returns immediately with the number of bytes (in frame size chunks) that were able to be immediately received.
handle | A CAN_Handle returned by CAN_open() |
buffer | A pointer to buffer containing space for CAN frames to be read into from the CAN interface (CAN_Frame, struct can_frame) |
size | The number of bytes in the buffer that can be filled with receive data from the CAN interface, sizeof(CAN_frame) |