[QEMU]CAN总线仿真支持

CAN总线仿真提供了通过一个或多个CAN总线(控制器器件“canbus”参数)将多个仿真CAN控制器芯片连接在一起的机制。各个总线可以连接到主机系统CAN API(目前仅支持Linux SocketCAN)。
总线的概念是通用的,可以实现不同的CAN控制器。
最初的提交实现了SJA1000控制器,该控制器很常见,并且得到了大多数操作系统的驱动程序的良好支持。
PCI插件卡硬件已被选为第一个实现的CAN接口,因为此类设备可以轻松连接到具有不同CPU架构(x86,PowerPC,Arm等)的系统。
2020年,CTU CAN FD控制器模型已被添加为Jan Charvat学士论文的一部分。该控制器是完整的开源/设计/硬件解决方案。该项目的核心设计师是Ondrej Ille,资金支持由CTU提供,包括大众汽车子公司在内的更多公司。
该项目最初是由Jin Yang在我们的指导下在RTEMS GSoC 2013插槽的框架内启动的,最初的想法是为RTEMS提供通用CAN子系统。但是,缺乏代码和RTMES测试的通用环境导致目标发生变化,以提供为测试提供完整仿真环境的环境,并且RTEMS GSoC插槽已被捐赠用于QEMU上的CAN硬件仿真工作。
如何对基于 SJA1000 的电路板使用 CAN 仿真的示例
当编译具有CAN PCI支持的QEMU时,可以选择下一个CAN板之一
CAN总线Kvaser PCI CAN-S(单SJA1000通道)板。QEMU 启动选项:
-object can-bus,id=canbus0-device kvaser_pci,canbus=canbus0
添加“can-host-socketcan”对象以将设备连接到主机系统 CAN 总线:
-object can-host-socketcan,id=canhost0,if=can0,canbus=canbus0
CAN 总线 PCM-3680I PCI(双通道 SJA1000 通道)仿真:
-object can-bus,id=canbus0-device pcm3680_pci,canbus0=canbus0,canbus1=canbus0
另一个例子:
-object can-bus,id=canbus0-object can-bus,id=canbus1-device pcm3680_pci,canbus0=canbus0,canbus1=canbus1
CAN 总线 MIOe-3680 PCI(双 SJA1000 通道)仿真:
-device mioe3680_pci,canbus0=canbus0
“kvaser_pci”板/设备型号与主线 Linux 内核中包含的“kvaser_pci”驱动程序兼容并已通过测试。测试的设置是主机端和来宾端的 Linux 4.9 内核。
qemu-system-x86_64示例:
qemu-system-x86_64 -accel kvm -kernel /boot/vmlinuz-4.9.0-4-amd64 \ -initrd ramdisk.cpio \ -virtfs local,path=shareddir,security_model=none,mount_tag=shareddir \ -object can-bus,id=canbus0 \ -object can-host-socketcan,id=canhost0,if=can0,canbus=canbus0 \ -device kvaser_pci,canbus=canbus0 \ -nographic -append "console=ttyS0"
qemu-system-arm的例子:
qemu-system-arm -cpu arm1176 -m 256 -M versatilepb \ -kernel kernel-qemu-arm1176-versatilepb \ -hda rpi-wheezy-overlay \ -append "console=ttyAMA0 root=/dev/sda2 ro init=/sbin/init-overlay" \ -nographic \ -virtfs local,path=shareddir,security_model=none,mount_tag=shareddir \ -object can-bus,id=canbus0 \ -object can-host-socketcan,id=canhost0,if=can0,canbus=canbus0 \ -device kvaser_pci,canbus=canbus0,host=can0 \
主机系统的CAN接口必须配置为适当的比特率并进行设置。配置不会通过总线从模拟设备传播到物理主机设备。1 Mbit/s 的配置示例:
ip link set can0 type can bitrate 1000000ip link set can0 up
虚拟(仅限主机本地)可以在主机端而不是物理接口上使用接口:
ip link add dev can0 type vcan
主机端的CAN接口可用于通过“candump”命令分析CAN流量,该命令包含在“can-utils”中:
candump can0
CTU CAN FD 支持示例
此开源内核提供 CAN FD 支持。当发现CAN FD接口具有CAN FD功能时,甚至可以将CAN FD存储器交付到主机系统。
现在提供 PCIe 板仿真(设备标识符ctucan_pci)。默认版本在电路板上定义了两个 CTU CAN FD 内核。
示例如何将 canbus0 总线(虚拟线路)连接到主机 Linux 系统(使用 SocketCAN)和在相应 PCI 卡上模拟的两个 CTU CAN FD 内核,期望主机系统 CAN 总线根据前面的 SJA1000 部分进行设置:
qemu-system-x86_64 -enable-kvm -kernel /boot/vmlinuz-4.19.52+ \ -initrd ramdisk.cpio \ -virtfs local,path=shareddir,security_model=none,mount_tag=shareddir \ -vga cirrus \ -append "console=ttyS0" \ -object can-bus,id=canbus0-bus \ -object can-host-socketcan,if=can0,canbus=canbus0-bus,id=canbus0-socketcan \ -device ctucan_pci,canbus0=canbus0-bus,canbus1=canbus0-bus \ -nographic
在客户机 Linux 系统中设置 CTU CAN FD 控制器:
insmod ctucanfd.ko || modprobe ctucanfd insmod ctucanfd_pci.ko || modprobe ctucanfd_pci for ifc in /sys/class/net/can* ; do if [ -e $ifc/device/vendor ] ; then if ! grep -q 0x1760 $ifc/device/vendor ; then continue; fi else continue; fi if [ -e $ifc/device/device ] ; then if ! grep -q 0xff00 $ifc/device/device ; then continue; fi else continue; fi ifc=$(basename $ifc) /bin/ip link set $ifc type can bitrate 1000000 dbitrate 10000000 fd on /bin/ip link set $ifc up done
该测试可以运行例如:
candump can1
在客户机系统中,以及主机系统中的基本 CAN 的下一个命令:
cangen can0
对于不带比特率开关的 CAN FD:
cangen can0 -f
并使用比特率开关:
cangen can0 -b
测试可以反之亦然,在来宾系统中生成消息,并在主机和更多组合中捕获它们。