Using CAN/CAN FD with Xilinx QEMU



Xilinx CAN/CAN FD Introduction

Using Xilinx QEMU, you can stream real or simulated CAN and CAN FD (flexible data-rate) traffic from your host machine to your guest running inside QEMU seamlessly. 

Xilinx CAN and CAN FD controllers are developed based on SocketCAN and QEMU CAN bus implementation. Versal Adaptive SoC devices support two CAN FDs: CANFD0 and CANFD1. ZynqMP devices support two CANs: CAN0 and CAN1. Bus connection and socketCAN interface for each of the CAN and CAN FD modules can be set through command lines. 

SocketCAN is supported with Linux only. This should already be installed on the host Linux machine if not please install using sudo apt-get install can-utils


We will be using three commands for initializing a CAN and CAN FD device for Xilinx QEMU. These commands will be appended with ARM instance. Below is an explanation for these commands on supported machines:

Machine - DeviceCommandDescription
ZynqMP - CAN-object can-bus,id=canbus0

This command will create a new canbus0.

ZynqMP - CAN-global driver=xlnx.zynqmp-can,property=canbus0,value=canbus0

This connects the CAN0 controller with the above-created canbus0

ZynqMP - CAN-object can-host-socketcan,id=socketcan0,if=vcan0,canbus=canbus0

This connects CAN0 (canbus0) to host system CAN bus(which is virtual CAN socket vcan0 in this example). So, whatever data transferred by CAN0 will be sent to the vcan0 socket which will go to all devices connected to this vcan0 interface.


For CAN FD, we are setting the bus connection in the device tree. We are creating one canfd-bus in DTS and connecting both the CANFD0 and CANFD1 to the common bus. User can create separate buses for both CANFD also. Please check versal-ps-iou.dtsi for more on how we are connecting the bus to CANFD controller in DTS.

Before we launch QEMU with CAN or CAN FD devices, we will need to set up CAN interfaces on the host machine. Linux supports virtual and physical interfaces for both CAN and CAN FD. A virtual interface can be created easily. However, the physical CAN interface will need a physical CAN bus/adapter on the host machine to work. 

Overview of CAN/CAN FD with QEMU

 

How to create virtual CAN/CAN FD interface on Linux host machine

Below commands will create a virtual CAN interface:

sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0

Below commands will create a virtual CAN FD interface:

sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0 mtu 72

How to create physical CAN/CAN FD interface on Linux host machine

The CAN interface of the host system has to be configured for proper bitrate and set up. The configuration is not propagated from emulated devices through the bus to the physical host device.

Below is an example for a configuration with 1Mbit/s bitrate:

ip link set can0 type can bitrate 1000000
ip link set can0 up

Using single CAN with QEMU (for Zynq UltraScale+ MPSoC)

# Append the following to ZynqMP ARM instance:
-object can-bus,id=canbus0 \
-global driver=xlnx.zynqmp-can,property=canbus0,value=canbus0 \
-object can-host-socketcan,id=socketcan0,if=vcan0,canbus=canbus0

# MicroBlaze instance is used same way.

The above example will create a canbus0 on the guest, connect CAN0 to canbus0 and connect CAN0's bus(i.e. canbus0) to vcan0 interface on the host device.

Above QEMU commands can be also used with Petalinux boot. Example: petalinux-boot --qemu --prebuilt 3 --qemu-args='argument list to append'

Using both CAN0 and CAN1 devices with QEMU (for Zynq UltraScale+ MPSoC)

# Append the following to ZynqMP ARM instance:
-object can-bus,id=canbus0 \
-object can-bus,id=canbus1 \
-global driver=xlnx.zynqmp-can,property=canbus0,value=canbus0 \
-global driver=xlnx.zynqmp-can,property=canbus1,value=canbus1 \
-object can-host-socketcan,id=socketcan0,if=vcan0,canbus=canbus0 \
-object can-host-socketcan,id=socketcan1,if=vcan0,canbus=canbus1

# MicroBlaze instance is used same way.

The above example will create two separate can buses, canbus0 and canbus1 on the guest. It will connect CAN0 to canbus0 and CAN1 to canbus1 and both CAN0 and CAN1 to the vcan0 interface on the host device. 

Using both CANFD0 and CANFD1 devices on separate buses with QEMU (for Versal Adaptive SoC)

# Add the following canfdbus1 to versal-ps-iou.dtsi after existing canfdbus0 node:

canfdbus1: canfdbus@0 {
		compatible = "can-bus";
	};

# Change canfd1 node to use canfdbus1:
canfd1: can_core@MM_CANFD1 {
		compatible = "xlnx,versal-canfd";
		rx-fifo0 = <0x40>;
		rx-fifo1 = <0x40>;
		enable-rx-fifo1 = <0x1>;
		canfdbus = <&canfdbus1>;
		interrupts = <CAN1_IRQ_0>;
		reg = <0x0 MM_CANFD1 0x0 MM_CANFD1_SIZE 0x0>;
	};

# Compile the DTS as per instruction in chapter 3 and run QEMU versal with new DTB.

How to dump random data to CAN through virtual can interface

The below command will pump random data to the vcan0 interface. Which will be received by CAN0 and CAN1 if they are connected to vcan0 interface.

cangen -v vcan0
#use cangen -h to know all supported option with cangen utility.

How to dump random data to CAN FD through virtual CAN FD interface

The below command will pump random data to the vcan0 interface. Which will be received by CANFD0 and CANFD1 if they are connected to vcan0 interface.

cangen -v -f vcan0
#use cangen -h to know all supported option with cangen utility.

How to analyze data on the host CAN/CAN FD interface

The CAN interface on the host side can be used to analyze CAN traffic with the candump command which is included in can-utils. This will show any data sent from Xilinx CAN devices in QEMU.

candump vcan0
#use candump -h to know all use cases.


© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy