Cover image for Linux CAN

Linux CAN

Words 16k
Views
Visitors

Timeline

Timeline

2026-01-09

init

This article introduces the CAN bus related content in the Linux driver notes, including the basic concepts, core features, application areas, development history, and hardware connection methods of the CAN protocol. CAN (Controller Area Network) is a serial communication protocol introduced by Bosch in 1986, designed for automotive electronic systems. It supports multi-master communication and a non-destructive arbitration mechanism, offering high reliability and low cost, and is widely used in automotive electronics, industrial automation, medical equipment, and other fields. The article also reviews the development history of the CAN protocol from the start of research in 1983 to the standardization of CAN FD and CAN XL. In terms of hardware connections, this article discusses two typical scenarios: when the CPU has a built-in CAN controller, it connects directly to the CAN bus through the CAN controller and CAN transceiver, and explains the CAN Tx/Rx signal lines, CAN_H/CAN_the function of the L differential signal line and the 120Ω termination resistor; when the CPU does not have a CAN controller, it communicates with the CAN bus by connecting an SPI-to-CAN converter through the SPI controller. The article describes the functions of each component in detail through tables, providing a reference for CAN in Linux driver development

Linux Driver Notes

Table of ContentsLinks
1. Linux Driver Framework
2. Linux Driver Loading Logic
3. Character Device Basics
4. Concurrency and Race Conditions
5. Advanced Character Device Topics
6. Interrupts
7. Platform Bus
8. Device Tree
9. Device Model
10. Hotplug
11. pinctrl Subsystem
12. GPIO subsystem
13. Input subsystem
14. 1-Wire
15. I2C
16. SPI
17. UART
18. PWM
19. RTC
20. Watchdog
21. CAN
22. Network devices
23. ADC
24. IIO
25. USB
26. LCD

CAN Bus Introduction

CAN(Controller Area Network) is a serial communication protocol introduced by Bosch in 1986, designed specifically for automotive electronic systems to reduce the number of wiring harnesses in vehicles and enable efficient communication among multiple electronic control units (ECUs).

Core Features

  • The CAN bus supports multi-master communication; all nodes (ECUs) can actively transmit data without relying on a central controller.
  • It uses a non-destructive arbitration mechanism to resolve bus conflicts via ID priority, ensuring that high-priority data is transmitted first.
  • The bus offers high reliability with built-in CRC checks, error detection and recovery mechanisms, and uses differential signaling to enhance resistance to electromagnetic interference.
  • The CAN bus achieves low-cost advantages by simplifying wiring and reducing system complexity.

Application Areas

  • Automotive electronics: engine control, body modules (lights/windows), diagnostic systems (OBD-II), etc.
  • Industrial automation: PLCs, sensor networks, robot control.
  • Other fields: medical devices, aerospace, smart buildings.

Development History

  • 1983: Bosch initiates research on automotive network technology.
  • 1986: CAN protocol officially released.
  • 1987: Intel and Philips launch the first CAN controller chips.
  • 1991: CAN 2.0 specification released, first applied in the Mercedes-Benz S-Class.
  • 1993: Became an international standard (ISO 11898).
  • 2015: CAN FD (Flexible Data Rate) standardized (supports higher data rates and 64-byte data).
  • 2020: Next-generation CAN XL released, with further increased bandwidth.

CAN Hardware Connection

In CAN hardware connections, there are two scenarios: the CPU has a built-in CAN controller, or the CPU lacks a CAN controller and requires an external adapter (such as SPI-to-CAN).

CPU with Built-in CAN Controller

The connection diagram for a CPU with a built-in CAN controller is shown below. The CPU communicates directly with the CAN transceiver through the integrated CAN controller. The CAN transceiver is responsible for converting digital signals into differential signals suitable for CAN bus transmission (CAN_H and CAN_L)。The CPU can directly communicate with the CAN bus.

The CPU has a built-in CAN controller.
The CPU has a built-in CAN controller.

ComponentDescription
CPU and CAN controllerEach CPU communicates with the CAN bus through a CAN controller. The CPU is responsible for processing control logic and data processing tasks, while the CAN controller is responsible for managing the communication details of the CAN protocol.
CAN TxSignal line for sending data. The CPU sends data to the CAN bus through the CAN controller, and this signal line is used to transmit the data being sent.
CAN RxSignal line for receiving data. The CPU receives data from the CAN bus through the CAN controller, and this signal line is used to receive data from the bus.
CAN transceiverThe CAN transceiver is connected between the CPU’s CAN controller and the CAN bus. Its main functions are:
Converting the digital signals output by the CPU into differential level signals suitable for transmission on the CAN bus (level conversion);
At the same time, it converts the differential signals on the bus back into digital signals that the CPU can recognize.
CAN H and CAN LThese are the two main physical signal lines of the CAN bus:
CAN H: used to transmit high-level signals;
CAN L: used to transmit low-level signals.
Data transmission is achieved through the voltage difference between these two lines (differential signal), which improves anti-interference capability.
120Ω resistorA 120Ω terminating resistor is connected at each end of the CAN bus to: • Prevent signal reflection at the bus ends (impedance matching); • Ensure signal integrity and improve communication stability. These terminating resistors are especially important in long-distance or multi-device connections.

CPU without a CAN controller

The connection diagram for a CPU without a CAN controller is shown below,The CPU communicates with an SPI-to-CAN module through the SPI controller, which converts SPI data into the format required by the CAN bus.

With this structure, the CPU can communicate with the CAN bus through the SPI protocol, making it suitable for application scenarios where it is necessary to connect to a CAN network without a direct CAN controller. The terminating resistors at both ends of the bus ensure the stability of CAN communication.

The CPU has no internal CAN controller.
The CPU has no internal CAN controller.

ComponentDescription
CPU and SPI ControllerThe CPU communicates with SPI-interface peripherals through the SPI controller. SPI (Serial Peripheral Interface) is a synchronous serial communication protocol commonly used for high-speed data exchange between microcontrollers and peripherals such as sensors and memories.
SPI to CAN ConverterThis is a key bridge module connected between the SPI controller and the CAN bus. Its function is to convert the data format of the SPI protocol into the CAN protocol format, allowing devices that originally could only use SPI communication to communicate with other nodes via the CAN bus.
CAN TxSignal line for transmitting data, used to send data received from the SPI-to-CAN module to the CAN bus.
CAN RxSignal line for receiving data, used to receive data from the CAN bus and transmit it to the SPI-to-CAN module for processing.
CAN transceiverConnected between the CAN bus and the SPI-to-CAN module, it is responsible for:
Converting logic-level signals (from the converter) into differential signals suitable for CAN bus transmission;
At the same time, it restores the differential signals on the bus to logic-level signals and sends them back to the module.
CAN H and CAN LThe two differential signal lines of the CAN bus:
CAN H: high-level signal line;
CAN L: low-level signal line. Data is transmitted through the voltage difference between the two, providing strong anti-interference capability.
120Ω resistorA 120Ω termination resistor is connected at each end of the CAN bus, with the purpose of:
Impedance matching to prevent signal reflection;
Improving communication stability, especially in long-distance or multi-node connections.

CAN Electrical Properties

The CAN bus uses differential signals to transmit data.

  1. CAN Signal Levels

The CAN bus uses two signal lines for data transmission: CAN_H (high level) and CAN_L (low level).

CAN_H and CAN_The voltage difference between L determines the state of the logic signal. This gives the CAN bus better anti-interference capability, making it especially suitable for working in noisy environments.

  • CAN_H: High-level signal line, typically with a voltage range of 2.5V to 3.5V.
  • CAN_L: Low-level signal line, typically with a voltage range of 1.5V to 2.5V.
  1. Differential signal and anti-interference

The CAN bus transmits data through differential signals, which means the transmission of information depends on CAN_H and CAN_The voltage difference between L, rather than a single voltage value. The characteristics of differential signals give the CAN bus extremely strong anti-interference capability in noisy environments.

Advantages of differential signals

  1. Noise usually affects both CAN_H and CAN_L, but because differential signals depend on the voltage difference between the two,The effects of noise on both cancel each other out, thereby maintaining signal integrity.
  2. This characteristic makes the CAN bus perform excellently in noisy environments such as automobiles and industrial control.

Electrical properties and working states

The electrical properties of the CAN bus determine its working state, specifically manifested as recessive and dominant states.

  • Recessive state (logic “1”)when CAN_H and CAN_L have equal voltages(typically 2.5V), indicatingthe bus is in an idle state. At this time, the bus has no data transmission, and all devices are waiting for communication. The recessive state is also called “idle level” or “logic 1”.
  • Dominant state (logic “0”)when CAN_H and CAN_L the voltage difference is 2V when, indicatingdata is being transmitted. Specifically, CAN_H is 3.5V, CAN_L is 1.5V, indicating logic ‘0’. The dominant state indicates that the bus is transmitting data, andhas a higher priority

Recessive level and dominant level
Recessive level and dominant level

iTOP-RK3568 development board CAN interface

The RK3568 SoC can use up to 3 CAN interfaces

CAN1
CAN1

where TJA1040T It is a high-speed CAN transceiver chip produced by NXP, responsible for converting the CPU’s digital signals into signals suitable for CAN bus transmission and receiving data from the bus. According to the net labels, the development board uses CAN1.

CAN interfacepinctrl functionNet labelCorresponding GPIOFunction
CAN0CAN0_TX_M0I2C1_SCL_TPGPIO0_B3_uMIPI screen touch I2C
CAN0_RX_M0I2C1_SDA_TPGPIO0_B4_uMIPI screen touch I2C
CAN0_TX_M1SDMMC0_CMDGPIO2_A1TF card CMD pin
CAN0_RX_M1SDMMC0_CLKGPIO2_A2TF card clock pin
CAN1CAN1_TX_M0I2C3_SCL_M0GPIO1_A1_u20-pin GPIO on the back of the baseboard
CAN1_RX_M0I2C3_SDA_M0GPIO1_A0_u20-pin GPIO on the back of the baseboard
CAN1_TX_M1HDMI_RX_INT_L_GPIO4_C3GPIO4_C3_dCAN TX
CAN1_RX_M14G_DISABLE_GPIO4_C2GPIO4_C2_dCAN RX
CAN2CAN2_TX_M0I2C2_SCL_M1GPIO4_B5_dMIPI screen touch I2C
CAN2_RX_M0I2C2_SDA_M1GPIO4_B4_dMIPI screen touch I2C
CAN2_TX_M1WIFI_WAKE_HOST_H_GPIO2_B2GPIO2_B2_uBackplane lead unused
CAN2_RX_M1WIFI_REG_ON_H_GPIO2_B1GPIO2_B1_uBackplane lead unused

CAN protocol frame structure

Frame types

A frame is the basic unit of data transmission in CAN communication. Five different types of frames are used in CAN communication to achieve different functions. The following is a brief description of each frame type and its purpose:

  • Data Frame: The data frame is the most commonly used frame type in CAN communication, used by the transmitting unit to transfer data to the receiving unit. The data frame has two formats:
    • Standard format (11-bit identifier) is suitable for simpler networks.
    • Extended format (29-bit identifier) is suitable for more complex networks.
  • Remote Frame: The remote frame is used by the receiving unit to request data from the transmitting unit. It does not contain a data field; instead, it tells the transmitting unit via the identifier (ID) “I need the data corresponding to this ID.” The remote frame also has two formats: standard and extended. Its structure is similar to the data frame, but it lacks the data field.
  • Error Frame: The error frame is used to notify other nodes of an error when a node detects one. It is a special frame used to interrupt current communication and restart. The error frame consists of an error flag (6 consecutive dominant or recessive bits) and an error delimiter. Trigger conditions include bit errors, stuffing errors, CRC errors, etc.
  • Overload Frame: The overload frame is used by the receiving unit to notify the transmitting unit that it is not yet ready to receive. It typically appears when the receiving node needs more time to process the previous frame. The overload frame can only be sent during the interframe space. Its structure is similar to the error frame, consisting of an overload flag and an overload delimiter.
  • Interframe Space: The interframe space is used to separate data frames or remote frames from the preceding frames. It is a time interval that ensures nodes on the network can correctly identify the start of the next frame. For data frames and remote frames, the interframe space is typically 3 bit times; for error frames and overload frames, the interframe space may differ.
Frame TypePurpose
Data frameA frame that the transmitting unit uses to transfer data to the receiving unit.
remote framesA frame that the receiving unit uses to request data from the transmitting unit with the same ID.
Error FrameA frame that notifies other units of an error when an error is detected.
Overload FrameA frame by which a receiving unit notifies that it is not yet ready to receive.
Interframe spaceA frame that separates data frames and remote frames from the preceding frame.

Data frame

The data frame is the most fundamental frame type, responsible for carrying actual data content and enabling efficient information transfer between the transmitting unit and the receiving unit.

In early CAN communication,The standard data frame uses an 11-bit identifier, which could meet the relatively simple network architecture requirements at the time. However, as vehicle functions became more complex (such as advanced driver assistance systems, powertrain control, body electronics, etc.), the address space of the 11-bit identifier gradually proved insufficient, making it difficult to support larger-scale nodes and more refined communication needs. To this end, the CAN protocol introducedExtended data frame, via 29-bit identifierprovides a larger address space, significantly improving the flexibility and scalability of the network.

Standard Data Frame

The standard data frame is the basic structure used for data transmission in the CAN communication protocol. It contains multiple fields, each with different functions, ensuring efficient and safe data transmission. The composition diagram of the data frame is shown below

Standard Data Frame
Standard Data Frame

From the figure above, it can be seen that the standard data frame consists of the following 7 main fields:

  • Start of Frame

    • The start of frame consists of a fixed dominant bit(logic 0)Composition,used to mark the start of the data frame

    It not only notifies the receiving device to prepare to receive data, but also serves to synchronize the clocks of the transmitting end and the receiving end, ensuring correct parsing of subsequent data.

  • Arbitration Field(Arbitration Field)

    • ID(11-bit identifier) is mainly used to distinguish message types, priorities, and determine the transmission order. The smaller the identifier value, the higher the priority.
    • RTR bit(1 bit, Remote Transmission Request) is used to distinguish between data frames (dominant 0) and remote frames (recessive 1). In addition, the high 7 bits in the arbitration field are prohibited from being all recessive to avoid arbitration errors.
  • Control field(Control Field)

    • IDE bit(1 bit) is used to distinguish between standard frames (dominant 0) and extended format.
    • R0 bit(1 reserved bit), the reserved bit is fixed to dominant 0 for future expansion.
    • DLC bits(4 bits) indicate the number of bytes contained in the data field (ranging from 0 to 8 bytes).
  • Data field(Data Field)

    • Data fieldContains up to 8 bytes (64 bits), is the core part of the data frame, used to carry the actual communication data content.
    • Itslength is specified by the DLC bits in the control field, ranging from 0 bytes (no data) to 8 bytes (maximum data amount). The content of this field is the actual information of the communication, which may include sensor data, control commands, etc.
  • CRC check field(CRC Field)

    • CRC checksum (15 bits)
    • CRC delimiter (1 bit), fixed to recessive 1, used to clearly mark the end position of the CRC field.
    • The receiving device verifies data integrity by recalculating the CRC and comparing it with the received CRC checksum.
  • ACK field(Acknowledgment Field)

    • ACK slot (1 bit), when the receiving device successfully receives the data frame, it returns a dominant bit in the ACK slot as an acknowledgment signal, indicating that the data frame has been correctly received.
    • ACK delimiter (1 bit), the ACK delimiter is fixed to recessive 1, used to mark the end of the ACK field.
  • End of Frame(End of Frame)

    • Consists of 7 consecutive recessive bits (logic 1), used to clearly mark the end of the data frame.
    • It not only tells the receiving device that the data frame has been fully transmitted, but also provides extra time for signal synchronization to ensure correct reception of the next frame.
Field NameCompositionFunction
Start of frame1 dominant bit (0)Marks the start of the data frame and is used to synchronize the clocks of the transmitter and receiver, ensuring correct parsing of subsequent data.
Arbitration Field11-bit identifier + 1 RTR bitDistinguishes message type (data frame or remote frame), priority, and transmission order; the smaller the identifier value, the higher the priority; the RTR bit distinguishes data frames (dominant 0) from remote frames (recessive 1); the high 7 bits are prohibited from being all recessive.
Control field1 IDE bit + 1 reserved bit (RO) + 4 DLC bitsThe IDE bit distinguishes standard frames (dominant 0) from extended frames (recessive 1); the reserved bit is fixed to dominant 0 for future expansion; the DLC bits indicate the data field length (0-8 bytes).
Data fieldUp to 8 bytes (64 bits)Carries the actual communication data content, with the length specified by the DLC bits; the data field is the core part of communication and may contain actual information such as sensor data and control commands.
CRC check field15-bit CRC check code + 1 CRC delimiterDetects errors during data transmission; the receiving device verifies data integrity by recalculating the CRC and comparing it with the received CRC check code; the CRC delimiter is fixed to recessive 1, marking the end of the CRC field.
ACK field1 ACK slot + 1 ACK delimiterThe receiving device returns a dominant bit in the ACK slot to confirm successful reception of the data frame; the ACK delimiter is fixed to recessive 1, marking the end of the ACK field.
End of Frame7-bit recessive 1Clearly marks the end of the data frame, notifies the receiving device that the data frame has been transmitted, and provides extra time for signal synchronization to ensure correct reception of the next frame.

Standard format and extended format
Standard format and extended format

Function of the SRR bit

In the CAN protocol, the SRR bit is used to replace the RTR bit of a standard frame and is located at the position of the original RTR bit in the arbitration field of an extended frame.

Its function is to be forced to a recessive level (1) to ensure that when a standard frame and an extended frame compete for the bus simultaneously, the standard frame has higher priority because its RTR bit is dominant (0). When a standard frame and an extended frame are sent at the same time, the bus arbitration logic detects the dominant level (0), allowing the standard frame to win.

IDE bit
The IDE bit is an identifier extension flag used to distinguish frame types:Dominant (0) indicates the current frame is a standard frame, recessive (1) indicates an extended frame

In an extended frame, the IDE bit exists not only in the arbitration field to identify the frame type, but also appears in the control field, further clarifying the frame structure and distinguishing extended frames from standard frames.

remote frames

Remote Frameis in the CAN protocola special frame type used to actively request data

When a node needs to obtain data from other nodes, it can send a remote frame to initiate a request on the bus, and the target node returns the corresponding data frame after receiving the request.

**A data frame with the data field removed is a remote frame.**Of course, like data frames, remote frames are also divided into standard remote frames and extended remote frames, and their respective structures are as follows:

remote frames
remote frames

  • Start of Frame
    • The start of frame consists of 1 dominant bit (0), same as the data frame, and is used to mark the beginning of the remote frame.
    • It not only notifies the receiving device to prepare to receive data, but also synchronizes the clocks of the transmitter and receiver, ensuring the accuracy of subsequent data parsing.
  • Arbitration Field
    • 11-bit identifier (ID)
    • 1-bit RTR bit (recessive 1)
    • It is used to specify the type of data frame being requested, and at the same time distinguishes it from a data frame (dominant 0) through the recessive RTR bit (1), ensuring that its priority is lower than that of a data frame with the same ID. In an extended remote frame, the arbitration field is expanded to a 29-bit identifier (ID), an SRR bit (recessive 1), an IDE bit (recessive 1), and an RTR bit (recessive 1). Among them, the SRR bit replaces the RTR bit of a standard frame, ensuring that the extended frame has lower priority than a standard data frame during arbitration; the recessive IDE bit (1) is used to identify the frame as an extended frame.
  • Control Field: Same as the control field in standard and extended data frames.
  • Data Field: Remote frameNo data field, which is the core difference from a data frame. By omitting the data field, it clearly indicates that the frame is a request rather than data transmission, thereby triggering the target node to send a data frame with the corresponding ID.
  • CRC Field
    • 15-bit CRC check code
    • 1-bit recessive CRC delimiter
    • Used to verify whether errors occurred during transmission of the remote frame. The receiving device recalculates the CRC and compares it with the received CRC check code to ensure the reliability of the request.
  • ACK Field: The ACK field consists of a 1-bit ACK slot and a 1-bit recessive ACK delimiter. When a receiving node successfully receives the remote frame, it returns a dominant bit in the ACK slot as an acknowledgment signal, indicating that the remote frame has been correctly received. The ACK delimiter is fixed to recessive 1 to mark the end of the ACK field.
  • End of Frame
    • The end of frame consists of 7 consecutive recessive 1s, the same as a data frame, and is used to clearly mark the end of the remote frame. It not only tells the receiving device that the remote frame has been fully transmitted, but also provides additional time for signal synchronization to ensure correct reception of the next frame.
Field NameCompositionFunction
Start of frame1 dominant bit (0)Marks the start of the remote frame, synchronizes the clocks of the transmitting and receiving ends, and ensures the accuracy of subsequent data parsing.
Arbitration FieldStandard frame: 11-bit ID + RTR (recessive 1); Extended frame: 29-bit ID + SRR (recessive 1) + IDE (recessive 1) + RTR (recessive 1)Specifies the type of data frame requested. The recessive RTR bit (1) distinguishes it from a data frame; the extended frame is compatible with standard frames through the SRR and IDE bits, and has lower priority than a data frame with the same ID.
Control fieldStandard frame: IDE + R0 + 4-bit DLC; Extended frame: R1 + R0 + 4-bit DLCThe DLC bits indicate the byte length of the target data frame (0-8 bytes), but the remote frame itself does not carry data; the IDE bit distinguishes extended frames from standard frames.
Data fieldNoneClarify that the remote frame is a request frame and does not perform data transmission.
CRC check field15-bit CRC check code + 1 recessive CRC delimiterVerify the correctness of the remote frame transmission process, ensuring the reliability of the request.
ACK field1-bit ACK slot (receiving node fills dominant bit) + 1 recessive ACK delimiterThe receiving node confirms via the ACK slot that the remote frame has been correctly received, and the ACK delimiter marks the end of this field.
End of Frame7 recessive 1sMarks the end of the remote frame, provides signal synchronization time, and ensures correct reception of the next frame.

Error Frame

An error frame is a special frame in the CAN bus used to indicate that an error has occurred during communication. Its structure differs from other frames (such as data frames or remote frames) and is mainly used to notify all nodes in the network that the current transmission has an error.

Error Frame Composition
Error Frame Composition

  • Error Flag
    • 6 consecutive dominant bits (logic 0) or recessive bits (logic 1), divided into active error flag and passive error flag.
    • Active Error FlagSent by the node that detected the error, forcibly interrupting the transmission of the current frame and notifying all nodes in the network of the error occurrence.
    • Passive Error FlagIt is sent by a node in the passive error state to avoid interfering with the normal communication of other nodes.
  • Error Delimiter
    • Composed of 8 consecutive recessive bits (logic 1), used to mark the end of the error frame. It ensures that all nodes can clearly identify the boundary of the error frame and resume normal communication flow after error handling is completed.
Field NameCompositionFunction
Error FlagActive error flag: 6 dominant bits; Passive error flag: 6 recessive bitsThe active error flag forcibly interrupts the current frame transmission to notify network nodes of an error; the passive error flag avoids interfering with communication of other nodes.
Error Delimiter8 recessive bitsMarks the end of the error frame, helping all nodes identify the error frame boundary and resume normal communication.

Overload Frame

An overload frame is a special frame in the CAN bus used to notify other nodes on the network that the receiving device needs more time to process data. It is usually sent when the receiving node cannot process the received data in time, to request the transmitting node to delay the transmission of the next frame. The composition of the overload frame is as follows:

Overload Frame
Overload Frame

  • Overload Flag
    • Composed of 6 consecutive dominant bits (logic 0), sent by the receiving node to notify other nodes on the network that the receiving device needs more time to process data, thereby requesting a delay in the transmission of the next frame.
    • Multiple nodes can send overload flags simultaneously; these flags are superimposed to form a longer sequence of dominant bits.
  • Overload Delimiter
    • Composed of 8 consecutive recessive bits (logic 1), used to mark the end of the overload frame.
    • It ensures that all nodes can clearly identify the boundary of the overload frame and resume normal communication after overload handling is completed.
Field NameCompositionFunction
overload flag6 consecutive dominant bitsSent by the receiving node to inform other nodes on the network that it needs more time to process data, requesting a delay in the next frame transmission.
overload delimiter8 consecutive recessive bitsMarks the end of an overload frame, helping all nodes identify its boundary and thereby resume normal communication flow.

The overload frame usesoverload flagandoverload delimiterThe two fields serve to identify and handle the insufficient processing capability of the receiving node.

When the receiving node cannot process data in time, it sends an overload flag (6 dominant bits) to notify other nodes on the network to delay the transmission of the next frame; then, through the overload delimiter (8 recessive bits), it clearly marks the end of the overload frame.

The design of the overload frame ensures that nodes in the network can coordinate communication under high load, avoiding data loss or errors.

Bit stuffing

Bit stuffing is an important mechanism in the CAN protocol for ensuring signal synchronization during data transmission.

Bit stuffing inserts a stuffing bit of opposite polarity after five consecutive bits of the same polarity, ensuring that there is always a level change on the bus, thereby maintaining synchronization between the transmitter and receiver.

Stuffing is performed only from the start of frame to the CRC field, avoiding interference with other parts. After detecting the stuffing bit, the receiver automatically removes it to restore the original data. This mechanism is crucial for preventing signal synchronization problems and improving the reliability of CAN bus communication.

Core purpose

By inserting a stuffing bit of opposite polarity after five consecutive bits of the same polarity, it avoids long runs of ‘0’ or ‘1’ levels that could cause bus synchronization problems, thereby improving communication reliability.

Bit stuffing rules

When five consecutive bits of the same polarity appear in the data, a stuffing bit with the opposite polarity is inserted at the sixth bit.

This mechanism breaks up potentially long runs of the same level, ensuring that there is always a level change on the bus, thereby maintaining synchronization between the transmitter and receiver.

Stuffing range

From the start of frame to the CRC fieldCRC Data after the field(such as ACK Field and end of frame)No stuffing is performedThis design limits the stuffing range, avoiding interference with parts that do not require synchronization, while ensuring the synchronization of critical data segments.

  • Example 1:
    • Original data: 110000011
    • Analysis: No five consecutive bits of the same polarity appear, so no stuffing is required.
    • Actual transmitted data: 110000011
    • Receiver directly recovers original data: 110000011
  • Example 2:
    • Original data: 0111111
    • Analysis: There are 5 consecutive '1’s, insert a ‘0’ at the 6th bit.
    • Actual transmitted data: 01111101
    • Receiver detects and removes the stuffed bit, recovering the original data: 0111111
  • Example 3:
    • Original data: 1000001111
    • Analysis: There are 5 consecutive '0’s, insert a ‘1’ at the 6th bit. After inserting the ‘1’, there are five consecutive '1’s, so a ‘0’ needs to be added at the last bit.
    • Actual transmitted data: 100000111110
    • Receiver detects and removes the stuffed bits, recovering the original data: 1000001111

CAN Waveform Example Analysis

Standard Data Frame

Example 1
Example 1

CAN communication is determined by a pair of differential signal lines, but there is only one CAN waveform above. This is because the waveform was acquired by a logic analyzer, which automatically converts the differential signal into a logic signal. Then we analyze the waveform.

Start of frame

First is the start of frame. The start of frame consists of a fixed dominant bit (logic 0) and is used to mark the beginning of the data frame.

Start of frame
Start of frame

Arbitration Field

Next is the 12-bit arbitration field. The first 11 bits are the identifier (ID), and the last bit is the Remote Transmission Request (RTR) bit. The identification diagram is shown below. The bits marked with a red × represent stuffed bits, so the corresponding bits need to be ignored during actual analysis. The RTR bit in the last position is a dominant bit (logic 0), so the currently transmitted frame is a data frame.

Arbitration Field
Arbitration Field

Control field

After the arbitration field is the 6-bit control field, including 1 IDE bit, 1 reserved bit (R0), and 4 data length code (DLC) bits. The identification diagram is shown below. The IDE bit is a dominant bit (logic 0), so the current frame is a standard frame. The reserved bit R0 defaults to a dominant bit (logic 0). The DLC bits in the last four positions are 0001, indicating that 8 bits of data will be sent later.

Control field
Control field

Data field

Next is the 8-bit data field, which is used to carry the actual communication data content. The identification diagram is shown below. The data to be sent is 00000001, and then continue analyzing downward.

Data field
Data field

CRC check field

CRC check field
CRC check field

ACK field

The next two bits are the ACK field (Acknowledgment Field). The ACK field consists of 2 bits, including 1 ACK slot and 1 ACK delimiter. When the receiving device successfully receives the data frame, it returns a dominant bit in the ACK slot as an acknowledgment signal, indicating that the data frame has been correctly received. The ACK delimiter is fixed to recessive 1, used to mark the end of the ACK field. The identification diagram is shown below:

ACK field
ACK field

Finally, the end of frame consists of 7 consecutive recessive bits (logic 1), which clearly marks the end of the data frame.

Standard Remote Frame

remote frames
remote frames

Start of frame

First is the start of frame, which consists of a fixed dominant bit (logic 0) and is used to mark the beginning of the data frame, as indicated in the figure below.

Start of frame
Start of frame

Arbitration Field

Next is the 12-bit arbitration field, in which the first 11 bits are the identifier (ID) and the last bit is the remote transmission request (RTR) bit. The identification diagram is shown below. The bits marked with red × indicate stuff bits, so the corresponding bits need to be ignored during actual analysis. The last RTR bit is a recessive bit (logic 1), and by observation it can be seen that there are no data bits to be transmitted afterward, so the currently transmitted frame is a remote frame.

Standard Remote Frame Arbitration Field Bit Identification Diagram
Standard Remote Frame Arbitration Field Bit Identification Diagram

Control field

After the arbitration field is the 6-bit control field (Control Field), including 1 IDE bit, 1 reserved bit (R0), and 4 data length code (DLC) bits. The identification diagram is shown below. The IDE bit is a recessive bit (logic 1), so the current frame is an extended remote frame. The reserved bit R0 defaults to a dominant bit (logic 0). The DLC bits of the last four bits are 0001, but since the current frame is a remote frame, no data will be sent.

Control field
Control field

CRC check field

The CRC check field consists of a 15-bit CRC check code and a 1-bit CRC delimiter, used to detect whether errors occur during data transmission. The identification diagram is shown below. The last CRC delimiter is fixed to recessive 1, used to clearly indicate the end position of the CRC field.

CRC check field
CRC check field

ACK field

The next two bits are the ACK field (Acknowledgment Field). The ACK field consists of 2 bits, including 1 ACK slot and 1 ACK delimiter. When the receiving device successfully receives the data frame, it returns a dominant bit in the ACK slot as an acknowledgment signal, indicating that the data frame has been correctly received. The ACK delimiter is fixed to recessive 1, used to mark the end of the ACK field. The identification diagram is shown below:

ACK field
ACK field

Finally, the end of frame is composed of 7 consecutive recessive bits (logic 1).

Extended data frame

Extended data frame
Extended data frame

Start of frame

First is the start of frame, which consists of a fixed dominant bit (logic 0) and is used to mark the beginning of the data frame, as indicated in the figure below.

Start of frame
Start of frame

Extended frame

Based on the waveform length and the yellow marker above, it can be determined that this frame is an extended frame. Therefore, in the next 12 bits, the first 11 bits are the identifier (ID), and the last bit is the SRR bit. The identification diagram is shown below. The bits marked with a red × are stuff bits, so the corresponding bits need to be ignored during actual analysis. The SRR bit is a recessive bit (logic 1).

Extended frame
Extended frame

Next is the 1-bit IDE bit. The IDE bit is a recessive bit (logic 1), so the current frame is an extended frame. However, whether it is an extended remote frame or an extended data frame still requires further analysis.

Extended frame
Extended frame

In the next 19 bits, the first 18 bits are also ID bits, and the last bit is the RTR bit, as shown in the diagram below. The RTR bit in the last position is a dominant bit (logic 0), so the currently transmitted frame is an extended data frame. Continue the analysis.

Extended frame
Extended frame

Control field

The next six bits are the control field (Control Field), including 2 reserved bits (R1 and R0) and a 4-bit data length code (DLC), as shown in the diagram below. The DLC bits in the last four positions are 0001, indicating that 8 bits of data will be sent next.

Control field
Control field

Data field

Next is the 8-bit data field, which is used to carry the actual communication data content, as shown in the diagram below. The data to be sent is 00000001.

Data field
Data field

CRC check field

The CRC check field consists of a 15-bit CRC check code and a 1-bit CRC delimiter. It is used to detect whether errors occur during data transmission, as shown in the diagram below. The CRC delimiter in the last position is fixed to recessive 1, which is used to clearly mark the end of the CRC field.

CRC check field
CRC check field

ACK field

The next two bits are the ACK field (Acknowledgment Field). The ACK field consists of 2 bits, including 1 ACK slot and 1 ACK delimiter. When a receiving device successfully receives a data frame, it returns a dominant bit in the ACK slot as an acknowledgment signal, indicating that the data frame has been correctly received. The ACK delimiter is fixed to recessive 1, which is used to mark the end of the ACK field, as shown in the diagram below.

ACK field
ACK field

Finally, the end of frame consists of 7 consecutive recessive bits (logic 1), which clearly marks the end of the data frame.

Core mechanisms and communication principles of the CAN bus

Bit time

In CAN bus communication,**Bit time refers to the time required to transmit one logical bit,**It is one of the core concepts for achieving reliable data transmission in the CAN protocol, directly affecting the communication baud rate and signal synchronization accuracy. As the basis of asynchronous communication, all nodes maintain synchronization through an agreed bit time.

The CAN protocol divides bit time into multiple time segments, which together determine the signal sampling and synchronization mechanism. Specifically, it includes the following parts:

Bit time division
Bit time division

  • Sync Segment

The sync segment is the first part of the bit time,fixed to 1 time quantumTQ (time quantum) is the basic unit of bit time, and all time segments are divided based on the time quantum.), mainly used to detect signal edges and achieve hard synchronization.

During the start of frame (SOF) phase, the receiving node forcibly adjusts its own clock according to the falling edge of the bus signal to align with the bus signal, thereby ensuring that all nodes remain synchronized at the initial stage of communication.

  • Propagation Segment

The propagation segment is used to compensate for the propagation delay of the signal on the bus and the response time of the input comparator. Its length is usually 1 to 8 time quanta (TQ), and the specific value is determined by configuration. This

time segment allows the signal to propagate on the physical medium and ensures that all nodes can receive a stable signal, thereby avoiding sampling errors caused by propagation delay.

  • Phase Buffer Segment 1 (Phase Segment 1)

Phase Buffer Segment 1 is a configurable part of the bit time, usually 1 to 8 time quanta (TQ),mainly used to adjust the position of the sampling point to ensure that the sampling point is located in a stable signal region.

If it is detected that the signal edge arrives early,,the phase buffer segment can be shortened 1 to achieve resynchronization,thereby dynamically compensating for the effects of clock deviation or signal jitter.。
  • Phase Segment 2

Phase Segment 2 is similar to Phase Segment 1, and is also a configurable part of the bit time, typically ranging from 1 to 8 time quanta (TQ).

It is mainly used to handle situations where signal edges arrive late.。If the signal edge is delayed,It can be handled by extending the phase buffer segment 2 to achieve resynchronization,thereby ensuring that the receiving node can sample the signal at the correct time.,improving the reliability of data transmission.。

The role of bit time

  1. Ensure synchronization: By dividing the time segments, CAN nodes can dynamically adjust the sampling point when signal edges occur, compensating for clock deviations and signal delays, thereby achieving synchronization among multiple nodes.
  2. Improve anti-interference capability: Set the sampling point in a stable signal region (e.g., at 87.5% of the bit time) to avoid misjudgment caused by signal edge jitter or interference.
  3. Support flexible configuration: By adjusting the lengths of various time segments (such as the propagation segment, phase buffer segments, etc.), it can adapt to different baud rates and network environments.

Hard Synchronization and Resynchronization

In CAN communication, because asynchronous communication is used and there is no independent clock line, each node relies on its local crystal oscillator for data transmission. However, clock drift of the crystal oscillator causes the timing between nodes to gradually shift, eventually leading to sampling errors. To solve this problem, the CAN protocol implements dynamic timing adjustment through two mechanisms: hard synchronization and resynchronization:

  1. Hard synchronization forcibly aligns the clocks of all nodes at the start-of-frame stage, eliminating the initial phase deviation.
  2. Resynchronization, on the other hand, dynamically adjusts the length of the phase buffer segments based on real-time detection of signal edges during data transmission to compensate for clock drift.

These two mechanisms work together, combined with the bit time division (synchronization segment, propagation segment, phase segments I/II) and the quantitative management of time quanta (Tq), to ensure that all nodes accurately read the bus level at the sampling point, thereby achieving highly reliable data transmission in asynchronous communication without an independent clock line. In this subsection, hard synchronization and resynchronization will be explained in detail.

Hard synchronization

In CAN communication, hard synchronization is an important mechanism to ensure consistent initial timing among all nodes. Its core function isto forcibly align the timing of each node during the start-of-frame (SOF) stage, thereby eliminating the initial phase difference caused by local crystal oscillator variations.

The trigger condition for hard synchronization isWhen the bus detects a falling edge of the dominant level (logic 0) from the idle state (i.e., the edge of the SOF bit), the node immediately adjusts its own timing to align the synchronization segment of the current bit to this edge.

This process can be divided into the following steps:

  • The nodecontinuously monitors level changes during the bus idle period.
  • whenWhen a falling edge of SOF is detected and the edge falls within the synchronization segment, hard synchronization is triggered.
  • The node forcibly adjusts its timing, aligning the start of the synchronization segment of the current bit to that edge, and restarts the counting of subsequent bit time.

Hard synchronization
Hard synchronization

However,The scope of hard synchronization is limited; it only takes effect at the beginning of a message frame and can only solve the initial phase offset problem.

For dynamic phase errors caused by clock drift or signal interference during communication,,hard synchronization is powerless.,These issues need to be handled by the subsequent resynchronization mechanism.

Resynchronization

In CAN communication,Resynchronization is a key mechanism for solving dynamic phase errors caused by clock drift or signal interference during communication.

Unlike hard synchronization, resynchronization is not limited to the frame start phase, butcontinues to function throughout the entire data transmission process.Its core function is to dynamically adjust the position of the sampling point,,ensuring that the receiving node can read the bus level at the correct time,,thereby maintaining communication reliability.

Specifically,The trigger condition for resynchronization is when a deviation is detected between a signal edge (such as a change from dominant to recessive level) and its expected position.

  • If the signal edge arrives early, it indicates that the transmitting node’s clock is faster than the receiving node’s; in this case, the receiving node advances the sampling point by shortening Phase Buffer Segment 1.
  • Conversely, if the signal edge arrives late, it indicates that the transmitting node’s clock is slower than the receiving node’s; the receiving node delays the sampling point by extending Phase Buffer Segment 2.

This dynamic adjustment process depends onthe Synchronization Jump Width (SJW), which definesthe maximum range of each resynchronization adjustment,to prevent excessive adjustment from causing new errors.

The edge from recessive level to dominant level occurs between PTS and PBS1.
The edge from recessive level to dominant level occurs between PTS and PBS1.

When the edge from recessive level to dominant level occurs in PBS2.
When the edge from recessive level to dominant level occurs in PBS2.

The advantage of resynchronization lies in its flexibility and real-time capability, effectively coping with challenges caused by clock drift or signal propagation delay during communication.

However,The adjustment range of resynchronization is limited by SJW the configuration of,If the phase error exceeds SJW the limit,it may lead to sampling errors,thereby affecting the reliability of communication

Therefore, resynchronization and hard synchronization work together to constitute the complete synchronization mechanism in the CAN protocol: hard synchronization provides initial alignment for communication, while resynchronization dynamically compensates for errors in subsequent transmissions, ensuring the accuracy and stability of data transmission.

Arbitration Rules

In CAN bus communication, because multiple nodes share the same bus, only one data frame can be transmitted at the same time, so an efficient arbitration mechanism is required to ensure orderly data transmission.

The CAN protocol, through the collaboration of carrier sensing, non-destructive arbitration, and readback mechanisms, achieves efficient and conflict-free communication among multiple nodes.

Carrier Sensing

BeforeBefore sending data, each node first listens to the bus stateOnly when the bus is in an idle state (i.e., no other node is sending data) is the node allowed to start sending data.

This mechanism is similar to ‘Carrier Sense Multiple Access (CSMA)’ in Ethernet, and can effectively avoid multiple nodes occupying the bus at the same time.

If two or more nodes detect the bus idle almost simultaneously and start sending data,then they enter the non-destructive arbitration phase。

Non-destructive Arbitration

Non-destructive arbitration is the core of the CAN bus arbitration mechanism, and its core principle isbased on the wired-AND mechanism

  • When all nodes send a recessive level (logic 1), the bus is recessive;
  • As long as one node sends a dominant level (logic 0), the bus is dominant.

This mechanism ensures that even if multiple nodes transmit data simultaneously, the signals on the bus will not be corrupted; instead, the dominant level prevails. The arbitration process is as follows:

  • The identifier (ID) field of each data frame is used for arbitration priority,The smaller the ID, the higher the priority.
  • When multiple nodes transmit data simultaneously, they compare, bit by bit, the ID they are sending with the actual level on the bus.
    • If a node is sending a recessive level (1) but detects a dominant level (0) on the bus, it means a higher-priority node is transmitting data. The node immediately stops transmitting and enters listen mode, waiting for the next bus idle condition to retry transmission.
    • If a node is sending a dominant level (0) and the bus also has a dominant level (0), the node continues transmitting, indicating that it currently has the highest priority.

Readback mechanism

To ensure the correctness of arbitration and the reliability of data transmission, CAN nodescontinuously read back the signals on the bus while transmitting dataand compare them with the data they are sending.

If a transmitting node finds that the readback data is inconsistent with the data it sent,(for example, sending a recessive level but reading back a dominant level,)then it indicates that an arbitration conflict has occurred, and the node will immediately**stop transmitting and switch to listen mode.**。

This mechanism ensures that lower-priority nodes can withdraw from transmission in time, avoiding interference with higher-priority nodes’ communication.

Error states

In the CAN protocol, a node’s error state is based on the values of the**Transmit Error Counter (TEC)andReceive Error Counter (REC)**dynamically adjusted based on the values of these counters.

Through three different error states—Error Active state, Error Passive state, and Bus-Off state,

the CAN protocol achieves effective management and isolation of faulty nodes, while ensuring the reliability and stability of communication.

Error Active state

When a node’s Transmit Error Counter (TEC) and Receive Error Counter (REC) are both less than or equal to 127, the node is in the Error Active state.

In this state, the node can participate normally in bus communication and actively sends an active error flag (dominant bit) when an error is detected. This dominant flag forcibly overrides the bus signal to notify other nodes that an error currently exists.

Because dominant bits have higher priority, this mechanism can quickly propagate error information, thereby ensuring errors are handled in a timely manner and maintaining the reliability of bus communication.

Error Passive State

If a node’s Transmit Error Counter (TEC) or Receive Error Counter (REC) exceeds 127 (usually triggered by TEC), the node enters the Error Passive state.

In this state, the node can still participate in communication, but its behavior is restricted: it cannot actively send dominant error flags; instead, it sends passive error flags (recessive bits) to avoid disturbing the bus. In addition, after each transmission, a delay of 8 recessive bits must be inserted before attempting to communicate again.

It is worth noting that if only a node in the Error Passive state detects an error while other active nodes do not, the bus is considered error-free and communication continues.

This design both limits the impact of low-reliability nodes on the bus and ensures the communication efficiency of high-reliability nodes.

Bus-Off State

When a node’s Transmit Error Counter (TEC) exceeds 255, the node enters the Bus-Off state.

In this state, the node is completely prohibited from communicating; it can neither send nor receive data, to prevent it from causing further interference to the bus.

To resume communication, the node needs to detect 128 consecutive occurrences of 11 recessive bits (i.e., the bus is idle for a sufficiently long time), then reset TEC and REC to 0, thereby returning to the Error Active state and rejoining bus communication.

This mechanism aims to isolate severely faulty nodes while providing them with an opportunity to rejoin the bus.

Error State Machine
Error State Machine

The more specific conditions for changing the Receive Error Counter (REC) and Transmit Error Counter (TEC) are shown in the following table:

No.Conditions for changing the receive and transmit error counter valuesTransmit Error Counter (TEC)Receive Error Counter (REC)
1When the receiving unit detects an error. Exception: When the receiving unit detects a ‘bit error’ while sending an error flag or overload flag, the receive error counter is not incremented.+1
2When the first bit detected by the receiving unit after sending an error flag is dominant.+8
3When the transmitting unit outputs an error flag.+8
4When the transmitting unit detects a bit error while sending an active error flag or overload flag.+8
5When the receiving unit detects a bit error while sending an active error flag or overload flag.+8
6When each unit detects 14 consecutive dominant bits from the very beginning of an active error flag or overload flag. Thereafter, each time it detects 8 consecutive dominant bits.When transmitting: +8When receiving: +8
7When 8 consecutive dominant bits are detected appended after a passive error flag.When transmitting: +8When receiving: +8
8When the transmitting unit finishes sending data normally (when ACK is returned and no error is detected up to the end of frame).When TEC=0: ±0; otherwise -1
9When the receiving unit finishes receiving data normally (when no error is detected up to CRC and ACK is returned normally).When 1≤REC≤127: -1; when REC=0: ±0; when REC>127: set REC=127
10When a unit in the bus-off state detects 128 occurrences of 11 consecutive recessive bits.TEC=0REC=0

Error Detection Mechanism

The CAN (Controller Area Network) protocol effectively improves communication reliability through multiple error detection methods.

The error detection mechanism can be divided into the following five types: bit error, stuff error, CRC error, form error, and ACK error.

Bit Error

A bit error refers toan error detected when the transmitting unit, during communication, compares its own output level with the bus level (excluding stuff bits) and finds a mismatch.

This type of error usually indicates a conflict or interference between the transmitting node and the signal on the bus.

Bit errors can occur in data frames、remote frames、and in any segment of error frames and overload frames.(From SOF to EOF)。

Since a bit error is detected by the transmitting unit itself, its detecting unit is the transmitting unit.

Stuff Error

A stuff error refers toan error triggered when the receiving unit continuously detects 6 bits of the same level in a segment that requires bit stuffing.

The CAN protocol specifies that in a bit stuffing segment, after every 5 consecutive bits of the same level, a stuff bit of the opposite level must be inserted to ensure DC balance of the signal.

If the receiving unit detects 6 consecutive bits of the same level, it considers a stuff error to have occurred.

Stuff errors mainly occur in any segment of data frames and remote frames.(From SOF to EOF),Its detection unit is the receiving unit.。

CRC error

A CRC error refers to**The CRC check value calculated by the receiving unit based on the received data is inconsistent with the CRC sequence actually received in the frame.**is the error detected when.

CRC check is a key mechanism in the CAN protocol for verifying data integrity. If the check fails, it indicates that the data may have been corrupted or lost during transmission.

CRC The error usually occurs in the CRC segment.,Its detection unit is the receiving unit.。

Format error

A format error refers to**an error triggered when the receiving unit detects a format opposite to the fixed-format bit field while parsing the frame.**For example, illegal values of the CRC delimiter, ACK delimiter, or EOF may all cause a format error.

This type of error usually indicates that the frame structure does not conform to the CAN protocol specification.

Format errors can occur in the CRC delimiter、ACK delimiter、EOF field,as well as in the error delimiter and overload delimiter.,Its detection unit is the receiving unit.。

ACK error

An ACK error refers toan error triggered when the transmitting unit detects a recessive level in the ACK slot.

In the CAN protocol,When the transmitting unit completes the transmission of a data frame or remote frame, it waits in the ACK slot for an acknowledgment signal (dominant level) from other nodes.

If the transmitting unit does not detect a dominant level, it considers that no acknowledgment signal was received, thereby triggering an ACK error.

ACK Errors mainly occur in the data frame and remote frame's ACK slot segment,Its detection unit is the transmitting unit.。

CAN bus protocol and standard specifications

In modern communication systems, the ISO seven-layer network model is a classic framework for describing and standardizing network communication processes. It divides network communication into seven layers, from the bottom physical signal transmission to the top application services, and each layer has specific functions and roles.

Although the design of the CAN protocol does not fully follow the ISO seven-layer network model, its functions can be mapped to some layers of the model.

The CAN protocol mainly focuses onPhysical LayerData Link LayerandTransport Layersome of the functions.

ISO seven-layer network model

  1. Physical Layer
    The physical layer is responsible for physical signal transmission between devices, defining the electrical signals, hardware specifications, and communication media required for communication. It covers communication modes (such as simplex, half-duplex, full-duplex), signal levels (such as high and low levels representing logic 0 and 1), hardware specifications (such as cables, connectors, transceivers), and bit timing conditions (such as bit synchronization, sampling points), thereby ensuring reliable data transmission over the physical medium.

  2. Data Link Layer
    The data link layer organizes the bit sequence received from the physical layer into meaningful data frames and provides error detection and control functions. Its specific items include the format of data frames (such as frame start, identifier, data field, CRC check), access control methods (such as CSMA/CD, CSMA/CA), and error detection and correction mechanisms (such as CRC check, ACK response), to ensure the accuracy and integrity of data transmission on the link.

  3. Network Layer
    The network layer is responsible for routing and relaying data packets, ensuring that data can be efficiently transmitted from the source device to the destination device. Through functions such as routing (such as static routing, dynamic routing), address management (such as IP address allocation), and packet fragmentation and reassembly, it enables data transmission across networks and provides support for communication in complex network environments.

  4. Transport Layer
    The transport layer ensures the reliability of data transmission, controlling data order, error recovery, and flow control. Through mechanisms such as data transmission order control (such as sequence numbers, acknowledgment mechanisms), error recovery (such as retransmission mechanisms), and flow control (such as sliding window protocols), it guarantees the consistency, integrity, and efficiency of data during end-to-end transmission.

  5. Session Layer
    The session layer manages the establishment, maintenance, and termination of communication sessions, ensuring that data can be correctly transmitted during the session. Through functions such as session establishment and termination (such as handshake protocols), session synchronization (such as checkpoint mechanisms), and session recovery (such as resumable transfer), it coordinates interactions between applications and improves the stability and efficiency of communication.

  6. Presentation Layer
    The presentation layer is responsible for converting the representation form of data, ensuring data compatibility between different systems. Through functions such as data format conversion (such as text encoding, image formats), data encryption and decryption, and data compression and decompression, it enables data to be seamlessly exchanged and processed between different platforms and applications.

  7. Application Layer
    The application layer provides network service interfaces for applications and implements specific application functions. It directly serves end users through application protocols (such as HTTP, FTP, SMTP), user interfaces (such as browsers, email clients), and data services (such as file transfer, email), meeting diverse network application needs.

The CAN protocol mainly focuses on the physical layer and the data link layer

  • Physical layer in the CAN protocol

The physical layer is responsible for defining the actual signal transmission method, using NRZ (Non-Return-to-Zero) encoding, and inserting stuffing bits after every 6 bits.

It also specifies bit timing and sample count, which users can choose according to their needs.

Synchronization is achieved through the synchronization segment (SS) and has resynchronization capability. However, specific details such as signal levels, communication speed, sampling points, electrical characteristics of drivers and buses, and connector shapes are not defined in the protocol and need to be determined by the user based on system requirements.

  • Data link layer in the CAN protocol
    • **MAC sublayer (Media Access Control sublayer)**It is responsible for organizing data into frames, including data frames, remote frames, error frames, and overload frames. It also handles arbitration during data conflicts, deciding which message continues to be sent based on priority, and responds via ACK (acknowledgment) and NACK (negative acknowledgment). In addition, the MAC sublayer detects and reports CRC errors, stuffing bit errors, bit errors, ACK errors, and format errors, and has fault confinement capability that can automatically distinguish temporary errors from persistent errors and isolate faulty nodes.
    • **LLC sublayer (Logical Link Control sublayer)**It is responsible for the selection of received messages, supporting point-to-point connections, broadcast, and multicast; it also provides error recovery functions, performing retransmission control when errors are detected to ensure reliable data transmission.

CAN
CAN

After ISO standardization, the CAN protocol is divided into two standards: ISO11898 and ISO11519-2.

The definitions of these two standards are the same at the data link layer, but they differ at the physical layer:

  • ISO11898 is a CAN high-speed communication standard with a communication speed of 125kbps-1Mbps
  • ISO11519-2 is a CAN low-speed communication standard with a communication speed below 125kbps.

 The two standards ISO11898 and ISO11519-2
The two standards ISO11898 and ISO11519-2

Comparison of the two standards
Comparison of the two standards

Enable CAN

Device Tree

1234567891011121314151617181920212223242526272829303132333435363738
can0: can@fe570000 {	compatible = "rockchip,rk3568-can-2.0"; // Specify the device compatibility string for matching the driver	reg = <0x0 0xfe570000 0x0 0x1000>; // Define the register address range: base address is 0xfe570000, length is 0x1000 bytes	interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>; // Define interrupt information: use GIC SPI interrupt, interrupt number 1, trigger type is high-level	clocks = <&cru CLK_CAN0>, <&cru PCLK_CAN0>; // Define the clock source: reference CLK in the CRU node_CAN0 (baud rate clock) and PCLK_CAN0 (APB bus clock)	clock-names = "baudclk", "apb_pclk"; // Name the clock signals: baud rate clock and APB bus clock, respectively.	resets = <&cru SRST_CAN0>, <&cru SRST_P_CAN0>;// Define the reset signal: reference SRST in the CRU node._CAN0 (main reset) and SRST_P_CAN0 (APB reset)	reset-names = "can", "can-apb"; // Name the reset signals: CAN main reset and APB reset, respectively.	tx-fifo-depth = <1>; // Define the transmit FIFO depth: depth is 1, meaning only one message to be sent can be stored at a time.	rx-fifo-depth = <6>; // Define the receive FIFO depth: depth is 6, meaning up to 6 received messages can be stored simultaneously.	status = "disabled"; // Define the initial device state: disabled by default, the device will not be enabled at startup.};can1: can@fe580000 {	compatible = "rockchip,rk3568-can-2.0";	reg = <0x0 0xfe580000 0x0 0x1000>;	interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;	clocks = <&cru CLK_CAN1>, <&cru PCLK_CAN1>;	clock-names = "baudclk", "apb_pclk";	resets = <&cru SRST_CAN1>, <&cru SRST_P_CAN1>;	reset-names = "can", "can-apb";	tx-fifo-depth = <1>;	rx-fifo-depth = <6>;	status = "disabled";};can2: can@fe590000 {	compatible = "rockchip,rk3568-can-2.0";	reg = <0x0 0xfe590000 0x0 0x1000>;	interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;	clocks = <&cru CLK_CAN2>, <&cru PCLK_CAN2>;	clock-names = "baudclk", "apb_pclk";	resets = <&cru SRST_CAN2>, <&cru SRST_P_CAN2>;	reset-names = "can", "can-apb";	tx-fifo-depth = <1>;	rx-fifo-depth = <6>;	status = "disabled";};

Although there are 3 CAN device nodes here, on the Xunwei baseboard there is only one CAN interface due to pin muxing issues. The corresponding schematic section is shown below:

topeet RK3568 CAN1
topeet RK3568 CAN1

It can be seen that CAN1 is used on the development board, and inrk3568.dtsiIn the device tree, the status of the can1 node is set to disabled, meaning it is not enabled, so there must be an addition to this node in another device tree.

123456789
//CAN interface&can1 {        status = "okay";// Specify the device compatibility string.        compatible = "rockchip,rk3568-can-2.0";// Set the device status to "okay", indicating the device is enabled.        assigned-clocks = <&cru CLK_CAN1>;// Allocate the clock source: reference CLK_CAN1 in the CRU (Clock and Reset Unit) node.        assigned-clock-rates = <150000000>;  //If can bitrate lower than 3M, the clock-rates should set 100M, else set 200M. // Set the allocated clock frequency to 150MHz. If the CAN baud rate is lower than 3Mbps, it is recommended to set the clock frequency to 100MHz; otherwise, set it to 200MHz.        pinctrl-names = "default";// Define the name of the pin control state; the default state is "default".        pinctrl-0 = <&can1m1_pins>;// Reference the pin configuration node &can1m1_pins to define the pin muxing and electrical properties of CAN1.};

In addition to enabling the device tree, the corresponding driver must also be enabled in the kernel configuration file. The specific path is as follows:

1234
> Networking support	> CAN bus subsystem support		> CAN Device Drivers		<*> Platform CAN drivers with Netlink support

Porting and usage of CAN tools

iproute2andcan-utilsThey are two essential tools. They provide basic management and advanced operation functions for the CAN interface respectively, helping us easily configure, test, and debug the CAN bus.

Porting the iproute2 tool

iproute2 is a toolset for network management, including commands such as ip, ss, and tc. The corresponding source code archive can be downloaded from the official website.

Compile:

123456
./configure# Modify the Makefile generated by configure, change the following to 'lib ip' to compile and use the ip tool.SUBDIRS=lib ipmake CC=/path/to/linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc

After compilation, the corresponding executable file will be generated in the ip directory. Copy this file to the development board.

Porting canutils tools

canutils is a commonly used CAN communication test toolkit, containing 5 independent programs: canconfig, candump, canecho, cansend, and cansequence. The introduction of each tool is as follows:

Tool NameFunction descriptionMain configuration items / Additional features / Purpose
canconfigUsed to configure parameters of the CAN bus interface.Bitrate
Working mode (Mode), such as loopback mode (Loopback) or normal mode (Normal).
candumpReceives data from the CAN bus interface and prints it to standard output in hexadecimal format.Can save the received data to a specified file.
canechoResends all data received from the CAN bus interface back to the CAN bus interface.Used to test the loopback function of the CAN bus.
cansendSends specified data to the specified CAN bus interface.Data is sent in CAN frame format, including frame ID and frame data.
cansequenceAutomatically sends an incrementing numeric sequence to the specified CAN bus interface; supports receive mode to verify whether the received incrementing numbers are correct.Used to test the data transmission integrity and stability of the CAN bus.

Since canutils depends on the libsocketcan library, you need to compile libsocketcan first, and then compile canutils. The corresponding source code link for libsocketcan is:

Compile:

123456789101112
$ export ARCH=arm64$ export CROSS_COMPILE=/path/to/linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-$ export PATH=$PATH:/path/to/linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/$ ./configure --host=aarch64-linux-gnu --prefix=/home/topeet/can/libsocketcan-0.0.12/out$ make && make install# After compilation, the corresponding files will be generated in the out directory of the current directory.$ ls outinclude lib share

The canutils source code download address is

After decompressing, enter the corresponding directory, andconfig/autoconf/config.subModify the file, add the following contents respectively to add support for aarch64. The modifications are as follows:

12
| aarch64 | aarch64_be \| aarch64-* | aarch64_be-* \

Then modify the configure configuration file, change the compiler on line 2604 to aarch64-linux-gnu-gcc. The modifications are as follows:

1
at_ct_CC=aarch64-linux-gnu-gcc

Compile:

123456789101112131415
$ export ARCH=arm64$ export CROSS_COMPILE=/path/to/linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-$ export PATH=$PATH:/home/topeet/work/linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/$ ./configure \	--host=aarch64-linux-gnu \	--prefix=/path/to/canutils-4.0.6/out \	libsocketcan_LIBS="-L/path/to/libsocketcan-0.0.12/out/lib -lsocketcan" \	libsocketcan_LDFLAGS="-L/path/to/libsocketcan-0.0.12/out/lib" \	libsocketcan_CFLAGS="-I/path/to/libsocketcan-0.0.12/out/include" \	CFLAGS="-I/path/to/libsocketcan-0.0.12/out/include	$ make && make install$ ls out/bin/candump canecho cansend cansequence

Using CAN tools

Set the baud rate of the CAN interface.

The baud rate of the CAN interface can be set using the ip command. For example, the following command sets the baud rate of the CAN0 interface to 250 kbps:

1
ip link set can0 type can bitrate 250000

Starting and stopping the CAN interface

After configuring the CAN interface baud rate, you need to start the CAN interface before it can be used.

  1. Method 1: Using the ifconfig command

ifconfig is a traditional network interface configuration tool. You can start the CAN interface with the following command:

1
ifconfig can0 up

Stopping the CAN interface:

1
ifconfig can0 down
  1. Method 2: Using the ip command

Starting the CAN interface

1
ip link set can0 up

Stopping the CAN interface

1
ip link set can0 down

Checking the CAN interface status

After starting the CAN interface, you can check its status using the ifconfig command and the ip command.

  1. Checking with ifconfig
1
ifconfig can0
  1. Checking with the ip command
1
ip -details link show can0

Testing communication with CAN tools

Receiving data with candump

candump is used to receive data from a CAN bus interface and print it to standard output in hexadecimal format.

Command format:candump <interface> [options]

1
candump can0 -L &
Set filter rules

There are two basic filter formulas:

  • <can id>:<can mask>Match a specific CAN frame

    • Indicates that when the received CAN ID meets the condition<received can id> & mask == can id & maskit matches.
    • The mask determines which bits need to participate in the match; only the bits corresponding to 1 are checked.
    • The can id is the target ID expected to match. This rule is usually used to filter frames that match a specific ID and format, for example, to receive only a certain standard frame or extended frame.
  • <can id>~<can mask>Excluding specific CAN frames is<can id>:<can mask>exactly the opposite, i.e., ignore frames that satisfy
    the condition, and receive all other frames.

    • Indicates that when the received CAN ID meets the condition<received can id> & mask != can id & maskit matches.
  • The CAN ID of a standard frame is 11 bits long, ranging from 0x000 to 0x7FF. In the filter rule, the upper 18 bits of the mask are usually set to 0, indicating that the
    extended frame part is not considered;

  • The CAN ID of an extended frame is 29 bits long, ranging from 0x00000000 to 0x1FFFFFFF. In its filter rule, the lower 11 bits of the mask can be flexibly set to 0 or 1 to decide whether to also match standard frames.

example


Matching a specific extended frame

1
candump can0,12345678:1FFFFFFF
  • Meaning: Only receive extended frames, and the CAN ID exactly matches 0x12345678.
  • Analysis:
    • can id = 0x12345678。
    • mask = 0x1FFFFFFF (matches all 29 bits, and requires an extended frame)

Matching a specific standard frame

1
candump can0,123:C00007FF
  • Meaning: Only receive standard frames, and the CAN ID exactly matches 0x123.
  • Analysis:
    • can id = 0x123。
    • mask = 0xC00007FF: the upper 18 bits are 0xC0000 (ignoring the extended frame part), and the lower 11 bits are 0x7FF (exactly matching the standard frame ID).

Matching standard frames and remote frames

1
candump can0,123:800007FF
  • Meaning: Only receive standard frames or remote frames, and the CAN ID exactly matches 0x123.
  • Analysis:
    • can id = 0x123
    • mask = 0x800007FF: the upper 18 bits are 0x80000 (allowing remote frames), and the lower 11 bits are 0x7FF (exactly matching the standard frame ID).

Excluding a specific extended frame

1
candump can0,12345678~1FFFFFFF
  • Meaning: Exclude extended frames, and the CAN ID exactly matches 0x12345678.
  • Analysis:
    • can id = 0x12345678。
    • mask = 0x1FFFFFFF (matches all 29 bits, and requires an extended frame). Use ~ to indicate exclusion of the match

Multiple matching rules

If you want to apply multiple matching rules, simply append them with commas. For example, only receive standard frames with CAN IDs exactly matching 0x123 and 0x456.

1
candump can0,123:C00007FF,456:C00007FF

Sending data using cansend

cansend is used to send different frames to a CAN bus interface. Examples of sending different frames are as follows:

  • Sending a standard data frame
  • Command format:cansend <interface> <frame ID>#<data>
    • <interface>: CAN interface name (e.g., can0).
  • <frame ID>: The ID of the CAN frame (11 bits, hexadecimal).
    • <data>: The data of the CAN frame (hexadecimal).
  • Example: Send a standard data frame on can0 with ID 0x123 and data DE AD BE EF.
1
cansend can0 123#DEADBEE
  • Send remote frame
    • Command format:cansend <interface> <frame ID>#R
    • R: Indicates a remote frame.
    • Example: Send a standard remote frame to can0 with ID 0x123.
1
cansend can0 123#R
  • Sending an extended data frame
    • Command format:cansend <interface> <frame ID>#<data>
    • <frame ID>: The ID of the CAN frame (29 bits, hexadecimal).
    • Example: Send an extended data frame to can0 with ID 0x00000123 and data 12 34 56 78.
1
cansend can0 00000123#12345678
  • Sending an extended remote frame
    • Command format:cansend <interface> <frame ID>#R
    • R: Indicates a remote frame.
    • Example: Send an extended remote frame to can0 with ID 0x00000123
1
cansend can0 00000123#R

CAN Application Programming

Creating a socket

The socket function is one of the most basic functions in network programming, used to create a socket.

A socket is the basic unit of network communication, providing a mechanism for inter-process communication.. Through the socket, applications can send and receive data packets, thereby achieving network communication.

socket()Used to create a socket, it is thefirst step. After successful creation, the returned socket descriptor is used for subsequentbindlistenconnectsendrecvoperations, etc.

Header file

12
#include <sys/types.h>#include <sys/socket.h>

Function prototype

1
int socket(int domain, int type, int protocol);

Return value

  • Success: Returns a non-negative integer, representing the socket descriptor (socket fd)
  • Failure: returns-1, and setserrno

Parameter description

  1. domainProtocol family (address family)

Specifies the protocol family used for communication, determiningaddress format and communication range. Common values:

Protocol familyDescription
AF_UNIXUsed for local communication (inter-process communication on the same machine), also known as AF_LOCAL.
AF_INETIPv4 Internet protocol family, used for IPv4-based network communication.
AF_INET6IPv6 Internet protocol family, used for IPv6-based network communication.
AF_IPXNovell’s IPX/SPX protocol family, used for Novell networks.
AF_NETLINKCommunication between the kernel and user space, used to receive kernel event notifications.
AF_X25ITU-T X.25/ISO-8208 protocol family, used for packet-switched networks.
AF_AX25Amateur radio AX.25 protocol family, used for amateur radio communication.
AF_ATMPVCUsed to access raw ATM PVCs (Permanent Virtual Circuits); ATM is a high-speed network communication technology.
AF_APPLETALKAppleTalk protocol family, used to connect Mac computers and other devices.
AF_PACKETLow-level packet interface, allowing applications to directly access network devices and send/receive raw packets.
AF_ALGInterface to the kernel cryptographic API, allowing applications to use encryption services provided by the kernel.
PF_CANProtocol family for CAN (Controller Area Network) communication.
  1. typeSocket type

Specifies the data transmission method. Common values:

TypeDescription
SOCK_STREAMStream socket, providing connection-oriented, reliable, bidirectional byte-stream communication (e.g., TCP).
SOCK_DGRAMDatagram socket, providing connectionless, unreliable, fixed-length datagram communication (e.g., UDP).
SOCK_RAWRaw socket, allowing direct access to underlying protocols (e.g., IP, ICMP).
SOCK_SEQPACKETProvides connection-oriented, reliable, fixed-length datagram communication.
  1. protocolProtocol type

Specifies the specific protocol to use, usually set to 0, determined by the system based ondomainandtypeAutomatic selection. Common values:

ProtocolDescriptionCorresponding domain and type
IPPROTO_TCPTCP protocol, used for SOCK_STREAM typeAF_INET or AF_INET6, SOCK_STREAM
IPPROTO_UDPUDP protocol, used for SOCK_DGRAM typeAF_INET or AF_INET6, SOCK_DGRAM
IPPROTO_RAWRaw protocol, used for SOCK_RAW typeAF_INET or AF_INET6, SOCK_RAW
CAN_RAWRaw CAN protocol, used for CAN bus communicationPF_CAN, SOCK_RAW
CAN_BCMBroadcast management protocol, used for more complex CAN communicationPF_CAN, SOCK_DGRAM

Common combination examples

1234567891011121314151617181920
// TCP IPv4 socketint fd = socket(AF_INET, SOCK_STREAM, 0);// UDP IPv4 socketint fd = socket(AF_INET, SOCK_DGRAM, 0);// Local process communicationint fd = socket(AF_UNIX, SOCK_STREAM, 0);// Raw CAN socket (most commonly used)int fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);// Broadcast Manager (BCM) CAN socketint fd = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);// ISO-TP (Transport layer over CAN)int fd = socket(PF_CAN, SOCK_DGRAM, CAN_ISOTP);// J1939 (commercial vehicle protocol)int fd = socket(PF_CAN, SOCK_DGRAM, CAN_J1939);

example

123456789101112131415161718192021
#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <sys/socket.h>#include <linux/can.h>#include <linux/can/raw.h>int main() {	int sockfd;	// Create CAN socket	sockfd = socket(PF_CAN, SOCK_RAW, CAN_RAW);	if (sockfd == -1) {		perror("Socket creation failed");		return EXIT_FAILURE;	}	printf("CAN socket created successfully\n");	// Close socket (optional)	close(sockfd);	return 0;}

Bind the socket

Function introduction

bind()Used to bind a socket tospecified local address

In network programming, it is usually used to bind IP address and port number; in CAN communication in,bind()the main function is to bind the socket tothe specified CAN interface(such ascan0), thereby determining which CAN controller is used for data transmission and reception.

bind()is a CAN socket communicationone of the basic configuration steps, and must be called before data transmission and reception.

Header file

12
#include <sys/types.h>#include <sys/socket.h>

Function prototype

1
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

Return value

  • Success: returns0
  • Failure: returns-1, and setserrno

Parameter description

  • sockfdSocket descriptor

bysocket()The socket file descriptor created by the function, indicating the socket to be bound.

  • addrAddress structure pointer: a structure pointer pointing to the address information to be bound. In different communication scenarios, the actual structure used differs:

    • IPv4struct sockaddr_in

    • IPv6struct sockaddr_in6

    • CANstruct sockaddr_can

When callingbind()when it needs to be cast tostruct sockaddr *type.

  • addrlenAddress structure length: indicatesaddrthe size of the pointed-to address structure, usually usingsizeof()calculate:

    • IPv4:sizeof(struct sockaddr_in)

    • IPv6:sizeof(struct sockaddr_in6)

    • CAN:sizeof(struct sockaddr_can)

bind example in CAN communication

123456
struct sockaddr_can addr;addr.can_family  = AF_CAN;addr.can_ifindex = if_nametoindex("can0");bind(fd, (struct sockaddr *)&addr, sizeof(addr));

Description:

  • can_family: must be set toAF_CAN
  • can_ifindex: specify the CAN interface index (e.g.can0
  • After binding, the socket will only communicate on the specified CAN interface.

example

123456789101112131415161718192021222324252627282930313233343536373839
#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <net/if.h>#include <linux/can.h>#include <linux/can/raw.h>int main(int argc, char *argv[]) {	int sockfd; // Socket descriptor	struct sockaddr_can addr; // CAN address structure	struct ifreq ifr; // Used to obtain network interface information    	// Create CAN socket	sockfd = socket(PF_CAN, SOCK_RAW, CAN_RAW);	if (sockfd < 0) {		printf("Socket creation failed");		return -1;	}	// Specify the CAN interface name to bind	strncpy(ifr.ifr_name, "can0", IFNAMSIZ - 1);	    // Use ioctl to get the index number of the CAN interface	ioctl(sockfd, SIOCGIFINDEX, &ifr)    // Set CAN address structure	addr.can_family = AF_CAN; // CAN address family	addr.can_ifindex = ifr.ifr_ifindex; // CAN interface index number    // Bind the socket to the specified CAN interface	bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))    // close the socket (in actual applications, you can continue sending/receiving data)	close(sockfd);        return 0;}

The above code uses the ioctl system call viaSIOCGIFINDEXmacro to obtain the CAN interface index number, exceptSIOCGIFINDEXBesides the macro, there are macros with other functions in network devices, as shown in the following table:

commandFunction description
SIOCGIFADDRGet the IP address of the network interface
SIOCSIFADDRSet the IP address of the network interface
SIOCGIFNETMASKGet the subnet mask of the network interface
SIOCSIFNETMASKSet the subnet mask of the network interface
SIOCGIFBRDADDRGet the broadcast address of the network interface
SIOCSIFBRDADDRSet the broadcast address of the network interface
SIOCGIFDSTADDRGet the destination address of the network interface (the peer address of a point-to-point interface)
SIOCSIFDSTADDRSet the destination address of the network interface
SIOCGIFHWADDRGet the hardware address of the network interface (e.g., MAC address)
SIOCSIFHWADDRSet the hardware address of the network interface (usually not commonly used, as hardware addresses are mostly fixed)
SIOCGIFINDEXGet the index number of the network interface (a unique identifier assigned by the system)
SIOCSIFMTUSet the maximum transmission unit (MTU) of the network interface
SIOCGIFFLAGSGet the flags of the network interface (e.g., whether it is enabled, whether it is a broadcast interface, etc.)
SIOCSIFFLAGSSet the flags of the network interface

Send/receive data

CAN data cannot be sent directly; it must be encapsulated before transmission.

struct can_frame

CAN data frames are usually represented bystruct can_framea structure. This structure is defined in<linux/can.h>the header file, used to encapsulate the CAN data to be sent. The contents of the structure are as follows:

12345
struct can_frame {	canid_t can_id; // CAN identifier (ID)	__u8 can_dlc; // Data length code (DLC), indicating the length of the data field (0 to 8 bytes)	__u8 data[8]; // Data field, up to 8 bytes};
  • can_id: can_id is a 32-bit unsigned integer field used to represent the CAN identifier (ID).
    • For standard frames, the lower 11 bits of can_id represent the identifier;
    • For extended frames, the lower 29 bits represent the identifier.
    • Bit 30 is used to identify whether it is a remote frame (via CAN_RTR_FLAG flag).
    • The highest bit (bit 31) is used to identify whether it is an extended frame (via CAN_EFF_FLAG flag),
  • can_dlc: can_dlc is an 8-bit unsigned integer field that indicates the length of the data field in a CAN data frame. Its value ranges from 0 to 8, corresponding to the maximum supported 8-byte data length in the classic CAN protocol.
    • For CAN FD (Flexible Data-rate CAN), can_dlc can support larger data lengths (e.g., 64 bytes). This field determines the actual number of data bytes sent or received; unused portions are ignored.
  • data: data is an 8-byte array field used to store the actual data content to be sent or received.
    • The actual length of the data is determined by the can_dlc field, with a maximum of 8 bytes (classic CAN) or larger (CAN FD).
    • Unused portions of the array are not transmitted, so only valid bytes need to be filled when encapsulating data.

Example:

123456789101112131415
struct can_frame frame[3]; // CAN frame arrayunsigned char data[2] = {0x01, 0x02}; // Data contentframe[0].can_id = 0x11; // Standard frame IDframe[0].can_dlc = 2; // Data length (2 bytes)memcpy(frame[0].data, data, 2); // Fill dataframe[1].can_id = 0x11 | CAN_EFF_FLAG; // Extended frame IDframe[1].can_dlc = 2; // Data length (2 bytes)memcpy(frame[1].data, data, 2);// Fill dataframe[2].can_id = 0x11 | CAN_RTR_FLAG; // Remote frame IDframe[2].can_dlc = 2;// Data length (2 bytes)

example

Send data

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <net/if.h>#include <linux/can.h>#include <linux/can/raw.h> // Contains CAN_RAW related definitionsint main(int argc, char *argv[]) {    int sockfd; // Socket descriptor    struct sockaddr_can addr; // CAN address structure    struct ifreq ifr; // Used to obtain network interface information    int ret; // Used to store the return value of system calls    // Create CAN socket    sockfd = socket(PF_CAN, SOCK_RAW, CAN_RAW);    if (sockfd < 0) {        printf("Socket creation failed");        return -1;    }    // Specify the CAN interface name to bind    strncpy(ifr.ifr_name, "can0", IFNAMSIZ - 1);    // Use ioctl to get the index number of the CAN interface    if (ioctl(sockfd, SIOCGIFINDEX, &ifr) < 0) {        printf("ioctl failed");        close(sockfd);        return -1;    }    // Set CAN address structure    addr.can_family = AF_CAN; // CAN address family    addr.can_ifindex = ifr.ifr_ifindex; // CAN interface index number    // Bind the socket to the specified CAN interface    if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {        printf("Bind failed");        close(sockfd);        return -1;    }    // Define CAN frame array    struct can_frame frame[3]; // CAN frame array    unsigned char data[2] = {0x01, 0x02}; // Data content    // Initialize standard frame    frame[0].can_id = 0x11; // Standard frame ID    frame[0].can_dlc = 2;   // Data length (2 bytes)    memcpy(frame[0].data, data, 2); // Fill data    // Initialize extended frame    frame[1].can_id = 0x11 | CAN_EFF_FLAG; // Extended frame ID    frame[1].can_dlc = 2;                 // Data length (2 bytes)    memcpy(frame[1].data, data, 2);       // Fill data    // Initialize remote frame    frame[2].can_id = 0x11 | CAN_RTR_FLAG; // Remote frame ID    frame[2].can_dlc = 2;                 // Data length (2 bytes)    // Send CAN frames in a loop    while (1) {        // Send standard frame        ret = write(sockfd, &frame[0], sizeof(frame[0]));        if (ret != sizeof(frame[0])) {            printf("write (标准帧)");            break;        }        printf("标准帧发送成功!\n");        // Send extended frame        ret = write(sockfd, &frame[1], sizeof(frame[1]));        if (ret != sizeof(frame[1])) {            printf("write (扩展帧)");            break;        }        printf("扩展帧发送成功!\n");        // Send remote frame        ret = write(sockfd, &frame[2], sizeof(frame[2]));        if (ret != sizeof(frame[2])) {            printf("write (远程帧)");            break;        }        printf("远程帧发送成功!\n");        // Delay 1 second        sleep(1);    }    // Close socket    close(sockfd);    return 0;}

Receive data

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <net/if.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <linux/can.h>#include <linux/can/raw.h>#define BUF_SIZE 128 // Buffer sizeint main() {    int sockfd; // Socket file descriptor    struct sockaddr_can addr; // CAN address structure    struct ifreq ifr; // Network interface request structure    struct can_frame frame; // CAN frame structure    char buf[BUF_SIZE]; // Formatted output buffer    int ret, n, i, err;    FILE *out = stdout; // Output file stream (standard output)    // Create CAN socket    sockfd = socket(PF_CAN, SOCK_RAW, CAN_RAW);    // Specify CAN interface name    strcpy(ifr.ifr_name, "can0");    ioctl(sockfd, SIOCGIFINDEX, &ifr);    // Set address information    addr.can_family = AF_CAN;    addr.can_ifindex = ifr.ifr_ifindex;    // Bind CAN interface    bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));    // Loop receiving CAN frames    while (1) {        // Receive CAN frame        ret = read(sockfd, &frame, sizeof(frame));        if (ret <= 0) {            printf("read");            break;        }        // Format and output CAN frame information        if (frame.can_id & CAN_EFF_FLAG) {            // Extended frame            n = snprintf(buf, BUF_SIZE, "<0x%08x>", frame.can_id & CAN_EFF_MASK);        } else {            // Standard frame            n = snprintf(buf, BUF_SIZE, "<0x%03x>", frame.can_id & CAN_SFF_MASK);        }        // Add data length        n += snprintf(buf + n, BUF_SIZE - n, "[%d]", frame.can_dlc);        // Add data content        for (i = 0; i < frame.can_dlc; i++) {            n += snprintf(buf + n, BUF_SIZE - n, " %02x", frame.data[i]);        }        // If it is a remote frame        if (frame.can_id & CAN_RTR_FLAG) {            n += snprintf(buf + n, BUF_SIZE - n, " remote request");        }        // Output to standard output        fprintf(out, "%s\n", buf);        // Flush output buffer        err = fflush(out);        if (err < 0) {            perror("fflush");            break;        }    }    // Close socket    close(sockfd);    return 0;}

Filter rule settings

Filter rule settings in CAN applications require the use ofsetsockoptfunction,setsockoptThe main function is to configure the filter rules or other specific options of the CAN socket.

By setting these options, users can control the behavior of the socket, such as filtering specific CAN data frames or adjusting the communication mode. This is one of the important steps to achieve efficient data processing in CAN communication.

setsockopt()

setsockopt()Used to set various for the socketprotocol-related options. In CAN Socket communication in, it is mainly used for:

  • Set CAN frame filtering rules
  • Control whether to receive error frames
  • Configure behaviors such as local loopback

Among them, one of the most commonly used and core configurations of CAN communication is CAN_RAW_FILTER, used to specify the socketwhich CAN frames to receive.

Header file

12
#include <sys/types.h>#include <sys/socket.h>

Function prototype

12345
int setsockopt(int sockfd,               int level,               int optname,               const void *optval,               socklen_t optlen);

Return value

  • Success: returns0
  • Failure: returns-1, and setserrno

Parameter description

  • sockfdSocket descriptor, bysocket()the created CAN socket file descriptor, indicating the socket to be configured.

  • levelOption level, specifying the protocol layer to which the option belongs. In CAN communication, it is fixed to useSOL_CAN_RAWindicating that what is set is raw CAN protocol (CAN_RAW) related options

  • optnameSpecific option name, specifying the CAN socket option to be set. Common options include:

    • CAN_RAW_FILTER: set the CAN data frame’sfilter rules(key point of this chapter)
    • CAN_RAW_ERR_FILTER: set whether to receive error frames
    • CAN_RAW_LOOPBACK: set whether to enable local loopback mode
  • optval: option value pointer, pointing to the buffer of the option data.

    • ForCAN_RAW_FILTER, type isstruct can_filter *
      • can be a single filter rule
      • or can be an array of filter rules
  • optlen: option value length, indicatingoptvalbuffer size (in bytes):

    • single filter rule:sizeof(struct can_filter)

    • multiple filter rules:sizeof(struct can_filter) * number of rules

Example:

only receive standard frames with ID 0x123

12345678
struct can_filter filter;filter.can_id   = 0x123;filter.can_mask = CAN_SFF_MASK;setsockopt(fd, SOL_CAN_RAW,           CAN_RAW_FILTER,           &filter, sizeof(filter));

Set multiple filter rules

12345678
struct can_filter filters[2] = {    { .can_id = 0x100, .can_mask = CAN_SFF_MASK },    { .can_id = 0x200, .can_mask = CAN_SFF_MASK }};setsockopt(fd, SOL_CAN_RAW,           CAN_RAW_FILTER,           filters, sizeof(filters));

Receive all CAN frames (disable filtering)

123
setsockopt(fd, SOL_CAN_RAW,           CAN_RAW_FILTER,           NULL, 0);

struct can_filter

CAN filter rule structure

1234
struct can_filter {    canid_t can_id;    // CAN ID + flags    canid_t can_mask;  // Mask, determines which bits participate in matching};
  • can_id

    • Indicates the expected CAN ID to match

    • Can include:

      • Standard frame ID (11 bits)
      • Extended frame ID (29 bits)
      • Flags (e.g.,CAN_EFF_FLAGCAN_RTR_FLAG
  • can_mask

    • Used to specify Which bits need to participate in matching

    • A certain bit is:

      • 1: This bit must match
      • 0: This bit is ignored

Common CAN mask macros

Mask valuemeaningExample code and usage
CAN_SFF_MASKMatch the lower 11 bits of standard frames (0x7FF), ignore the extended frame partcan_id=0x123, can_mask=CAN_SFF_MASK
Only receive standard frames with ID exactly matching 0x123
CAN_EFF_MASKMatch all 29 bits of extended frames (0x1FFFFFFF)can_id=0x12345678, can_mask=CAN_EFF_MASK
Only receive extended frames with ID exactly matching 0x12345678
CAN_EFF_FLAGMatch the extended frame flag (bit 31)can_mask=CAN_EFF_FLAG
Distinguish standard/extended frames, only care whether it is an extended frame
CAN_RTR_FLAGMatch the remote frame flag (bit 30)can_mask=CAN_RTR_FLAG
Distinguish data frame / remote frame, only care whether it is a remote frame
CAN_SFF_MASK | CAN_EFF_FLAGMatch lower 11 bits of standard frame, distinguish whether it is an extended frame`can_id=0x123, can_mask=CAN_SFF_MASK
CAN_EFF_MASK | CAN_RTR_FLAGMatch 29 bits of extended frame, distinguish whether it is a remote frame`can_id=0x12345678, can_mask=CAN_EFF_MASK
CAN_SFF_MASK | CAN_RTR_FLAGMatch lower 11 bits of standard frame, distinguish whether it is a remote frame`can_id=0x123, can_mask=CAN_SFF_MASK
CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAGMatch lower 11 bits of standard frame, distinguish whether it is an extended frame and remote frame`can_id=0x123, can_mask=CAN_SFF_MASK
0xFFFFFFFFMatch all 32 bits (including standard, extended, and remote frame flags)can_id=0x123, can_mask=0xFFFFFFFF
Exactly match a complete CAN ID and frame type
0x0Ignore all bits, match all frames (no filter rules)can_mask=0x0
Receive all frames, no filtering

example

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <net/if.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <linux/can.h>#include <linux/can/raw.h>#define BUF_SIZE 128 // Buffer sizeint main() {    int sockfd; // Socket file descriptor    struct sockaddr_can addr; // CAN address structure    struct ifreq ifr; // Network interface request structure    struct can_frame frame; // CAN frame structure    struct can_filter rfilter[2]; // an array of filter rules    char buf[BUF_SIZE]; // Formatted output buffer    int i, n;    FILE *out = stdout; // Output file stream (standard output)    // Create CAN socket    if ((sockfd = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {        perror("Socket creation failed");        return -1;    }    // Specify CAN interface name    strcpy(ifr.ifr_name, "can0");    if (ioctl(sockfd, SIOCGIFINDEX, &ifr) < 0) {        perror("ioctl failed");        close(sockfd);        return -1;    }    // Set address information    addr.can_family = AF_CAN;    addr.can_ifindex = ifr.ifr_ifindex;    // Bind CAN interface    if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {        perror("Bind failed");        close(sockfd);        return -1;    }    // Set filter rules    // First rule: only accept data frames of standard frames, and ID exactly matches 0x123    rfilter[0].can_id = 0x123; // Target CAN ID    rfilter[0].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; // Match standard frames, exclude extended frames and remote frames    // Second rule: only accept data frames of extended frames, and ID exactly matches 0x456    rfilter[1].can_id = 0x456; // Target CAN ID    rfilter[1].can_mask = CAN_EFF_MASK | CAN_RTR_FLAG; // Match extended frames, exclude remote frames    // Apply filter rules    if (setsockopt(sockfd, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0) {        perror("setsockopt failed");        close(sockfd);        return -1;    }    // Loop receiving CAN frames    while (1) {        // Receive CAN frame        if (read(sockfd, &frame, sizeof(frame)) < 0) {            perror("Read failed");            break;        }        // Format and output CAN frame information        if (frame.can_id & CAN_EFF_FLAG) {            // Extended frame            n = snprintf(buf, BUF_SIZE, "<0x%08x>", frame.can_id & CAN_EFF_MASK);        } else {            // Standard frame            n = snprintf(buf, BUF_SIZE, "<0x%03x>", frame.can_id & CAN_SFF_MASK);        }        // Add data length        n += snprintf(buf + n, BUF_SIZE - n, "[%d]", frame.can_dlc);        // Add data content        for (i = 0; i < frame.can_dlc; i++) {            n += snprintf(buf + n, BUF_SIZE - n, " %02x", frame.data[i]);        }        // If it is a remote frame        if (frame.can_id & CAN_RTR_FLAG) {            n += snprintf(buf + n, BUF_SIZE - n, " remote request");        }        // Output to standard output        fprintf(out, "%s\n", buf);        // Flush output buffer        fflush(out);    }    // Close socket    close(sockfd);    return 0;}
Loading comments…