Wiki
CAN communication
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-utilsVery 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、电机驱动器控制打基础