[QEMU]CAN總線仿真支持

CAN總線仿真提供了通過一個或多個CAN總線(控制器器件“canbus”參數(shù))將多個仿真CAN控制器芯片連接在一起的機制。各個總線可以連接到主機系統(tǒng)CAN API(目前僅支持Linux SocketCAN)。
總線的概念是通用的,可以實現(xiàn)不同的CAN控制器。
最初的提交實現(xiàn)了SJA1000控制器,該控制器很常見,并且得到了大多數(shù)操作系統(tǒng)的驅(qū)動程序的良好支持。
PCI插件卡硬件已被選為第一個實現(xiàn)的CAN接口,因為此類設(shè)備可以輕松連接到具有不同CPU架構(gòu)(x86,PowerPC,Arm等)的系統(tǒng)。
2020年,CTU CAN FD控制器模型已被添加為Jan Charvat學(xué)士論文的一部分。該控制器是完整的開源/設(shè)計/硬件解決方案。該項目的核心設(shè)計師是Ondrej Ille,資金支持由CTU提供,包括大眾汽車子公司在內(nèi)的更多公司。
該項目最初是由Jin Yang在我們的指導(dǎo)下在RTEMS GSoC 2013插槽的框架內(nèi)啟動的,最初的想法是為RTEMS提供通用CAN子系統(tǒng)。但是,缺乏代碼和RTMES測試的通用環(huán)境導(dǎo)致目標(biāo)發(fā)生變化,以提供為測試提供完整仿真環(huán)境的環(huán)境,并且RTEMS GSoC插槽已被捐贈用于QEMU上的CAN硬件仿真工作。
如何對基于 SJA1000 的電路板使用 CAN 仿真的示例
當(dāng)編譯具有CAN PCI支持的QEMU時,可以選擇下一個CAN板之一
CAN總線Kvaser PCI CAN-S(單SJA1000通道)板。QEMU 啟動選項:
-object can-bus,id=canbus0-device kvaser_pci,canbus=canbus0
添加“can-host-socketcan”對象以將設(shè)備連接到主機系統(tǒng) 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”板/設(shè)備型號與主線 Linux 內(nèi)核中包含的“kvaser_pci”驅(qū)動程序兼容并已通過測試。測試的設(shè)置是主機端和來賓端的 Linux 4.9 內(nèi)核。
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 \
主機系統(tǒng)的CAN接口必須配置為適當(dāng)?shù)谋忍芈什⑦M行設(shè)置。配置不會通過總線從模擬設(shè)備傳播到物理主機設(shè)備。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 支持示例
此開源內(nèi)核提供 CAN FD 支持。當(dāng)發(fā)現(xiàn)CAN FD接口具有CAN FD功能時,甚至可以將CAN FD存儲器交付到主機系統(tǒng)。
現(xiàn)在提供 PCIe 板仿真(設(shè)備標(biāo)識符ctucan_pci)。默認(rèn)版本在電路板上定義了兩個 CTU CAN FD 內(nèi)核。
示例如何將 canbus0 總線(虛擬線路)連接到主機 Linux 系統(tǒng)(使用 SocketCAN)和在相應(yīng) PCI 卡上模擬的兩個 CTU CAN FD 內(nèi)核,期望主機系統(tǒng) CAN 總線根據(jù)前面的 SJA1000 部分進行設(shè)置:
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 系統(tǒng)中設(shè)置 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
在客戶機系統(tǒng)中,以及主機系統(tǒng)中的基本 CAN 的下一個命令:
cangen can0
對于不帶比特率開關(guān)的 CAN FD:
cangen can0 -f
并使用比特率開關(guān):
cangen can0 -b
測試可以反之亦然,在來賓系統(tǒng)中生成消息,并在主機和更多組合中捕獲它們。