User documentation
The cpp2can
module defines an abstraction layer for CAN,
enabling higher-level libraries or applications to use CAN
independent of hardware-specific implementation details.
Using CAN transceivers
For each CAN transceiver,
a concrete implementation of the can::AbstractCANTransceiver
class is instantiated.
While each concrete implementation will have its own configuration to set up,
from the viewpoint of cpp2can
the only configuration needed is that each CAN transceiver
is assigned a unique Bus ID which is passed to the can::AbstractCANTransceiver
constructor.
Once instantiated, higher-level libraries or applications use the can::ICANTransceiver
interface
to perform operations such as…
Control the CAN transceiver’s state
Send frames to the CAN bus as
can::CANFrame
objects usingwrite()
Listen for CAN frames received or sent, filtered in various ways (this is described in more detail below).
Example
The following example initializes and opens the interface, then sends a CAN frame to the bus:
void doSomethingWithCAN(can::ICanTransceiver* transceiver)
{
static const uint8_t msg[] = {0, 1, 2};
if (transceiver->init() != can::ICanTransceiver::ErrorCode::CAN_ERR_OK)
{
return;
}
if (transceiver->open() != can::ICanTransceiver::ErrorCode::CAN_ERR_OK)
{
return;
}
can::CANFrame myFrame;
myFrame.setId(42);
myFrame.setPayload(msg, 3);
transceiver->write(myFrame);
}
ICANTransceiver
states
The state diagram below shows the transitions that transceivers implementing ICANTransceiver
follow.
The method getState()
returns the current state.
Note that write()
is not allowed in the CLOSED
or MUTED
states.
The different states allow or block CAN Rx/Tx as shown in the table below.
State |
Receive |
Transmit |
---|---|---|
CLOSED |
No |
No |
INITIALIZED |
No |
Yes |
OPEN |
Yes |
Yes |
MUTED |
Yes |
No |
Representing CAN frames
CAN Frames are represented using the can::CANFrame
class.
A CAN Frame is composed of:
CAN ID - Both the standard 11-bit identifier format and the extended 29-bit identifier format are supported.
can::CanId
is a helper class to assist in forming and identifying CAN IDs.Data payload - The standard maximum payload length is 8 bytes, but this can be set to 64 bytes, as introduced by CAN FD, by compiling with the preprocessor define
CPP2CAN_USE_64_BYTE_FRAMES
.Timestamp - This is expected to be set by the transceiver on receive or send.
Example
In the example below, two CAN Frames are created. One with a standard 11-bit ID, and the other with a 29-bit extended ID.
static const uint8_t canData[] = {0, 1, 2, 3, 4, 5, 6, 7};
::can::CANFrame standardIdFrame(0x558, canData, 8);
::can::CANFrame extendedIdFrame(can::CanId::Extended<0x17002345>::value, canData, 8);
CAN listeners and filters
The can::ICANTransceiver
interface supports adding and removing listeners for…
CAN frames sent
CAN frames received
State changes in the CAN transceiver
can::ICANFrameSentListener
An object implementing can::ICANFrameSentListener
can be passed to the overloaded method can::ICanTransceiver::write()
to provide a callback method which will be called when the CAN Frame is transmitted.
can::ICANFrameListener
An object implementing can::ICANFrameListener
provides a callback
for received CAN Frames that match its filter.
These can be added to (or removed from) a list of such objects maintained by the transceiver
by calling the following methods of can::ICanTransceiver
.
Each can::ICANFrameListener
object must be configured with a filter before being added to the list.
Method |
Description |
---|---|
|
Add |
|
Add |
|
Remove |
can::IFilteredCANFrameSentListener
An object implementing can::IFilteredCANFrameSentListener
provides a callback
for transmitted CAN Frames that match its filter.
These can be added to (or removed from) a list of such objects maintained by the transceiver
by calling the following methods of can::ICanTransceiver
.
Each can::IFilteredCANFrameSentListener
object must be configured with a filter before being added to the list.
Method |
Description |
---|---|
|
Add |
|
Remove |
can::ICANTransceiverStateListener
Only one can::ICANTransceiverStateListener
object is supported by each can::ICanTransceiver
object.
Method |
Description |
---|---|
|
Set |
|
Unset the CAN transceiver state listener |
CAN Filters
Two of the listener interfaces use can::IFilter
for filtering CAN frames:
can::ICANFrameListener
is used to capture CAN frames received by the transceiver that match its filter.can::IFilteredCANFrameSentListener
is used to capture CAN frames sent by the transceiver that match its filter.
can::IntervalFilter
A can::IntervalFilter
is used to specify a continuous range of CAN IDs to match in a listener.
can::AbstractStaticBitFieldFilter
A can::AbstractStaticBitFieldFilter
is used to specify a selection of CAN IDs as a static bitfield to match in a listener.
can::BitFieldFilter
A can::BitFieldFilter
is used to specify a selection of CAN IDs as a dynamic bitfield to match in a listener.
Example
Below is an example of setting up a listener for CAN frames received
with CAN IDs in the range 0x300
to 0x400
using ::can::BitFieldFilter
.
class ExampleCanListener : public ::can::ICANFrameListener
{
public:
ExampleCanListener() : _canFilter() { _canFilter.add(0x300, 0x400); }
::can::IFilter& getFilter() { return _canFilter; }
void frameReceived(::can::CANFrame const& frame);
private:
::can::BitFieldFilter _canFilter;
};
void ExampleCanListener::frameReceived(::can::CANFrame const& frame)
{
/*
This is called when a CAN Frame in the range 0x300 to 0x400 is received.
An action can be added here.
*/
return;
}
/* Set up listener */
ExampleCanListener exListener;
transceiver->addCANFrameListener(exListener);