CAN communication
Linux CAN communication
CAN communication is a very common bus communication method in robotics, vehicles, industrial control, and motor drives.
Compared to serial communication, CAN is better suited for multiple devices communicating on the same bus. For example, in a robot chassis, multiple motor drivers, a chassis control board, and sensor nodes may all be connected to the CAN bus.
In practical projects, CAN communication is common in:
- Control motor driver
- Read motor encoder feedback
- Connect the chassis control board
- Communication between multiple control nodes
- Vehicle bus communication
- Industrial equipment and motion control systems
For areas such as mobile robot chassis, motor control, and autonomous driving by-wire systems, CAN is a very important type of communication method.
What is CAN communication?
CAN, full name Controller Area Network, is a multi-master bus communication protocol.
Unlike serial point-to-point communication, multiple nodes can be connected to the CAN bus. Each node can send messages, and other nodes determine whether to process the message based on the CAN ID.
Common concepts in CAN communication include:
| concept | Explanation |
|---|---|
| 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 area | Classic CAN frame has at most 8 bytes of data. |
| CAN FD | An extended version of CAN that supports longer data fields and higher data rates. |
| baud rate | Common values include 250K, 500K, and 1M. |
| termination resistor | CAN bus typically requires 120Ω termination resistors at both ends. |
In Linux, CAN devices are usually not device files like /dev/ttyUSB0, but are abstracted into network interfaces, for example:
can0
You can view it with the following command:
ip link
Common CAN Tools and Libraries for Linux
The core of CAN communication on Linux is SocketCAN.
SocketCAN is a CAN communication framework provided by the Linux kernel. It abstracts CAN devices into a form similar to network interfaces, for example can0, can1.
Common tools and libraries include:
| solution | type | Features | Suitable scenarios |
|---|---|---|---|
| SocketCAN | Linux native CAN interface | Linux standard solution: universal, stable, and commonly used in engineering. | Recommended as a primary learning path |
| can-utils | SocketCAN command-line tool set | Provide tools such as candump, cansend, cangen, etc. | Debugging CAN Bus |
| libsocketcan | SocketCAN Helper Library | Easy to configure and manage the CAN interface | Use when configuring CAN parameters within the program. |
| ros2_socketcan | ROS 2 Wrapper Library | Integrating SocketCAN into the ROS 2 ecosystem | Pure ROS 2 project or reference implementation |
| ros2_canopen | ROS 2 CANopen protocol stack | Suitable for CANopen devices | When the motor driver uses the CANopen protocol, |
| vendor SDK | vendor-provided driver library | bound to specific hardware | When using specific USB-CAN, PCIe-CAN devices |
Comparison of Solutions
| solution | Advantages | Disadvantages |
|---|---|---|
| SocketCAN | Linux-native, general-purpose, stable, and ideal for long-term learning. | Need to understand socket programming and CAN frame structure. |
| can-utils | Easy debugging, simple commands. | Mainly used for command line testing, not a complete project package. |
| libsocketcan | Configuring the CAN interface is convenient. | Not the primary data communication solution. |
| ros2_socketcan | Convenient integration with the ROS 2 ecosystem | After leaving ROS 2, reusability is poor. |
| ros2_canopen | Suitable for CANopen devices, complete protocol stack. | Only suitable for CANopen scenarios, learning cost is relatively high. |
| vendor SDK | Good support for specific hardware | Poor generality, easily tied to a vendor. |
This tutorial recommends selecting
This tutorial recommends prioritizing:
SocketCAN + can-utils
The reason is:
- SocketCAN is the standard solution for CAN communication on Linux.
- Independent of ROS 2, suitable for regular C++, OpenCV, Qt, embedded Linux projects
can-utilsis very suitable for debugging and verifying CAN devices.- Later, it can be packaged as a standard 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 project structure is:
上层项目:ROS 2 / OpenCV / Qt / 普通 C++ 程序
↓
自己封装的 CanDriver 类
↓
SocketCAN
↓
can0
↓
电机驱动器 / STM32 / 底盘控制板
Relationship with ROS 2
Learning SocketCAN doesn't mean you don't need ROS 2.
In a ROS 2 project, you can encapsulate CAN communication as a regular C++ class, then use it in a ROS 2 node or 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 is not tightly coupled with ROS 2. Even when working on standard C++ projects, Qt host computer applications, or OpenCV control programs in the future, the same CAN driver can still be reused.
When to use ros2_socketcan
ros2_socketcan is not unusable.
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 learning low-level drivers and long-term engineering reuse, it is still recommended to first master SocketCAN.
It can be understood this way:
SocketCAN:底层能力
ros2_socketcan:ROS 2 封装
First learn SocketCAN, then it will be easier to understand ros2_socketcan.
When to use ros2_canopen
If your motor driver or industrial device uses the CANopen protocol, you can’t just treat it as ordinary CAN frame communication.
CANopen is a high-level protocol built on top of CAN, involving concepts such as object dictionary, PDO, SDO, NMT, etc.
In this case, consider learning:
ros2_canopen
But if your device only uses a custom CAN protocol, such as defining your own CAN IDs and data formats, then prioritizing learning SocketCAN is sufficient.
Chapter learning objectives
After completing this chapter, you should be able to:
- Basic concepts of CAN communication
- How to use the
can0device on Linux - Configure CAN baud rate using
ip link - Use
candumpandcansendto debug the CAN bus - Understand concepts such as CAN ID, standard frame, extended frame, data field, etc.
- Sending and Receiving CAN Frames Using C++ SocketCAN
- Encapsulate CAN communication into reusable C++ classes
- Lay the foundation for subsequent integration with ROS 2, ros2_control, and motor driver control.