Last edited 11 months ago

How to send or receive CAN data

Applicable for STM32MP13x lines, STM32MP15x lines, STM32MP25x lines

1. Purpose[edit source]

This article describes how to send/receive data on a SocketCAN interface using the can-utils[1] package.

The can-utils contains some userspace utilities for Linux® SocketCAN subsystem. It is integrated in the SDK for the STM32 microprocessor series. Only cansend and candump are used in this example, but many other tools are available in the package.

2. Prerequisite[edit source]

At least two nodes are required to communicate on a CAN network. To implement such configuration, connect two boards on the same CAN bus. Then, send data from one node, and receive data on the other node.

Prior to starting communications, the SocketCAN interface has to be configured and enabled on each board. See How to set up a SocketCAN interface.

3. Sending data on the CAN bus[edit source]

To send a single frame, use the cansend utility:

 cansend can0 123#1122334455667788

To print help on cansend utility:

 cansend -h
Usage: cansend <device> <can_frame>

If you get frame error, try:

    <can_id>#{R|data}          for CAN 2.0 frames
    <can_id>##<flags>{data}    for CAN FD frames

<can_id> can have 3 (SFF) or 8 (EFF) hex chars
{data} has 0..8 (0..64 CAN FD) ASCII hex-values (optionally separated by '.')
<flags> a single ASCII Hex value (0 .. F) which defines canfd_frame.flags

e.g. 5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / 123##1 / 213##311
     1F334455#1122334455667788 / 123#R for remote transmission request.

4. Receiving data on the CAN bus[edit source]

To display in real-time the list of messages received on the bus, use the candump utility:

 candump can0
can0  123   [8] 11 22 33 44 55 66 77 88

To print help on candump utility:

 candump -h

Usage: candump [options] <CAN interface>+
   (use CTRL-C to terminate candump)

Options: -t <type>   (timestamp: (a)bsolute/(d)elta/(z)ero/(A)bsolute w date)
         -c          (increment color mode level)
         -i          (binary output - may exceed 80 chars/line)
         -a          (enable additional ASCII output)
         -S          (swap byte order in printed CAN data[] - marked with '`' )
         -s <level>  (silent mode - 0: off (default) 1: animation 2: silent)
         -b <can>    (bridge mode - send received frames to <can>)
         -B <can>    (bridge mode - like '-b' with disabled loopback)
         -u <usecs>  (delay bridge forwarding by <usecs> microseconds)
         -l          (log CAN-frames into file. Sets '-s 2' by default)
         -L          (use log file format on stdout)
         -n <count>  (terminate after receiption of <count> CAN frames)
         -r <size>   (set socket receive buffer to <size>)
         -D          (Don't exit if a "detected" can device goes down.
         -d          (monitor dropped CAN frames)
         -e          (dump CAN error frames in human-readable format)
         -x          (print extra message infos, rx/tx brs esi)
         -T <msecs>  (terminate after <msecs> without any reception)

Up to 16 CAN interfaces with optional filter sets can be specified on the commandline in the form: <ifname>[,filter]*

Comma separated filters can be specified for each given CAN interface:
 <can_id>:<can_mask> (matches when <received_can_id> & mask == can_id & mask)
 <can_id>~<can_mask> (matches when <received_can_id> & mask != can_id & mask)
 #<error_mask>       (set error frame filter, see include/linux/can/error.h)
 [j|J]               (join the given CAN filters - logical AND semantic)

CAN IDs, masks and data content are given and expected in hexadecimal values.
When can_id and can_mask are both 8 digits, they are assumed to be 29 bit EFF.
Without any given filter all data frames are received ('0:0' default filter).

Use interface name 'any' to receive from all CAN interfaces.

Examples:
candump -c -c -ta can0,123:7FF,400:700,#000000FF can2,400~7F0 can3 can8
candump -l any,0~0,#FFFFFFFF    (log only error frames but no(!) data frames)
candump -l any,0:0,#FFFFFFFF    (log error frames and also all data frames)
candump vcan2,92345678:DFFFFFFF (match only for extended CAN ID 12345678)
candump vcan2,123:7FF (matches CAN ID 123 - including EFF and RTR frames)
candump vcan2,123:C00007FF (matches CAN ID 123 - only SFF and non-RTR frames)

5. Hardware self-test[edit source]

In internal Loopback test mode, the FDCAN handles the messages it transmitted as received messages. This option is used for harware self-test (no need to connect an external CAN node on the CAN bus).

To configure and enable the SocketCAN in Loopback mode, proceed as follows:

 ip link set can0 up type can bitrate 1000000 dbitrate 2000000 fd on loopback on
[ 78.700698] m_can 4400e000.can can0: bitrate error 0.3%
[ 78.704568] m_can 4400e000.can can0: bitrate error 1.6%
[ 78.710140] IPv6: ADDRCONF(NETDEV_CHANGE): can0: link becomes ready

To send and receive messages on the same interface, proceed as follows:

 candump can0 -L &
[1] 475
 cansend can0 300#AC.AB.AD.AE.75.49.AD.D1
(1539944874.949723) can0 300#ACABADAE7549ADD1
(1539944874.949683) can0 300#ACABADAE7549ADD1

6. References[edit source]

  1. CAN-UTILS information, README on github.com