Skip to content

Wiki

CAN communication

About 11 min read

Existing English translations were reused. 2 current source blocks remain in Simplified Chinese, without triggering paid translation.

1.Linux CAN Communication

CAN communication is a very common bus communication method in robots, vehicles, industrial control, and motor drives.

Compared with serial communication, CAN is more suitable for communication in which multiple devices are connected to the same bus. For example, in a robot chassis, multiple motor drivers, chassis control boards, and sensor nodes may all be connected to the CAN bus.

In actual projects, CAN communication is commonly seen in:

  • Control motor driver
  • Read motor encoder feedback
  • Connect chassis control board
  • Communication between multiple control nodes
  • Vehicle bus communication
  • Industrial equipment and motion control systems

For fields such as mobile robot chassis, motor control, and autonomous driving drive-by-wire systems, CAN is a very important type of communication method.

1.1.What is CAN communication

CAN, whose full name is Controller Area Network, is a multi-master bus communication protocol.

Unlike point-to-point serial communication, multiple nodes can be connected to a CAN bus. Each node can send messages, and other nodes determine whether they need to process a given message based on the CAN ID.

Common concepts in CAN communication include:

Concept Description
CAN ID Used to identify the meaning or source of a CAN message frame
Standard frame 11-bit CAN ID
Extended frame 29-bit CAN ID
Data field A classic CAN frame carries at most 8 bytes of data
CAN FD An extended version of CAN that supports a longer data field and higher data rates
Baud rate Common values are 250K, 500K, 1M
Terminating resistor Both ends of a CAN bus usually require a 120Ω terminating resistor

In Linux, CAN devices are usually not represented as /dev/ttyUSB0 device files, but are abstracted as network interfaces, for example:

can0

You can view it using the following command:

ip link

1.2.Common CAN tools and libraries on Linux

The core of CAN communication under Linux is SocketCAN.

SocketCAN is a CAN communication framework provided by the Linux kernel, which abstracts CAN devices into a form similar to network interfaces, such as can0 and can1.

Common tools and libraries include:

Solution Type Features Suitable Scenarios
SocketCAN Linux native CAN interface Linux standard solution, general-purpose, stable, commonly used in engineering Recommended as the main learning path
can-utils SocketCAN command-line toolset Provides candump, cansend and cangen tools Debugging CAN bus
libsocketcan SocketCAN auxiliary library Facilitates configuration and management of CAN interfaces Use when CAN parameters need to be configured within a program
ros2_socketcan ROS 2 wrapper library Wraps SocketCAN into the ROS 2 ecosystem Pure ROS 2 projects or reference implementations
ros2_canopen ROS 2 CANopen protocol stack Suitable for CANopen devices When motor drivers use the CANopen protocol
Vendor SDK Vendor-provided driver library Bound to specific hardware When using specific USB-CAN, PCIe-CAN devices

1.3.Comparison of Schemes

Solution Advantages Disadvantages
SocketCAN Native to Linux, general-purpose, stable, suitable for long-term learning Requires understanding of socket programming and CAN frame structure
can-utils Convenient for debugging, simple commands Mainly used for command-line testing, not a complete engineering wrapper
libsocketcan Convenient for configuring CAN interfaces Not the primary solution for data transmission and reception
ros2_socketcan Convenient integration with the ROS 2 ecosystem Poor reusability when separated from ROS 2
ros2_canopen Suitable for CANopen devices, complete protocol stack Only suitable for CANopen scenarios, relatively high learning cost
Vendor SDK Good support for specific hardware Poor generality, prone to vendor lock-in

1.4.This tutorial recommends selecting

This tutorial recommends prioritizing:

SocketCAN + can-utils

The reason is:

  • SocketCAN is the standard solution for CAN communication under Linux
  • Does not depend on ROS 2, suitable for ordinary C++, OpenCV, Qt, and embedded Linux projects
  • can-utils Very suitable for debugging and verifying CAN devices
  • Can later be encapsulated into an ordinary C++ driver
  • Can naturally integrate with ros2_control hardware_interface

The recommended learning order is:

1. 使用 ip link 配置 can0
2. 使用 candump 接收 CAN 帧
3. 使用 cansend 发送 CAN 帧
4. 理解 struct can_frame
5. 使用 C++ SocketCAN 进行收发
6. 封装自己的 CanDriver 类
7. 接入 ROS 2 或 ros2_control

The recommended engineering structure is:

上层项目:ROS 2 / OpenCV / Qt / 普通 C++ 程序
        ↓
自己封装的 CanDriver 类
        ↓
SocketCAN
        ↓
can0
        ↓
电机驱动器 / STM32 / 底盘控制板

1.5.Relationship with ROS 2

Learning SocketCAN does not mean that ROS 2 is not used.

在 ROS 2 项目中,可以将 CAN 通信封装成一个普通 C++ 类,然后在 ROS 2 节点或 ros2_control hardware_interface 中调用。

For example:

ros2_control controller
        ↓
hardware_interface
        ↓
自己封装的 CanDriver
        ↓
SocketCAN
        ↓
can0
        ↓
电机驱动器

The advantage of this approach is that the CAN communication code will not be strongly bound to ROS 2. In the future, even when writing ordinary C++ projects, Qt host computer applications, or OpenCV control programs, the same CAN driver can continue to be reused.

1.6.When to use ros2_socketcan

ros2_socketcan It is not that it cannot be used.

If the project itself is a pure ROS 2 architecture and you want to quickly convert CAN frames into ROS 2 topics, then ros2_socketcan is an option worth considering.

However, for low-level driver learning and long-term engineering reuse, it is still recommended to first master SocketCAN.

It can be understood as follows:

SocketCAN:底层能力
ros2_socketcan:ROS 2 封装

Learn SocketCAN first, then look at ros2_socketcan and it will be easier to understand.

1.7.When should ros2_canopen be used?

If your motor drive or industrial equipment uses the CANopen protocol, then it cannot be treated merely as ordinary CAN frame communication.

CANopen is a high-level protocol built on top of CAN, involving concepts such as the object dictionary, PDO, SDO, and NMT.

In this case, you can consider learning:

ros2_canopen

However, if your device only uses a custom CAN protocol, for example, you define your own CAN ID and data format, then it is sufficient to prioritize learning SocketCAN.

1.8.Chapter Learning Objectives

After completing this chapter, you should be able to master:

  • CAN 通信的基本概念
  • Linux 下 can0 设备的使用方式
  • 使用 ip link 配置 CAN 波特率
  • 使用 candump、cansend 调试 CAN 总线
  • 理解 CAN ID、标准帧、扩展帧、数据区等概念
  • 使用 C++ SocketCAN 进行 CAN 帧收发
  • 将 CAN 通信封装成可复用的 C++ 类
  • 为后续接入 ROS 2、ros2_control、电机驱动器控制打基础