ChibiOS/HAL  6.1.0
CAN Driver

Generic CAN Driver. More...

Collaboration diagram for CAN Driver:

Detailed Description

Generic CAN Driver.

This module implements a generic CAN (Controller Area Network) driver allowing the exchange of information at frame level.

Precondition
In order to use the CAN driver the HAL_USE_CAN option must be enabled in halconf.h.

Driver State Machine

The driver implements a state machine internally, not all the driver functionalities can be used in any moment, any transition not explicitly shown in the following diagram has to be considered an error and shall be captured by an assertion (if enabled).

dot_inline_dotgraph_2.png

Macros

#define CAN_ANY_MAILBOX   0U
 Special mailbox identifier. More...
 
#define CAN_TX_MAILBOXES   1
 Number of transmit mailboxes. More...
 
#define CAN_RX_MAILBOXES   1
 Number of receive mailboxes. More...
 

CAN status flags

#define CAN_LIMIT_WARNING   1U
 Errors rate warning. More...
 
#define CAN_LIMIT_ERROR   2U
 Errors rate error. More...
 
#define CAN_BUS_OFF_ERROR   4U
 Bus off condition reached. More...
 
#define CAN_FRAMING_ERROR   8U
 Framing error of some kind on the CAN bus. More...
 
#define CAN_OVERFLOW_ERROR   16U
 Overflow in receive queue. More...
 

CAN configuration options

#define CAN_USE_SLEEP_MODE   TRUE
 Sleep mode related APIs inclusion switch. More...
 
#define CAN_ENFORCE_USE_CALLBACKS   FALSE
 Enforces the driver to use direct callbacks rather than OSAL events. More...
 

Macro Functions

#define CAN_MAILBOX_TO_MASK(mbx)   (1U << ((mbx) - 1U))
 Converts a mailbox index to a bit mask. More...
 
#define canTransmit(canp, mailbox, ctfp, timeout)   canTransmitTimeout(canp, mailbox, ctfp, timeout)
 Legacy name for canTransmitTimeout(). More...
 
#define canReceive(canp, mailbox, crfp, timeout)   canReceiveTimeout(canp, mailbox, crfp, timeout)
 Legacy name for canReceiveTimeout(). More...
 

Low level driver helper macros

#define _can_tx_empty_isr(canp, flags)
 TX mailbox empty event. More...
 
#define _can_rx_full_isr(canp, flags)
 RX mailbox empty full event. More...
 
#define _can_wakeup_isr(canp)
 Error event. More...
 
#define _can_error_isr(canp, flags)
 Error event. More...
 

PLATFORM configuration options

#define PLATFORM_CAN_USE_CAN1   FALSE
 CAN1 driver enable switch. More...
 

Typedefs

typedef struct CANDriver CANDriver
 Type of a structure representing an CAN driver. More...
 
typedef uint32_t canmbx_t
 Type of a transmission mailbox index. More...
 
typedef void(* can_callback_t) (CANDriver *canp, uint32_t flags)
 Type of a CAN notification callback. More...
 

Data Structures

struct  CANTxFrame
 CAN transmission frame. More...
 
struct  CANRxFrame
 CAN received frame. More...
 
struct  CANConfig
 Driver configuration structure. More...
 
struct  CANDriver
 Structure representing an CAN driver. More...
 

Functions

void canInit (void)
 CAN Driver initialization. More...
 
void canObjectInit (CANDriver *canp)
 Initializes the standard part of a CANDriver structure. More...
 
void canStart (CANDriver *canp, const CANConfig *config)
 Configures and activates the CAN peripheral. More...
 
void canStop (CANDriver *canp)
 Deactivates the CAN peripheral. More...
 
bool canTryTransmitI (CANDriver *canp, canmbx_t mailbox, const CANTxFrame *ctfp)
 Can frame transmission attempt. More...
 
bool canTryReceiveI (CANDriver *canp, canmbx_t mailbox, CANRxFrame *crfp)
 Can frame receive attempt. More...
 
msg_t canTransmitTimeout (CANDriver *canp, canmbx_t mailbox, const CANTxFrame *ctfp, sysinterval_t timeout)
 Can frame transmission. More...
 
msg_t canReceiveTimeout (CANDriver *canp, canmbx_t mailbox, CANRxFrame *crfp, sysinterval_t timeout)
 Can frame receive. More...
 
void canSleep (CANDriver *canp)
 Enters the sleep mode. More...
 
void canWakeup (CANDriver *canp)
 Enforces leaving the sleep mode. More...
 
void can_lld_init (void)
 Low level CAN driver initialization. More...
 
void can_lld_start (CANDriver *canp)
 Configures and activates the CAN peripheral. More...
 
void can_lld_stop (CANDriver *canp)
 Deactivates the CAN peripheral. More...
 
bool can_lld_is_tx_empty (CANDriver *canp, canmbx_t mailbox)
 Determines whether a frame can be transmitted. More...
 
void can_lld_transmit (CANDriver *canp, canmbx_t mailbox, const CANTxFrame *ctfp)
 Inserts a frame into the transmit queue. More...
 
bool can_lld_is_rx_nonempty (CANDriver *canp, canmbx_t mailbox)
 Determines whether a frame has been received. More...
 
void can_lld_receive (CANDriver *canp, canmbx_t mailbox, CANRxFrame *crfp)
 Receives a frame from the input queue. More...
 
void can_lld_sleep (CANDriver *canp)
 Enters the sleep mode. More...
 
void can_lld_wakeup (CANDriver *canp)
 Enforces leaving the sleep mode. More...
 

Enumerations

Variables

CANDriver CAND1
 CAN1 driver identifier. More...
 

Macro Definition Documentation

#define CAN_LIMIT_WARNING   1U

Errors rate warning.

Definition at line 41 of file hal_can.h.

#define CAN_LIMIT_ERROR   2U

Errors rate error.

Definition at line 45 of file hal_can.h.

#define CAN_BUS_OFF_ERROR   4U

Bus off condition reached.

Definition at line 49 of file hal_can.h.

#define CAN_FRAMING_ERROR   8U

Framing error of some kind on the CAN bus.

Definition at line 53 of file hal_can.h.

#define CAN_OVERFLOW_ERROR   16U

Overflow in receive queue.

Definition at line 57 of file hal_can.h.

#define CAN_ANY_MAILBOX   0U

Special mailbox identifier.

Definition at line 63 of file hal_can.h.

Referenced by can_lld_is_rx_nonempty(), and can_lld_is_tx_empty().

#define CAN_USE_SLEEP_MODE   TRUE

Sleep mode related APIs inclusion switch.

This option can only be enabled if the CAN implementation supports the sleep mode, see the macro CAN_SUPPORTS_SLEEP exported by the underlying implementation.

Definition at line 80 of file hal_can.h.

#define CAN_ENFORCE_USE_CALLBACKS   FALSE

Enforces the driver to use direct callbacks rather than OSAL events.

Definition at line 87 of file hal_can.h.

#define CAN_MAILBOX_TO_MASK (   mbx)    (1U << ((mbx) - 1U))

Converts a mailbox index to a bit mask.

Definition at line 123 of file hal_can.h.

#define canTransmit (   canp,
  mailbox,
  ctfp,
  timeout 
)    canTransmitTimeout(canp, mailbox, ctfp, timeout)

Legacy name for canTransmitTimeout().

Deprecated:

Definition at line 130 of file hal_can.h.

#define canReceive (   canp,
  mailbox,
  crfp,
  timeout 
)    canReceiveTimeout(canp, mailbox, crfp, timeout)

Legacy name for canReceiveTimeout().

Deprecated:

Definition at line 138 of file hal_can.h.

#define _can_tx_empty_isr (   canp,
  flags 
)
Value:
{ \
osalThreadDequeueAllI(&(canp)->txqueue, MSG_OK); \
osalEventBroadcastFlagsI(&(canp)->txempty_event, flags); \
}
void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up all threads from the queue.
Definition: osal.c:309
static void osalSysLockFromISR(void)
Enters a critical zone from ISR context.
Definition: osal.h:550
void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags)
Add flags to an event source object.
Definition: osal.c:323
static void osalSysUnlockFromISR(void)
Leaves a critical zone from ISR context.
Definition: osal.h:560

TX mailbox empty event.

Definition at line 150 of file hal_can.h.

#define _can_rx_full_isr (   canp,
  flags 
)
Value:
{ \
osalThreadDequeueAllI(&(canp)->rxqueue, MSG_OK); \
osalEventBroadcastFlagsI(&(canp)->rxfull_event, flags); \
}
void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg)
Dequeues and wakes up all threads from the queue.
Definition: osal.c:309
static void osalSysLockFromISR(void)
Enters a critical zone from ISR context.
Definition: osal.h:550
void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags)
Add flags to an event source object.
Definition: osal.c:323
static void osalSysUnlockFromISR(void)
Leaves a critical zone from ISR context.
Definition: osal.h:560

RX mailbox empty full event.

Definition at line 160 of file hal_can.h.

#define _can_wakeup_isr (   canp)
Value:
{ \
osalEventBroadcastFlagsI(&(canp)->wakeup_event, 0U); \
}
static void osalSysLockFromISR(void)
Enters a critical zone from ISR context.
Definition: osal.h:550
void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags)
Add flags to an event source object.
Definition: osal.c:323
static void osalSysUnlockFromISR(void)
Leaves a critical zone from ISR context.
Definition: osal.h:560

Error event.

Definition at line 170 of file hal_can.h.

#define _can_error_isr (   canp,
  flags 
)
Value:
{ \
osalEventBroadcastFlagsI(&(canp)->error_event, flags); \
}
static void osalSysLockFromISR(void)
Enters a critical zone from ISR context.
Definition: osal.h:550
void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags)
Add flags to an event source object.
Definition: osal.c:323
static void osalSysUnlockFromISR(void)
Leaves a critical zone from ISR context.
Definition: osal.h:560

Error event.

Definition at line 179 of file hal_can.h.

#define CAN_TX_MAILBOXES   1

Number of transmit mailboxes.

Definition at line 37 of file hal_can_lld.h.

Referenced by canTransmitTimeout(), and canTryTransmitI().

#define CAN_RX_MAILBOXES   1

Number of receive mailboxes.

Definition at line 42 of file hal_can_lld.h.

Referenced by canReceiveTimeout(), and canTryReceiveI().

#define PLATFORM_CAN_USE_CAN1   FALSE

CAN1 driver enable switch.

If set to TRUE the support for CAN1 is included.

Note
The default is FALSE.

Definition at line 58 of file hal_can_lld.h.

Typedef Documentation

typedef struct CANDriver CANDriver

Type of a structure representing an CAN driver.

Definition at line 73 of file hal_can_lld.h.

typedef uint32_t canmbx_t

Type of a transmission mailbox index.

Definition at line 78 of file hal_can_lld.h.

typedef void(* can_callback_t) (CANDriver *canp, uint32_t flags)

Type of a CAN notification callback.

Parameters
[in]canppointer to the CANDriver object triggering the callback
[in]flagsflags associated to the mailbox callback

Definition at line 88 of file hal_can_lld.h.

Enumeration Type Documentation

enum canstate_t

Driver state machine possible states.

Enumerator
CAN_UNINIT 

Not initialized.

CAN_STOP 

Stopped.

CAN_STARTING 

Starting.

CAN_READY 

Ready.

CAN_SLEEP 

Sleep state.

Definition at line 102 of file hal_can.h.

Function Documentation

void canInit ( void  )

CAN Driver initialization.

Note
This function is implicitly invoked by halInit(), there is no need to explicitly initialize the driver.
Function Class:Initializer, this function just initializes an object and can be invoked before the kernel is initialized.

Definition at line 56 of file hal_can.c.

References can_lld_init().

Referenced by halInit().

Here is the call graph for this function:

void canObjectInit ( CANDriver canp)

Initializes the standard part of a CANDriver structure.

Parameters
[out]canppointer to the CANDriver object
Function Class:Initializer, this function just initializes an object and can be invoked before the kernel is initialized.

Definition at line 68 of file hal_can.c.

References CAN_STOP, CANDriver::config, CANDriver::error_event, osalEventObjectInit(), osalThreadQueueObjectInit(), CANDriver::rxfull_event, CANDriver::rxqueue, CANDriver::sleep_event, CANDriver::state, CANDriver::txempty_event, CANDriver::txqueue, and CANDriver::wakeup_event.

Referenced by can_lld_init().

Here is the call graph for this function:

void canStart ( CANDriver canp,
const CANConfig config 
)

Configures and activates the CAN peripheral.

Note
Activating the CAN bus can be a slow operation.
Unlike other drivers it is not possible to restart the CAN driver without first stopping it using canStop().
Parameters
[in]canppointer to the CANDriver object
[in]configpointer to the CANConfig object. Depending on the implementation the value can be NULL.
Function Class:Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 104 of file hal_can.c.

References can_lld_start(), CAN_READY, CAN_STARTING, CAN_STOP, CANDriver::config, osalDbgAssert, osalDbgCheck, osalSysLock(), osalSysUnlock(), and CANDriver::state.

Here is the call graph for this function:

void canStop ( CANDriver canp)

Deactivates the CAN peripheral.

Parameters
[in]canppointer to the CANDriver object
Function Class:Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 131 of file hal_can.c.

References can_lld_stop(), CAN_READY, CAN_STOP, CANDriver::config, osalDbgAssert, osalDbgCheck, osalOsRescheduleS(), osalSysLock(), osalSysUnlock(), osalThreadDequeueAllI(), CANDriver::rxqueue, CANDriver::state, and CANDriver::txqueue.

Here is the call graph for this function:

bool canTryTransmitI ( CANDriver canp,
canmbx_t  mailbox,
const CANTxFrame ctfp 
)

Can frame transmission attempt.

The specified frame is queued for transmission, if the hardware queue is full then the function fails.

Parameters
[in]canppointer to the CANDriver object
[in]mailboxmailbox number, CAN_ANY_MAILBOX for any mailbox
[in]ctfppointer to the CAN frame to be transmitted
Returns
The operation result.
Return values
falseFrame transmitted.
trueMailbox full.
Function Class:This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 166 of file hal_can.c.

References can_lld_is_tx_empty(), can_lld_transmit(), CAN_READY, CAN_SLEEP, CAN_TX_MAILBOXES, osalDbgAssert, osalDbgCheck, osalDbgCheckClassI, and CANDriver::state.

Here is the call graph for this function:

bool canTryReceiveI ( CANDriver canp,
canmbx_t  mailbox,
CANRxFrame crfp 
)

Can frame receive attempt.

The function tries to fetch a frame from a mailbox.

Parameters
[in]canppointer to the CANDriver object
[in]mailboxmailbox number, CAN_ANY_MAILBOX for any mailbox
[out]crfppointer to the buffer where the CAN frame is copied
Returns
The operation result.
Return values
falseFrame fetched.
trueMailbox empty.
Function Class:This is an I-Class API, this function can be invoked from within a system lock zone by both threads and interrupt handlers.

Definition at line 200 of file hal_can.c.

References can_lld_is_rx_nonempty(), can_lld_receive(), CAN_READY, CAN_RX_MAILBOXES, CAN_SLEEP, osalDbgAssert, osalDbgCheck, osalDbgCheckClassI, and CANDriver::state.

Here is the call graph for this function:

msg_t canTransmitTimeout ( CANDriver canp,
canmbx_t  mailbox,
const CANTxFrame ctfp,
sysinterval_t  timeout 
)

Can frame transmission.

The specified frame is queued for transmission, if the hardware queue is full then the invoking thread is queued.

Note
Trying to transmit while in sleep mode simply enqueues the thread.
Parameters
[in]canppointer to the CANDriver object
[in]mailboxmailbox number, CAN_ANY_MAILBOX for any mailbox
[in]ctfppointer to the CAN frame to be transmitted
[in]timeoutthe number of ticks before the operation timeouts, the following special values are allowed:
  • TIME_IMMEDIATE immediate timeout.
  • TIME_INFINITE no timeout.
Returns
The operation result.
Return values
MSG_OKthe frame has been queued for transmission.
MSG_TIMEOUTThe operation has timed out.
MSG_RESETThe driver has been stopped while waiting.
Function Class:Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 242 of file hal_can.c.

References can_lld_is_tx_empty(), can_lld_transmit(), CAN_READY, CAN_SLEEP, CAN_TX_MAILBOXES, osalDbgAssert, osalDbgCheck, osalSysLock(), osalSysUnlock(), osalThreadEnqueueTimeoutS(), CANDriver::state, and CANDriver::txqueue.

Here is the call graph for this function:

msg_t canReceiveTimeout ( CANDriver canp,
canmbx_t  mailbox,
CANRxFrame crfp,
sysinterval_t  timeout 
)

Can frame receive.

The function waits until a frame is received.

Note
Trying to receive while in sleep mode simply enqueues the thread.
Parameters
[in]canppointer to the CANDriver object
[in]mailboxmailbox number, CAN_ANY_MAILBOX for any mailbox
[out]crfppointer to the buffer where the CAN frame is copied
[in]timeoutthe number of ticks before the operation timeouts, the following special values are allowed:
  • TIME_IMMEDIATE immediate timeout (useful in an event driven scenario where a thread never blocks for I/O).
  • TIME_INFINITE no timeout.
Returns
The operation result.
Return values
MSG_OKa frame has been received and placed in the buffer.
MSG_TIMEOUTThe operation has timed out.
MSG_RESETThe driver has been stopped while waiting.
Function Class:Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 290 of file hal_can.c.

References can_lld_is_rx_nonempty(), can_lld_receive(), CAN_READY, CAN_RX_MAILBOXES, CAN_SLEEP, osalDbgAssert, osalDbgCheck, osalSysLock(), osalSysUnlock(), osalThreadEnqueueTimeoutS(), CANDriver::rxqueue, and CANDriver::state.

Here is the call graph for this function:

void canSleep ( CANDriver canp)

Enters the sleep mode.

This function puts the CAN driver in sleep mode and broadcasts the sleep_event event source.

Precondition
In order to use this function the option CAN_USE_SLEEP_MODE must be enabled and the CAN_SUPPORTS_SLEEP mode must be supported by the low level driver.
Parameters
[in]canppointer to the CANDriver object
Function Class:Normal API, this function can be invoked by regular system threads but not from within a lock zone.

Definition at line 329 of file hal_can.c.

References can_lld_sleep(), CAN_READY, CAN_SLEEP, osalDbgAssert, osalDbgCheck, osalEventBroadcastFlagsI(), osalOsRescheduleS(), osalSysLock(), osalSysUnlock(), CANDriver::sleep_event, and CANDriver::state.

Here is the call graph for this function:

void canWakeup ( CANDriver canp)

Enforces leaving the sleep mode.

Note
The sleep mode is supposed to be usually exited automatically by an hardware event.
Parameters
[in]canppointer to the CANDriver object

Definition at line 354 of file hal_can.c.

References can_lld_wakeup(), CAN_READY, CAN_SLEEP, osalDbgAssert, osalDbgCheck, osalEventBroadcastFlagsI(), osalOsRescheduleS(), osalSysLock(), osalSysUnlock(), CANDriver::state, and CANDriver::wakeup_event.

Here is the call graph for this function:

void can_lld_init ( void  )

Low level CAN driver initialization.

Function Class:Not an API, this function is for internal use only.

Definition at line 65 of file hal_can_lld.c.

References canObjectInit().

Referenced by canInit().

Here is the call graph for this function:

void can_lld_start ( CANDriver canp)

Configures and activates the CAN peripheral.

Parameters
[in]canppointer to the CANDriver object
Function Class:Not an API, this function is for internal use only.

Definition at line 80 of file hal_can_lld.c.

References CAN_STOP, and CANDriver::state.

Referenced by canStart().

void can_lld_stop ( CANDriver canp)

Deactivates the CAN peripheral.

Parameters
[in]canppointer to the CANDriver object
Function Class:Not an API, this function is for internal use only.

Definition at line 101 of file hal_can_lld.c.

References CAN_READY, and CANDriver::state.

Referenced by canStop().

bool can_lld_is_tx_empty ( CANDriver canp,
canmbx_t  mailbox 
)

Determines whether a frame can be transmitted.

Parameters
[in]canppointer to the CANDriver object
[in]mailboxmailbox number, CAN_ANY_MAILBOX for any mailbox
Returns
The queue space availability.
Return values
falseno space in the transmit queue.
truetransmit slot available.
Function Class:Not an API, this function is for internal use only.

Definition at line 127 of file hal_can_lld.c.

References CAN_ANY_MAILBOX.

Referenced by canTransmitTimeout(), and canTryTransmitI().

void can_lld_transmit ( CANDriver canp,
canmbx_t  mailbox,
const CANTxFrame ctfp 
)

Inserts a frame into the transmit queue.

Parameters
[in]canppointer to the CANDriver object
[in]ctfppointer to the CAN frame to be transmitted
[in]mailboxmailbox number, CAN_ANY_MAILBOX for any mailbox
Function Class:Not an API, this function is for internal use only.

Definition at line 154 of file hal_can_lld.c.

Referenced by canTransmitTimeout(), and canTryTransmitI().

bool can_lld_is_rx_nonempty ( CANDriver canp,
canmbx_t  mailbox 
)

Determines whether a frame has been received.

Parameters
[in]canppointer to the CANDriver object
[in]mailboxmailbox number, CAN_ANY_MAILBOX for any mailbox
Returns
The queue space availability.
Return values
falseno space in the transmit queue.
truetransmit slot available.
Function Class:Not an API, this function is for internal use only.

Definition at line 176 of file hal_can_lld.c.

References CAN_ANY_MAILBOX.

Referenced by canReceiveTimeout(), and canTryReceiveI().

void can_lld_receive ( CANDriver canp,
canmbx_t  mailbox,
CANRxFrame crfp 
)

Receives a frame from the input queue.

Parameters
[in]canppointer to the CANDriver object
[in]mailboxmailbox number, CAN_ANY_MAILBOX for any mailbox
[out]crfppointer to the buffer where the CAN frame is copied
Function Class:Not an API, this function is for internal use only.

Definition at line 202 of file hal_can_lld.c.

Referenced by canReceiveTimeout(), and canTryReceiveI().

void can_lld_sleep ( CANDriver canp)

Enters the sleep mode.

Parameters
[in]canppointer to the CANDriver object
Function Class:Not an API, this function is for internal use only.

Definition at line 220 of file hal_can_lld.c.

Referenced by canSleep().

void can_lld_wakeup ( CANDriver canp)

Enforces leaving the sleep mode.

Parameters
[in]canppointer to the CANDriver object
Function Class:Not an API, this function is for internal use only.

Definition at line 233 of file hal_can_lld.c.

Referenced by canWakeup().

Variable Documentation

CANDriver CAND1

CAN1 driver identifier.

Definition at line 41 of file hal_can_lld.c.