SocketCAN is a set of open source CAN drivers and a networking stack contributed by Volkswagen Research to the Linux kernel. SocketCAN was formerly known as Low Level CAN Framework (LLCF).
CAN-utils is a collection of extremely useful debugging tools using the SocketCAN interface. It includes applications such as:
- candump – Dump can packets – display, filter and log can messages.
- canplayer – Replay CAN log files.
- cansend – Send a single frame.
- cangen – Generate random traffic.
- canbusload – Display the current CAN bus utilization.
- ISO-TP – Tools for multiple frame transport protocol (ISO 157650-2)
Installing can-utils and connect your can bus analizer
$ paru -S can-utils
make sure your module is recognized by linux: down below you can se is detected as can0
$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp9s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether b4:2e:99:36:99:64 brd ff:ff:ff:ff:ff:ff
4: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
link/can
5: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
link/ether 20:79:18:e2:c7:e6 brd ff:ff:ff:ff:ff:ff
Set the can baud-rate and enable the can0 interface. you will need to type this line every time after a reset (PC or board)
$ sudo ip link set can0 up type can bitrate 100000
We need to use candump to read any message from CAN, to get the candump help, just type: ( we can see how to invoke its built in help to review all the options )
$ candump -h
candump - dump CAN bus traffic.
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)
-H (read hardware timestamps instead of system timestamps)
-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)
-l (log CAN-frames into file. Sets '-s 2' by default)
-L (use log file format on stdout)
-n <count> (terminate after reception 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)
-8 (display raw DLC values in {} for Classical CAN)
-x (print extra message infos, rx/tx brs esi)
-T <msecs> (terminate after <msecs> if no frames were received)
Up to 16 CAN interfaces with optional filter sets can be specified
:
:
For instance to read any number of message indefinitely from any can device. To stop press Ctrl+c
$ candump any
can0 1EF [8] 79 31 20 57 4F 52 4C 44
can0 1EF [8] 7A 31 20 57 4F 52 4C 44
can0 1EF [8] 7B 31 20 57 4F 52 4C 44
can0 1EF [8] 7C 31 20 57 4F 52 4C 44
can0 1EF [8] 7D 31 20 57 4F 52 4C 44
can0 1EF [8] 7E 31 20 57 4F 52 4C 44
can0 1EF [8] 7F 31 20 57 4F 52 4C 44
can0 1EF [8] 80 31 20 57 4F 52 4C 44
can0 1EF [8] 81 31 20 57 4F 52 4C 44
^C
If we want to see the timestamp (-t) and only receive 10 messages from can0 device
$ candump -ta -n10 can0
(1677098592.958334) can0 1EF [8] 64 31 20 57 4F 52 4C 44
(1677098593.456790) can0 1EF [8] 65 31 20 57 4F 52 4C 44
(1677098593.955256) can0 1EF [8] 66 31 20 57 4F 52 4C 44
(1677098594.453793) can0 1EF [8] 67 31 20 57 4F 52 4C 44
(1677098594.952320) can0 1EF [8] 68 31 20 57 4F 52 4C 44
(1677098595.450782) can0 1EF [8] 69 31 20 57 4F 52 4C 44
(1677098595.949239) can0 1EF [8] 6A 31 20 57 4F 52 4C 44
(1677098596.447688) can0 1EF [8] 6B 31 20 57 4F 52 4C 44
(1677098596.946203) can0 1EF [8] 6C 31 20 57 4F 52 4C 44
(1677098597.444679) can0 1EF [8] 6D 31 20 57 4F 52 4C 44
And if we want to send messages we can use cansend
$ cansend -h
cansend - send CAN-frames via CAN_RAW sockets.
Usage: cansend <device> <can_frame>.
<can_frame>:
<can_id>#{data} for Classical CAN 2.0 data frames
<can_id>#R{len} for Classical CAN 2.0 data frames
<can_id>#{data}_{dlc} for Classical CAN 2.0 data frames
<can_id>#R{len}_{dlc} for Classical CAN 2.0 data frames
<can_id>##<flags>{data} for CAN FD frames
<can_id>:
3 (SFF) or 8 (EFF) hex chars
{data}:
0..8 (0..64 CAN FD) ASCII hex-values (optionally separated by '.')
{len}:
an optional 0..8 value as RTR frames can contain a valid dlc field
_{dlc}:
an optional 9..F data length code value when payload length is 8
<flags>:
a single ASCII Hex value (0 .. F) which defines canfd_frame.flags
Examples:
5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / 123##1 / 213##311223344 /
1F334455#1122334455667788_B / 123#R / 00000123#R3 / 333#R8_E
For instance to send 8 bytes with an standard Id of 123 to can0 we type
$ cansend can0 123#02.00.00.2E.00.10.FF.AA
For some reason some terminals will interpretare the # between the 123 and the 02 as a wildcard, to tell the shell is not ta wildcard we ca use de \ after the #, just like this: $ cansend can0 123\#02.00.00.2E.00.10.FF.AA
OK, candump what does is to monitor the CAN bus, and it means we can also read the messages we send, to do that we gonna need two terminals, on the right we use cansend to send the message and on the left we use candump, where we can see the messages received plus the message we send (with an ID of 123)
$ candump -ta -n10 can0
(1677099002.174714) can0 1EF [8] 99 31 20 57 4F 52 4C 44
(1677099002.673197) can0 1EF [8] 9A 31 20 57 4F 52 4C 44
(1677099002.891804) can0 123 [8] 02 00 00 2E 00 10 FF AA
(1677099003.171799) can0 1EF [8] 9B 31 20 57 4F 52 4C 44
(1677099003.670155) can0 1EF [8] 9C 31 20 57 4F 52 4C 44
(1677099004.168639) can0 1EF [8] 9D 31 20 57 4F 52 4C 44
(1677099004.667019) can0 1EF [8] 9E 31 20 57 4F 52 4C 44
(1677099005.165498) can0 1EF [8] 9F 31 20 57 4F 52 4C 44
(1677099005.663911) can0 1EF [8] A0 31 20 57 4F 52 4C 44
(1677099006.162343) can0 1EF [8] A1 31 20 57 4F 52 4C 44
$ cansend can0 123#02.00.00.2E.00.10.FF.AA
typing messages in the terminal can be very tire an unacceptable for a software engineer, luckily we can automate this process, just write the messages in the file canmsgs.sh
echo "sending message 123#02.00.00.2E.00.10.FF.AA to can0"
cansend can0 123#02.00.00.2E.00.10.FF.AA
echo "sending message 123#02.00.00.2E.00.10.FF.AA to can0"
cansend can0 123#04.00.00.2E.00.10.FF.AA
echo "sending message 123#02.00.00.2E.00.10.FF.AA to can0"
cansend can0 123#06.00.00.2E.00.10.FF.AA
In the terminal type candump to see the messages
$ candump -ta -n10 can0
(1677099571.338581) can0 1EF [8] 0F 31 20 57 4F 52 4C 44
(1677099571.836836) can0 1EF [8] 10 31 20 57 4F 52 4C 44
(1677099572.335184) can0 1EF [8] 11 31 20 57 4F 52 4C 44
(1677099572.816924) can0 123 [8] 02 00 00 2E 00 10 FF AA
(1677099572.818499) can0 123 [8] 04 00 00 2E 00 10 FF AA
(1677099572.819798) can0 123 [8] 06 00 00 2E 00 10 FF AA
(1677099572.833527) can0 1EF [8] 12 31 20 57 4F 52 4C 44
(1677099573.331809) can0 1EF [8] 13 31 20 57 4F 52 4C 44
(1677099573.830165) can0 1EF [8] 14 31 20 57 4F 52 4C 44
(1677099574.328488) can0 1EF [8] 15 31 20 57 4F 52 4C 44
and then run the script
$ sh canmsgs.sh
sending message 123#02.00.00.2E.00.10.FF.AA to can0
sending message 123#02.00.00.2E.00.10.FF.AA to can0
sending message 123#02.00.00.2E.00.10.FF.AA to can0
But maybe you don’t want to send messages one after the other, maybe you want to wait at least 500ms between messages
echo "sending message 123#02.00.00.2E.00.10.FF.AA to can0"
cansend can0 123#02.00.00.2E.00.10.FF.AA
sleep 0.5s
echo "sending message 123#02.00.00.2E.00.10.FF.AA to can0"
cansend can0 123#04.00.00.2E.00.10.FF.AA
sleep 0.5s
echo "sending message 123#02.00.00.2E.00.10.FF.AA to can0"
cansend can0 123#06.00.00.2E.00.10.FF.AA
candump
$ candump -ta -n10 can0
(1677099897.269672) can0 1EF [8] 9D 31 20 57 4F 52 4C 44
(1677099897.768087) can0 1EF [8] 9E 31 20 57 4F 52 4C 44
(1677099897.927801) can0 123 [8] 02 00 00 2E 00 10 FF AA
(1677099898.266489) can0 1EF [8] 9F 31 20 57 4F 52 4C 44
(1677099898.431006) can0 123 [8] 04 00 00 2E 00 10 FF AA
(1677099898.764865) can0 1EF [8] A0 31 20 57 4F 52 4C 44
(1677099898.933689) can0 123 [8] 06 00 00 2E 00 10 FF AA
(1677099899.263270) can0 1EF [8] A1 31 20 57 4F 52 4C 44
(1677099899.761644) can0 1EF [8] A2 31 20 57 4F 52 4C 44
(1677099900.259944) can0 1EF [8] A3 31 20 57 4F 52 4C 44
script
$ sh canmsgs.sh
sending message 123#02.00.00.2E.00.10.FF.AA to can0
sending message 123#02.00.00.2E.00.10.FF.AA to can0
sending message 123#02.00.00.2E.00.10.FF.AA to can0
hey i got an idea!!, lets send up to three different messages when we press up to three different keys each of them assigned to an specific one. try the code down below and tell me what do you think.
echo "Welcome, press 1, 2 or 3 to send message or Ctrl+c to quit the program"
echo " 1 to send: 111#02.00.00.2E.00.10.FF.AA"
echo " 2 to send: 122#04.00.00.2E.00.10.FF.AA"
echo " 3 to send: 133#06.00.00.2E.00.10.FF.AA"
while [ true ]
do
#capture key
read -n 1 KEY
if [ $KEY == '1' ]; then
echo " sending message 111#02.00.00.2E.00.10.FF.AA to can0"
cansend can0 111#02.00.00.2E.00.10.FF.AA
elif [ $KEY == '2' ]; then
echo " sending message 122#02.00.00.2E.00.10.FF.AA to can0"
cansend can0 122#04.00.00.2E.00.10.FF.AA
elif [ $KEY == '3' ]; then
echo " sending message 133#02.00.00.2E.00.10.FF.AA to can0"
cansend can0 133#06.00.00.2E.00.10.FF.AA
else
echo " Invalid input, press 1,2 or 3"
fi
done
What we just did it was a sort of automation using bash scripting. One of the things I love about using the terminal is that we can automated anything with bash scripts, ANYTHING!!!!, if you want to know more go ahead and take a look at some good tutorials about how to bash script