Cover image for Linux CAN

Linux CAN


Timeline

Timeline

2026-01-09

init

This article introduces the core features, application areas, and development history of the CAN bus, and discusses in detail the architecture principles and key component roles of two hardware connection methods: the CPU's built-in CAN controller and the SPI-to-CAN module.

Linux Driver Notes

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

Introduction to CAN Bus

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, where all nodes (ECUs) can actively send 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 has high reliability, with built-in CRC checks, error detection and recovery mechanisms, and uses differential signals to enhance resistance to electromagnetic interference.
  • The CAN bus achieves low cost by simplifying wiring and reducing system complexity.

Application Areas

  • Automotive Electronics: Engine control, body modules (lights/windows), diagnostic systems (OBD-II), etc.
  • Industrial Automation: PLC, sensor networks, robot control.
  • Other Fields: Medical devices, aerospace, smart buildings.

Development History

  • 1983: Bosch initiates research on automotive network technology.
  • 1986: Official release of the CAN protocol.
  • 1987: Intel and Philips launch the first CAN controller chip.
  • 1991: CAN 2.0 specification released, first applied in Mercedes-Benz S-Class.
  • 1993: Becomes 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 bandwidth improvement.

CAN Hardware Connection

In CAN hardware connection, there are two cases: the CPU has an integrated CAN controller, or the CPU lacks a CAN controller and requires an external adapter (e.g., SPI to CAN).

CPU with Integrated CAN Controller

The connection diagram for a CPU with an integrated CAN controller is shown below. The CPU communicates directly with the CAN transceiver via the integrated CAN controller, and the CAN transceiver converts digital signals into differential signals suitable for CAN bus transmission (CAN_H and CAN_L)。The CPU can communicate directly with the CAN bus

The CPU comes with a built-in CAN controller
The CPU comes with a built-in CAN controller

ComponentDescription
CPU and CAN ControllerEach CPU communicates with the CAN bus via a CAN controller. The CPU is responsible for handling control logic and data processing tasks, while the CAN controller manages the communication details of the CAN protocol.
CAN TxSignal line for transmitting data. The CPU sends data to the CAN bus through the CAN controller, and this signal line is used to transmit the sent data.
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, and 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, converting the differential signals on the bus back into digital signals recognizable by the CPU.
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), improving anti-interference capability.
120Ω resistorA 120Ω termination 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 termination resistors are especially important in long-distance or multi-device connections.

CPU without CAN controller

The connection diagram for a CPU without a CAN controller is shown below,The CPU communicates with the SPI-to-CAN module via 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 via the SPI protocol, suitable for application scenarios where connection to a CAN network is needed without a direct CAN controller. The termination resistors at both ends of the bus ensure the stability of CAN communication.

No CAN controller inside the CPU
No CAN controller inside the CPU

ComponentDescription
CPU and SPI controllerThe CPU communicates with SPI interface peripherals via 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 memory.
SPI to CAN ConverterThis is a critical 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, enabling devices that originally could only communicate via SPI to communicate with other nodes through the CAN bus.
CAN TxThe signal line for transmitting data, used to send data received from the SPI-to-CAN module onto the CAN bus.
CAN RxThe signal 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, responsible for:
Converting logic level signals (from the converter) into differential signals suitable for CAN bus transmission;
Simultaneously converting the differential signals on the bus back into logic level signals and sending 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;
Improve communication stability, especially in long-distance or multi-node connections.

CAN Electrical Characteristics

The CAN bus uses differential signals for data transmission.

  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 operation 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 Signals and Anti-Interference

The CAN bus transmits data via differential signals, meaning information transfer relies on the voltage difference between CAN_H and CAN_L, rather than individual voltage values. The characteristic of differential signals gives the CAN bus extremely strong anti-interference capability in noisy environments.

Advantages of differential signals

  1. Noise typically affects both CAN_H and CAN_L, but since differential signals rely 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 automotive and industrial control.

Electrical properties and operating states

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

  • Recessive state (logic “1”)When CAN_H and CAN_L have equal voltages(typically 2.5V), indicating**The bus is in an idle state.**At this time, there is no data transmission on the bus, 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 ,it indicatesdata is being transmitted. Specifically, CAN_H is 3.5V, CAN_L is 1.5V, representing logic “0”. The dominant state indicates that the bus is transmitting data, andit has 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

Among them,TJA1040Tis a high-speed CAN transceiver chip produced by NXP. It is 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 label, 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_uBackplane back 20-pin GPIO
CAN1_RX_M0I2C3_SDA_M0GPIO1_A0_uBackplane back 20-pin GPIO
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_uBase plate lead unused
CAN2_RX_M1WIFI_REG_ON_H_GPIO2_B1GPIO2_B1_uBase plate 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. Below 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. Data frames have two formats:
    • Standard format (11-bit identifier) suitable for simpler networks
    • Extended format (29-bit identifier) 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, but instead tells the transmitting unit via the identifier (ID) “I need the data corresponding to this ID.” Remote frames also have standard and extended formats, with a structure similar to data frames but lacking the data field.
  • Error Frame: The error frame is used when a node detects an error to notify other nodes of the error occurrence. It is a special frame used to interrupt the current communication and restart. The error frame consists of an error flag (6 consecutive dominant or recessive bits) and an error delimiter, and is triggered by conditions such as 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 occurs when the receiving node needs more time to process the previous frame. Overload frames can only be sent during the interframe space, and their structure is similar to error frames, 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 frame. It is a time interval that ensures nodes in 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 transmits data from the sending unit to the receiving unit.
Remote FrameA frame that requests data from the sending unit with the same ID by the receiving unit.
Error FrameA frame that notifies other units of an error when an error is detected.
Overload FrameA frame that notifies that the receiving unit 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 core frame type, responsible for carrying actual data content and enabling efficient information transmission between the sending 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 that 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. For this reason, the CAN protocol introducedthe extended data frame, which uses a29-bit identifierto provide 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 a different function, ensuring efficient and secure data transmission. The composition block diagram of the data frame is shown below.

Standard Data Frame
Standard Data Frame

From the above diagram, 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 identify the start of a data frame

It not only notifies the receiving device to prepare for data reception but also synchronizes the clocks of the transmitter and receiver, ensuring correct parsing of subsequent data.

  • Arbitration field(Arbitration Field)

    • ID(11-bit identifier) is mainly used to distinguish message types, priorities, and determine 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). Additionally, 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
    • RO bit(1 reserved bit), the reserved bit is fixed to dominant 0 for future expansion
    • DLC bit(4 bits) indicates the number of bytes contained in the data field (range from 0 to 8 bytes).
  • Data field(Data Field)

    • Data FieldContains up to 8 bytes (64 bits), which 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 check code (15 bits)
    • CRC delimiter (1 bit), fixed as recessive 1, used to clearly mark the end of the CRC field.
    • The receiving device verifies data integrity by recalculating the CRC and comparing it with the received CRC check code.
  • 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 as 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 transmitted completely, 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-bit 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 RO reserved bit + 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 length specified by the DLC bits; the data field is the core part of communication, potentially containing sensor data, control commands, and other actual information.
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 recessive 1 bitsClearly marks the end of the data frame, notifying the receiving device that the data frame transmission is complete, and provides additional time for signal synchronization to ensure correct reception of the next frame.

Standard Format and Extended Format
Standard Format and Extended Format

SRR bit function

The SRR bit in the CAN protocol replaces the RTR bit of standard frames and is located at the original RTR bit position in the arbitration field of extended frames.

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 due to its dominant RTR bit (0). When both frames 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 the 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 extended frames, 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 enabling differentiation between extended and standard frames.

Remote frame

Remote Frameis a special frame type in the CAN protocolused 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 upon receiving the request.

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

Remote frame
Remote frame

  • Start of Frame
    • The start of frame consists of 1 dominant bit (0), identical to that of a data frame, used to mark the beginning of a remote frame.
    • It not only notifies the receiving device to prepare for data reception but also synchronizes the clocks of the transmitter and receiver, ensuring the accuracy of subsequent data parsing.
  • Arbitration Field
    • 11-bit Identifier (ID)
    • Consists of 1 RTR bit (recessive 1),
    • Used to specify the type of data frame being requested, and distinguishes from data frames (dominant 0) via the recessive RTR bit (1), ensuring lower priority than data frames with the same ID. In extended remote frames, the arbitration field expands to a 29-bit identifier (ID), SRR bit (recessive 1), IDE bit (recessive 1), and RTR bit (recessive 1). The SRR bit replaces the RTR bit of standard frames, ensuring extended frames have lower priority than standard data frames during arbitration; the recessive IDE bit (1) identifies the frame as an extended frame.
  • Control Field: Same as the control field in standard data frames and extended data frames.
  • Data Field: Remote framehas no data field, which is the core difference from data frames. 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 checksum
    • 1 recessive CRC delimiter
    • Used to verify whether errors occur during the 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 (Acknowledgment Field)**The ACK field consists of 1 ACK slot bit and 1 recessive ACK delimiter bit. After the 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, while the ACK delimiter is fixed as recessive 1 to mark the end of the ACK field.
  • End of Frame
    • The end of frame consists of 7 consecutive recessive 1 bits, same as the data frame, used to clearly mark the end of the remote frame. It not only tells the receiving device that the remote frame transmission is complete but also provides additional time for signal synchronization, ensuring correct reception of the next frame.
Field NameCompositionFunction
Start of Frame1 dominant 0 bitMarks the start of the remote frame, synchronizes the clocks of the transmitter and receiver, 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; RTR recessive 1 distinguishes it from data frames; the extended frame is compatible with standard frames via SRR and IDE bits, with lower priority than data frames with the same ID.
Control FieldStandard Frame: IDE + R0 + 4-bit DLC bits; Extended Frame: R1 + R0 + 4-bit DLC bitsThe DLC bits indicate the number of bytes in the target data frame (0-8 bytes), but the remote frame itself carries no data; the IDE bit distinguishes between extended and standard frames.
Data FieldNoneClearly indicates that the remote frame is a request frame and does not perform data transmission.
CRC Check Field15-bit CRC check code + 1 recessive CRC delimiterVerifies the correctness of the remote frame transmission process, ensuring the reliability of the request.
ACK Field1-bit ACK slot (filled with dominant bit by receiving node) + 1 recessive ACK delimiterThe receiving node confirms correct reception of the remote frame via the ACK slot, and the ACK delimiter marks the end of this field.
End of Frame7 recessive bits (1)Marks the end of the remote frame, providing signal synchronization time to ensure 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 primarily 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 detects the error, it forcibly interrupts the transmission of the current frame and notifies 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), it is 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 complete.
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 other nodes’ communication.
Error Delimiter8 recessive bitsMarks the end of an 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 typically sent when the receiving node cannot process the received data in time, requesting the transmitting node to delay the next frame. The composition of an overload frame is as follows:

Overload Frame
Overload Frame

  • Overload Flag
    • Consists 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 next frame’s transmission.
    • Multiple nodes can send overload flags simultaneously, and these flags will superimpose to form a longer sequence of dominant bits.
  • Overload Delimiter
    • Consists of 8 consecutive recessive bits (logic 1), used to mark the end of an overload frame.
    • It ensures that all nodes can clearly identify the boundaries of the overload frame and resume normal communication flow after overload handling is complete.
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 the overload frame, helping all nodes identify its boundaries, thereby restoring normal communication flow.

The overload frame consists ofan overload flagandan overload delimiterTwo fields implement the identification and handling of insufficient processing capability at the receiving node.

When the receiving node cannot process data in time, it sends an overload flag (6 dominant bits) to notify other nodes in the network to delay the transmission of the next frame; then, an overload delimiter (8 recessive bits) 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 conditions, avoiding data loss or errors.

Bit Stuffing

Bit stuffing is an important mechanism in the CAN protocol used to ensure signal synchronization during data transmission.

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

Stuffing is only performed from the start of frame to the CRC field to avoid 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 issues 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 bus synchronization issues caused by prolonged ‘0’ or ‘1’ levels, thereby improving communication reliability.

Bit Stuffing Rules

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

This mechanism ensures that there is always a level change on the bus by breaking up potentially long strings of the same level, thereby maintaining synchronization between the transmitter and receiver.

Stuffing Range

Performed from the start of frame to the CRC fieldCRC Data after the field(such as ACK field and frame end)no paddingThis design limits the padding 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 5 consecutive identical polarity bits appear, so no padding is needed.
    • Actual transmitted data: 1100000111
    • The receiver directly recovers the original data: 110000011
  • Example 2:
    • Original data: 0111111
    • Analysis: 5 consecutive '1’s appear, so a ‘0’ is inserted at the 6th bit.
    • Actual transmitted data: 01111101
    • The receiver detects and removes the padding bit, recovering the original data: 0111111
  • Example 3:
    • Original data: 1000001111
    • Analysis: Five consecutive '0’s appear, so a ‘1’ is inserted at the 6th bit. After inserting the ‘1’, five consecutive '1’s appear, so a ‘0’ needs to be added at the last bit.
    • Actual transmitted data: 100000111110
    • The receiver detects and removes the stuffing bits, restoring 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 the CAN waveform above shows only one signal. This is because the waveform was captured by a logic analyzer, which automatically converts the differential signal into a logic signal. Then the waveform is analyzed.

Start of frame

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

Start of frame
Start of frame

Arbitration field

Next is the 12-bit arbitration field, where 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, where bits marked with a red ‘×’ indicate stuffing bits, so they should be ignored during actual analysis. The last RTR bit is dominant (logic 0), so the currently transmitted frame is a data frame.

Arbitration field
Arbitration field

Control field

After the arbitration field comes a 6-bit control field, including 1 IDE bit, 1 reserved bit (R0), and 4 data length code (DLC) bits. As shown in the identification diagram, the IDE bit is dominant (logic 0), so the current frame is a standard frame. The reserved bit R0 defaults to dominant (logic 0), and the last four DLC bits 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 identification diagram, the data to be sent is 00000001, and then the analysis continues.

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 as recessive 1, used to mark the end of the ACK field. The identification diagram is as follows:

ACK Field
ACK Field

Finally, the end of frame consists of 7 consecutive recessive bits (logic 1), used to clearly mark the end of the data frame.

Extended Remote Frame

Remote Frame
Remote Frame

Start of Frame

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

Start of Frame
Start of Frame

Arbitration Field

Next is the 12-bit arbitration field, where 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, where bits marked with a red X indicate stuff bits, so they should be ignored during actual analysis. The last RTR bit is recessive (logic 1), and it can be observed that there are no data bits to be transmitted afterward, so the currently transmitted frame is a remote frame.

image-20260109104015402
image-20260109104015402

Control Field

Following the arbitration field is the 6-bit control field, which includes 1 IDE bit, 1 reserved bit (R0), and 4 data length code (DLC) bits. The identification diagram is shown below. The IDE bit is recessive (logic 1), so the current frame is an extended remote frame. The reserved bit R0 defaults to dominant (logic 0), and the last four DLC bits are 0001. However, since the current frame is a remote frame, no data is transmitted.

Control Field
Control Field

CRC Check Field

The CRC check field consists of 15 bits of CRC check code and 1 CRC delimiter, used to detect errors during data transmission. The identification diagram is shown below. The last CRC delimiter is fixed as recessive 1 to 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), which consists of 2 bits: 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 as recessive 1 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).

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) used to mark the beginning of the data frame, as indicated in the diagram below.

Start of Frame
Start of Frame

Extended Frame

Based on the waveform length and the yellow marker above, 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, where bits marked with a red × indicate stuff bits, so they should be ignored during actual analysis. The SRR bit is a recessive bit (logic 1).

Extended Frame
Extended Frame

Next is the IDE bit, which 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 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. The identification diagram is shown below. The RTR bit is a dominant bit (logic 0), so the currently transmitted frame is an extended data frame. Continue with further analysis:

Extended Frame
Extended Frame

Control Field

The next six bits are the control field, which includes 2 reserved bits (R1 and R0) and 4 data length code (DLC) bits. The identification diagram is shown below. The last four DLC bits 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 carries the actual communication data content. The identification diagram is shown 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, used to detect errors during data transmission. The identification diagram is shown below. The last bit, the CRC delimiter, is fixed as a recessive 1 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 a 1-bit ACK slot and a 1-bit ACK delimiter. After 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 as a recessive 1 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), used to clearly mark the end of the data frame.

Core Mechanisms and Communication Principles of CAN Bus

Bit Time

In CAN bus communication,**bit time refers to the time required to transmit one logical bit,**which 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-upon bit time.

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

Bit Time Segmentation
Bit Time Segmentation

  • 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 based on 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 signal propagation delay on the bus and the response time of the input comparator. Its length is typically 1 to 8 time quanta (TQ), with the specific value 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 delays.

  • Phase Segment 1

Phase Segment 1 is a configurable part of the bit time, typically 1 to 8 time quanta (TQ),mainly used to adjust the position of the sampling point, ensuring it is located in a stable signal region

If a signal edge is detected to arrive early,,it can be achieved by shortening the phase buffer segment 1 to achieve resynchronization,Thus dynamically compensating for the effects of clock deviation or signal jitter.。
  • Phase Segment 2

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

It is mainly used to handle cases where the signal edge arrives late.。If the signal edge is delayed,,it can be compensated by extending the phase buffer segment, 2 achieving resynchronization.,Thus ensuring that the receiving node can sample the signal at the correct time,,improving the reliability of data transmission.。

Role of Bit Time

  1. Ensuring synchronization: By dividing time segments, CAN nodes can dynamically adjust the sampling point when a signal edge occurs, compensating for clock deviation and signal delay, thereby achieving synchronization among multiple nodes.
  2. Improving anti-interference capability: Setting 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. Supporting 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, due to the use of asynchronous communication and the absence of an independent clock line, each node relies on its local crystal oscillator for data transmission. However, clock drift of the crystal oscillator can cause gradual timing offset between nodes, ultimately leading to sampling errors. To address this issue, the CAN protocol implements dynamic timing adjustment through two major mechanisms: hard synchronization and resynchronization:

  1. Hard synchronization forcibly aligns the clocks of all nodes during the frame start phase, eliminating initial phase deviation.
  2. Resynchronization dynamically adjusts the length of the phase buffer segment 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 a separate clock line. This subsection will provide a detailed explanation of hard synchronization and resynchronization.

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) phase, 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 a 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 that edge.

This process can be divided into the following steps:

  • The nodecontinuously monitors level changes during bus idle periods.
  • Whena falling edge of SOF is detected and this 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 times.

Hard synchronization
Hard synchronization

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

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

Resynchronization

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

Unlike hard synchronization, resynchronization is not limited to the start of a frame, butcontinuously functions 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 the 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 sending node’s clock is faster than the receiving node’s clock. 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 sending node’s clock is slower than the receiving node’s clock. The receiving node then delays the sampling point by extending Phase Buffer Segment 2.

This dynamic adjustment process relies on theSynchronization Jump Width (SJW), which defines themaximum 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 within PBS2
When the edge from recessive level to dominant level occurs within PBS2

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

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

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

Arbitration Rules

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

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

Carrier Sensing

Beforesending data, each node first listens to the bus status, and only when the bus is idle (i.e., no other node is transmitting data) is the node allowed to start sending data.

This mechanism is similar to ‘Carrier Sense Multiple Access (CSMA)’ in Ethernet, effectively preventing multiple nodes from seizing the bus simultaneously.

If two or more nodes detect the bus idle and start sending data almost simultaneously,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 recessive level (logic 1), the bus appears recessive;
  • As long as one node sends a dominant level (logic 0), the bus appears dominant.

This mechanism ensures that even if multiple nodes send data simultaneously, the signal on the bus is not corrupted but is dominated by the dominant level. 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 send data simultaneously, they compare their own transmitted ID bit by bit with the actual level on the bus,
    • If a node sends a recessive level (1) but detects a dominant level (0) on the bus, it indicates that a higher-priority node is sending data. This node immediately stops transmitting and enters listening mode, waiting for the next bus idle time to retry sending.
    • If a node sends a dominant level (0) and the bus also shows a dominant level (0), the node continues transmitting, indicating it currently has the highest priority.

Read-back mechanism

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

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

This mechanism ensures that low-priority nodes can withdraw from transmission in time, avoiding interference with the communication of high-priority nodes

Error State

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

Through three different error states: active error state, passive error state, and bus-off state,

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

Active Error State

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

In this state, the node can normally participate 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, notifying other nodes of the current error.

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

Passive Error State

If a node’s Transmit Error Counter (TEC) or Receive Error Counter (REC) exceeds 127 (typically triggered by TEC), the node enters the passive error 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. Additionally, after each transmission, a delay of 8 recessive bits must be inserted before attempting communication again.

It is worth noting that if only a node in the passive error 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 further disturbance to the bus.

To resume communication, the node must detect 128 consecutive occurrences of 11 recessive bits (i.e., the bus being idle for a sufficient period), then reset TEC and REC to 0, thereby returning to the active error state and rejoining bus communication.

This mechanism is designed 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 changes in the Receive Error Counter (REC) and Transmit Error Counter (TEC) are shown in the following table:

Serial NumberConditions for Changes in Receive and Transmit Error CountersTransmit Error Counter (TEC)Receive Error Count (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 count does not increase.+1
2When the first bit detected by the receiving unit after sending the 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 start of an active error flag or overload flag. Thereafter, each time 8 consecutive dominant bits are detected.+8 when transmitting+8 when receiving
7When 8 consecutive dominant bits are detected after a passive error flag.+8 when transmitting+8 when receiving
8When the transmitting unit successfully completes data transmission (when ACK is returned and no error is detected up to the end of frame).±0 when TEC=0, otherwise -1
9When the receiving unit successfully completes data reception (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
10A unit in bus-off state detects 128 consecutive occurrences of 11 recessive bits.TEC=0REC=0

Error Detection Mechanism

The CAN (Controller Area Network) protocol effectively improves communication reliability through various 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

Bit error refers toan error detected when the transmitting unit compares its own output level with the bus level (excluding stuff bits) during communication and finds them inconsistent.

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

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

Since bit errors are detected by the transmitting unit itself, the detecting unit is the transmitting unit.

Stuff Error

A stuff error refers toan error triggered when the receiving unit detects six consecutive identical bits within a segment requiring bit stuffing.

The CAN protocol stipulates that in a bit stuffing segment, a stuffing bit of opposite polarity must be inserted after every five consecutive identical bits to ensure DC balance of the signal.

If the receiving unit detects six consecutive identical bits, 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**an inconsistency between the CRC check value calculated by the receiving unit based on the received data and the actual CRC sequence received in the frame,**which is detected as an error.

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 Errors usually occur in the CRC Within the segment,Its detection unit is the receiving unit。

Format error

A format error refers toAn error triggered when the receiving unit detects a format contrary to the fixed-format bit field while parsing a frame. For example, illegal values in the CRC delimiter, ACK delimiter, or EOF can cause a format error.

This error usually indicates that the frame structure does not comply with the CAN protocol specification.

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

ACK error

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

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

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

ACK The error mainly occurs in the ACK 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 underlying physical signal transmission to the high-level application services, each with specific functions and roles.

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

The CAN protocol mainly focuses on thephysical layerdata link layerandtransport layersome of the functions.

ISO Seven-Layer Network Model

  1. Physical Layer
    The Physical Layer is responsible for the transmission of physical signals between devices, defining the electrical signals, hardware specifications, and communication media required for communication. It covers communication modes (e.g., simplex, half-duplex, full-duplex), signal levels (e.g., high and low levels representing logic 0 and 1), hardware specifications (e.g., cables, connectors, transceivers), and bit timing conditions (e.g., 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 (e.g., frame start, identifier, data field, CRC check), access control methods (e.g., CSMA/CD, CSMA/CA), and error detection and correction mechanisms (e.g., CRC check, ACK response), to ensure the accuracy and integrity of data transmission over 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. It achieves cross-network data transmission through functions such as routing (e.g., static routing, dynamic routing), address management (e.g., IP address allocation), and packet segmentation and reassembly, providing support for communication in complex network environments.

  4. Transport Layer
    The Transport Layer ensures the reliability of data transmission, controlling data sequencing, error recovery, and flow control. It guarantees the consistency, integrity, and efficiency of data during end-to-end transmission through mechanisms such as data transmission sequence control (e.g., sequence numbers, acknowledgment mechanisms), error recovery (e.g., retransmission mechanisms), and flow control (e.g., sliding window protocol).

  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. It coordinates interactions between applications through functions such as session establishment and termination (e.g., handshake protocols), session synchronization (e.g., checkpoint mechanisms), and session recovery (e.g., resumable transfers), improving the stability and efficiency of communication.

  6. Presentation Layer
    The Presentation Layer is responsible for converting data representation formats, ensuring data compatibility between different systems. It enables seamless exchange and processing of data across different platforms and applications through functions such as data format conversion (e.g., text encoding, image formats), data encryption and decryption, and data compression and decompression.

  7. Application Layer
    The application layer provides network service interfaces for applications, implementing 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 data link layer

  • Physical layer in the CAN protocol

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

It also specifies bit timing and the number of samples, 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 types 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 (Medium 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 based on priority, and responds with ACK (acknowledgment) and NACK (negative acknowledgment). Additionally, the MAC sublayer detects and reports CRC errors, stuffing bit errors, bit errors, ACK errors, and format errors, while also having fault confinement capability to automatically distinguish between temporary and persistent errors and isolate faulty nodes.
    • **LLC sublayer (Logical Link Control sublayer)**It is responsible for message reception selection, supporting point-to-point connections, broadcasting, and multicasting. It also provides error recovery functions, controlling retransmission 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.

These two standards have the same definition at the data link layer but differ at the physical layer:

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

Two standards: ISO11898 and ISO11519-2
Two standards: ISO11898 and ISO11519-2

Comparison of the two standards
Comparison of the two standards

Enable CAN

Device tree

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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's 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, due to pin multiplexing issues, there is only one CAN interface. The corresponding schematic section is as follows:

topeet RK3568 CAN1
topeet RK3568 CAN1

It can be seen that CAN1 is used on the development board, while in therk3568.dtsidevice tree, the status of the can1 node is set to disabled, indicating it is not enabled, so there must be an addition to this node in another device tree:

1
2
3
4
5
6
7
8
9
//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>;// Assign 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 assigned 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 multiplexing 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:

1
2
3
4
> Networking support
> CAN bus subsystem support
> CAN Device Drivers
<*> Platform CAN drivers with Netlink support

Porting and Usage of CAN Tools

iproute2andcan-utilsare two indispensable 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 iproute2 Tools

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.

Compilation:

1
2
3
4
5
6
./configure
# Modify the Makefile generated by configure, change it to 'lib ip' to compile and use the ip tool.
SUBDIRS=lib ip

make CC=/path/to/linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x8
6_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 can-utils 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 / Usage
canconfigUsed to configure parameters of the CAN bus interface.Bitrate
Working mode (Mode), such as Loopback mode or Normal mode.
candumpReceive data from the CAN bus interface and print it to standard output in hexadecimal format.The received data can be saved to a specified file.
canechoResend all data received from the CAN bus interface back to the CAN bus interface.Used to test the loopback function of the CAN bus.
cansendSend specified data to the specified CAN bus interface.Data is sent in CAN frame format, including frame ID and frame data.
cansequenceAutomatically send an incrementing number 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, libsocketcan must be compiled first, followed by canutils. The source code link for libsocketcan is:

Compile:

1
2
3
4
5
6
7
8
9
10
11
12
$ export ARCH=arm64
$ export CROSS_COMPILE=/path/to/linux_sdk/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x8
6_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-x8
6_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 out
include lib share

The canutils source code download address is:

After decompression, enter the corresponding directory and modify theconfig/autoconf/config.subfile by adding the following content to support aarch64. The modified file is as follows:

1
2
| aarch64 | aarch64_be \
| aarch64-* | aarch64_be-* \

Then modify the configure configuration file, changing the compiler on line 2604 to aarch64-linux-gnu-gcc. The modification is completed as shown below:

1
at_ct_CC=aarch64-linux-gnu-gcc

Compile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ 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 k:

1
ip link set can0 type can bitrate 250000

Starting and Stopping the CAN Interface

After configuring the baud rate of the CAN interface, you need to start the CAN interface to use it.

  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

Stop the CAN interface:

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

Start the CAN Interface

1
ip link set can0 up

Stop the CAN Interface

1
ip link set can0 down

Check the CAN Interface Status

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

  1. Check using ifconfig
1
ifconfig can0
  1. Check using the ip command
1
ip -details link show can0

Test communication using CAN tools

Receive data using candump

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

Command format:candump <接口> [选项]

1
candump can0 -L &
Set filter rules

Basic filter formulas are divided into two types:

  • <can id>:<can mask>Match specific CAN frames

    • 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 parts where the corresponding bit is 1 will be checked
    • The can id is the target ID expected to match. This rule is typically used to filter frames that meet a specific ID and format, such as only receiving certain standard frames or extended frames.
  • <can id>~<can mask>Exclude specific CAN frames, opposite to<can id>:<can mask>which ignores those that meet
    frames that meet the condition, while receiving all other frames.

    • Indicates that when the received CAN ID meets the condition<received can id> & mask != can id & maskit matches.
  • The CAN ID length of a standard frame is 11 bits, 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 concerned;

  • The CAN ID length of an extended frame is 29 bits, 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


Match 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 it to be an extended frame)

Match 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).

Match standard frames and remote frames

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

Exclude specific extended frames

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

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

Use cansend to send data

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

  • Send standard data frame
  • Command format:cansend <接口> <帧 ID>#<数据>
    • <接口>: CAN interface name (e.g., can0).
  • <帧 ID>: CAN frame ID (11 bits, hexadecimal).
    • <数据>: CAN frame data (hexadecimal).
  • Example: can0 sends a standard data frame with ID 0x123 and data DE AD BE EF.
1
cansend can0 123#DEADBEE
  • Send Remote Frame
    • Command format:cansend <接口> <帧 ID>#R
    • R: Indicates a remote frame.
    • Example: Send a standard remote frame to can0 with ID 0x123.
1
cansend can0 123#R
  • Send Extended Data Frame
    • Command format:cansend <接口> <帧 ID>#<数据>
    • <帧 ID>: CAN frame ID (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
  • Send Extended Remote Frame
    • Command format:cansend <接口> <帧 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

Create a Socket

The socket function is one of the most fundamental 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 sockets, applications can send and receive data packets, thereby enabling network communication.

socket()Used to create a socket, it is thefirst stepof network communication. The socket descriptor returned upon successful creation is used for subsequentbindlistenconnectsendrecvand other operations.

Header File

1
2
#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 file descriptor (socket fd)
  • Failure: Return-1, and seterrno

Parameter Description

  1. domainProtocol Family (Address Family)

Specifies the protocol family used for communication, determiningthe address format and communication scope. 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 kernel and user space, used for receiving 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 to send and 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

Specify the specific protocol to use, usually set to0, which is automatically selected by the system based ondomainandtype. 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// TCP IPv4 socket
int fd = socket(AF_INET, SOCK_STREAM, 0);

// UDP IPv4 socket
int fd = socket(AF_INET, SOCK_DGRAM, 0);

// Local inter-process communication
int fd = socket(AF_UNIX, SOCK_STREAM, 0);

// Raw CAN socket (most common)
int fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);

// Broadcast Manager (BCM) CAN socket
int 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);

Examples

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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 socket

Function introduction

bind()Used to bind a socket toa specified local address

In network programming, it is commonly used to bindIP addresses and port numbers; inCAN communication,bind()its main function is to bind a socket to aspecified CAN interface(such ascan0), thereby determining which CAN controller transmits and receives data.

bind()It is abasic configuration stepin CAN socket communication and must be called before data transmission and reception.

Header file

1
2
#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

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

  • addrAddress Structure Pointer: A pointer to the structure containing the address information to bind. The actual structure used varies in different communication scenarios:

    • IPv4struct sockaddr_in

    • IPv6struct sockaddr_in6

    • CANstruct sockaddr_can

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

  • addrlenAddress Structure Length: Indicates the size of theaddraddress structure pointed to, typically usingsizeof()Calculate:

    • IPv4:sizeof(struct sockaddr_in)

    • IPv6:sizeof(struct sockaddr_in6)

    • CAN:sizeof(struct sockaddr_can)

Bind Example in CAN Communication

1
2
3
4
5
6
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#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 a 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 the 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 practice, data can still be sent/received)
close(s);

return 0;
}

The above code uses the ioctl system call via theSIOCGIFINDEXmacro to obtain the CAN interface index number. In addition to theSIOCGIFINDEXmacro, there are other macros with different functions in network devices, as shown in the table below:

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 (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 uncommon as hardware addresses are mostly fixed)
SIOCGIFINDEXGet the index number of the network interface (system-assigned unique identifier)
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; a packetization operation is required before sending

struct can_frame

CAN data frames are typically represented using thestruct can_framestructure. This structure is defined in the<linux/can.h>header file, used to encapsulate the CAN data to be sent. The content of this structure is as follows:

1
2
3
4
5
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 the CAN_RTR_FLAG flag).
    • The most significant bit (bit 31) is used to identify whether it is an extended frame (via the 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 data length of 8 bytes 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, and 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 more (CAN FD).
    • Unused portions of the array are not transmitted, so only valid bytes need to be filled when encapsulating data.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct can_frame frame[3]; // CAN frame array

unsigned char data[2] = {0x01, 0x02}; // Data content

frame[0].can_id = 0x11; // Standard Frame ID
frame[0].can_dlc = 2; // Data Length (2 bytes)

memcpy(frame[0].data, data, 2); // Padding Data
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);// Padding Data

frame[2].can_id = 0x11 | CAN_RTR_FLAG; // Remote Frame ID
frame[2].can_dlc = 2;// Data Length (2 bytes)

Example

Send Data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#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 definitions

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
int ret; // Used to store system call return value

// 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 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

// Bind 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)

// Loop Send CAN Frame
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#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 Size

int 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 to receive 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 configuration

Filter rule configuration in CAN applications requires the use ofsetsockoptfunction,setsockoptThe main function of 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()is used to set variousprotocol-related options. InCAN Socket communication, it is mainly used for:

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

One of the most commonly used and core configurations of CAN communication is CAN_RAW_FILTER, used to specify which CAN frames the socketreceives.

Header file

1
2
#include <sys/types.h>
#include <sys/socket.h>

Function prototype

1
2
3
4
5
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, created bysocket()The CAN socket file descriptor, representing 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 the setting is foroptions related to the raw CAN protocol (CAN_RAW)

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

    • CAN_RAW_FILTER, setting the CAN data frame’sfilter rules(focus of this chapter)

    • CAN_RAW_ERR_FILTER, setting whether to receive error frames

    • CAN_RAW_LOOPBACK, setting whether to enable local loopback mode

  • optvalOption value pointer, pointing to the buffer of option data.

    • ForCAN_RAW_FILTER, the type isstruct can_filter *
      • Can bea single filter rule
      • or can bean array of filter rules
  • optlenOption value length: indicatesoptvalbuffer size (in bytes):

    • Single filter rule:sizeof(struct can_filter)

    • Multiple filter rules:sizeof(struct can_filter) * 规则数量

Example:

Only receive standard frames with ID 0x123

1
2
3
4
5
6
7
8
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

1
2
3
4
5
6
7
8
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)

1
2
3
setsockopt(fd, SOL_CAN_RAW,
CAN_RAW_FILTER,
NULL, 0);

struct can_filter

CAN filter rule structure

1
2
3
4
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)
      • Flag bits (e.g.,CAN_EFF_FLAGCAN_RTR_FLAG
  • can_mask

    • Used to specifywhich 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 (0x7FF) of standard frames, ignore 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 extended frame flag (bit 30)can_mask=CAN_EFF_FLAG
Distinguish standard/extended frames, only focus on whether it is an extended frame
CAN_RTR_FLAGMatch remote frame flag (bit 31)can_mask=CAN_RTR_FLAG
Distinguish data/remote frames, only focus on whether it is a remote frame
CAN_SFF_MASK | CAN_EFF_FLAGMatch lower 11 bits of standard frames, 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 frames, 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 frames, 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 frames, distinguish whether it is an extended frame and remote frame`can_id=0x123, can_mask=CAN_SFF_MASK
0xFFFFFFFFMatch all 32 bits (including standard frame, extended frame, and remote frame flags)can_id=0x123, can_mask=0xFFFFFFFF
Exact match of a specific complete CAN ID and frame type
0x0Ignore all bits, match all frames (no filter rules)can_mask=0x0
Receive all frames, no filtering

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#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 size

int 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]; // Filter rule array
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 receive standard data frames with ID exactly matching 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 receive extended data frames with ID exactly matching 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 to receive 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;
}