wiki:Developer/Simulators/QEMU/CANEmulation

Version 22 (modified by C Rempel, on Jun 22, 2013 at 10:20:04 PM) (diff)

/* Linux-QEMU environment */

QEMU with CAN Emulation

Device Requirements

# sends CAN packets from a guest OS.

Use Cases / Testing

the best option is to implement that as simple device

-device can-kvasser-pcican-q

or

-device pcican,model=kvasser-pcican-q

and use Linux mainlined SocketCAN API to connect virtual device to real CAN hardware (SocketCAN allows multiple applications access) or to SocketCAN Virtual CAN (vcan - TCP/IP lo equivalent). This is straightforward and would result in minimal overhead and latency.

The OS will be Linux and the current CAN driver to test will be Socket CAN (as it's maintlined into Linux)= Excerpts from the email chain =

Stefan Weil: PCI (and USB if they were supported with LinCAN) CAN controller boards could also be used with x86, so QEMU (with KVM) would be much faster and use lessresources than an ARM system emulation.

So one of the PCI controllers might be the best choice.

Select one with good documentation, complete implementation (on the RTEMS / LinCAN side) and small source code (which is typically an indicator for the complexity - a large complex driver typically also needs a complex emulation in QEMU).= Use Cases =

Paolo Bonzini and > Cynthia Rempel

we want to be able to verify a guest OS's CAN driver has been integrated

properly and is sending CAN packets...

Perhaps along the lines of two calls:

qemu-system-arm -hda linux1.img -can student-implemented-device

qemu-system-arm -hda linux2.img -can student-implemented-device

You would probably use either -net, or -netdev and -device (see docs/qdev-device-use.txt).

Then using a network protocol analyzer (such as Wireshark) with a custom

filter to recognize CAN packets,

OR

qemu-system-arm -hda linux1.img -can student-implemented-device

then attaching a real CAN device to the host computer and verifying that the

output is being recognized be real hardware.

Is this CAN device just an Ethernet device? QEMU does not support other link-level protocols. Adding them would be possible and interesting, however it would add a bit to the complexity.

Whichever is more feasible to implement...

Both would be the same. In the first case, you'd probably use "-netdev socket" to share a virtual network between two virtual machines. In the second, you would use something like "-netdev tap" (again assuming it's just an Ethernet device).

Implementation

Paulo B: Ok, learnt a bit more... You could probably implement this in two ways: 1) "-netdev socket" would probably work as a CAN->UDP gateway;

2) connecting to a virtual CAN interface in the host, created using SocketCAN (similar to "-netdev tap", e.g. "-netdev cantap").

In the first case, it would probably be useful to write the matching UDP->CAN gateway program.

In any case, you have to implement both the backend and the actual device.

Stefan Weil: I used TCP instead of UDP in a proprietary solution more than 10 years ago.

CAN devices are connected to CAN buses, so I had a CAN device emulation (on CAN API level, not on hardware level like with QEMU) and a CAN bus emulation.

The CAN bus emulation was a TCP server process. It could simulate several CAN buses.

Each CAN controller was a TCP client connected to the CAN bus emulation.

The TCP clients sent CAN data packets (length, packet type and data) to the TCP server and received such packets from the server. They also exchanged control packets with the server (topology = which bus, data rate, CAN filter settings).

The CAN bus emulation routed each received packet to other CAN controllers on the same bus (CAN is a broadcast protocol) and could also simulate error packets (for example when there was a mismatch of the data rates between sender and receiver). In debug mode, the bus emulation could also display the packets (raw data or CAN Open packets).

Several CAN vendors provide bidirectional CAN-Ethernet gateways, but I don't know whether there is a standard for CAN-over-Ethernet.

Andreas Färber: Unfortunately that is out of date as far as the code goes (QOM is our successor to qdev), but it might serve as a good starting point. I emailed you my KVM Forum slides on QOM with a device skeleton to use as a starting point.

One point I would like to point out is that QEMU devices don't simulate their hardware counterpart but instead only emulate them - that is, if you implement, e.g., a Freescale MPC5604B FlexCAN or Renesas RX62N RCAN controller you will deal with register accesses coming from the guest and their abstract concepts like mailboxes and objects rather than actual line-encodings. So if you want, you might get around some of the gory details by implementing the device using an abstract CANBus bus implementation (cf. PCIBus, I2CBus, etc.) and if necessary interfacing with whatever CAN API on the host directly; if you need to externalize this through a -chardev command line option for analysis, it probably requires some more work.

Pavel Pisa: 1) I think that for Linux the best option is to implement that as simple device

-device can-kvasser-pcican-q

or

-device pcican,model=kvasser-pcican-q

and use Linux mainlined SocketCAN API to connect virtual device to real CAN hardware (SocketCAN allows multiple applications access) or to SocketCAN Virtual CAN (vcan - TCP/IP lo equivalent). This is straightforward and would result in minimal overhead and latency.

2) If the portability is a problem, then we can create UDP socket and use it send CAN messages as packets (but it is newer able to model and pas over real CAN bus behavior, i.e. there are no silently lost messages on CAN side due to ACK). We have done prototype of SocketCAN to Ethernet gateway (in user-space and in Linux kernel) on contract with SocketCAN project. So we can offer some part of the code for reuse. Code is open/GPLed.

3) The option is to provide both above method or even pull in OrtCAN VCA (virtual can API) library which can route CAN messages to SocketCAN, LinCAN and possibly other targets.

Problem is that there is knowledge but amount of work could easily exceed RTEMS GSoC resources. So I would incline personally to 1). But opinions, help, documentation etc are welcomed.

Andreas Farber: While using a model property is not wrong per se, "can" seems too generic as type name, since it needs to inherit from a particular base class such as PCIDevice. QOM types can be made abstract to share code between device implementations to the same effect, e.g. PCIHostState.

Submitting a Patch to Qemu

fundamental requirements for new contributions:

Detail

The CAN simulation environment is based on QEMU-1.4.2, you can download it from https://github.com/Jin-Yang/QEMU-1.4.2 or get a copy using the following command(Linux)

git clone https://github.com/Jin-Yang/QEMU-1.4.2.git .

Then you can build it through

./configure --prefix=/opt/qemu && make && make install

RTEMS environment

You can get a basic simulation environment from https://github.com/Jin-Yang/RTEMS-QEMU. This is a simple environment. However before run the RTEMS, environment variables 'PATH' and 'RTEMS_MAKEFILE_PATH' should be added to ~/.bashrc, such as

export PATH=/opt/rtems-4.10/bin:${PATH} export RTEMS_MAKEFILE_PATH=/opt/rtems-4.10/i386-rtems4.10/pc386

Then, you can run it just using

./qemu

Source file located at examples-v2/ and before runing, rtems-grub.cfg should be edited too.

Linux-QEMU environment

In this section, the environment is based on QEMU-1.4.2, linux-3.4.48, busybox-1.21.0 and Ubuntu 13.04. You can get those source file from their offical website.

  • Build the Linux kernel

You can build through a default configration.

make i386_defconfig make bzImage

However, this will waste a lot of time on compiling and running something which we do not need. So, we build a minimal kernel through the following commands.

cd linux-3.4.48 make allnoconfig make menuconfig # Detailed intructions below make bzImage

In the 'make menuconfig' step we will chose

  • Bus options (PCI etc.)
    • PCI support
      • PCI Express support
      • Root Port Advanced Error Reporting support
  • Executable file formats / Emulations
    • Kernel support for ELF binaries
  • Device Drivers
    • SCSI device support
      • SCSI disk support
      • SCSI generic support
    • Serial ATA and Parallel ATA drivers
      • ATA SFF support
        • ATA BMDMA support
          • Intel ESB, ICH ,PIIX3, PIIX4 PATA/SATA support
    • Character devices
      • Serial drivers
        • 8250/16550 and compatible serial support
        • Console on 8250/16550 serial ports
  • File systems
    • Ext3 journalling file system support
  • Build a root file system

This can be done through the following commands.

dd if=/dev/zero of=rootfs.img bs=1024 count=80000 mkfs.ext3 rootfs.img mkdir rootfs sudo mount -t ext3 -o loop rootfs.img rootfs cd rootfs mkdir dev proc sys ...... and some config files.

  • Build the basic commands through busybox tar -xf busybox-1.20.0.tar.bz2 cd busybox-1.20.0 make defconfig make menuconfig make make install CONFIG_PREFIX=~/qemu/rootfs
  • Start qemu qemu-system-i386 -s kernel bzImage -hda rootfs.img -append "root=/dev/sda init=/sbin/init"

If you want to see what has displayed to screen, you can use

qemu-system-i386 -s kernel ~/linux-3.4.48/arch/i386/boot/bzImage \ -hda ~/qemu/rootfs.img \ -serial file:./linux-start.log \ -append "root=/dev/sda init=/sbin/init console=ttyS0"

Adding Qemu to the RTEMS Source Builder

Although not necessarily part of the CAN project one interesting issue that came up was the need to hook qemu into the RTEMS Source Builder for gcc-testing purposes.

The issues brought up with adding qemu to the RTEMS Source Builder included the question of how to build qemu on all supported host platforms, in particular, how to build qemu from source on Windows and Mac (in addition to Linux).

Some resources for building on Windows are:

MinGW # http://wiki.qemu.org/Hosts/W32#Native_builds # http://www.mingw.org/wiki/Bootstrapping_GLIB_with_MinGW

Cygwin # http://cygwin.com/packages/

Some resources for building on Mac are: # http://www.rubenerd.com/qemu-1-macosx/

References

# https://lists.gnu.org/archive/html/qemu-devel/2013-05/threads.html # http://www.linux-kvm.org/wiki/images/f/f6/2012-forum-QOM_CPU.pdf