Plain memory mapped CTU CAN FD with QEMU emulating Zynq ARM target
The mainline QEMU does not support plain memory mapped or platform variant of CTU CAN FD core. But experimental version at branch net-can-ctucanfd-platform of the https://github.com/ppisa/qemu repository adds preliminary dirty support of such emulation.
RTEM has to be compiled for single CPU variant because QEMU emulates only single ARM Cortex-A9 core for this target. The attached configuration arm-rtems-sys.cfg selects arm/xilinx_zynq_a9_qemu BSP and enables RTEMS_POSIX_API.
The rtems-canfd is built for alternative BSP by next command
make RTEMS_MAKEFILE_PATH=/opt/rtems/6/arm-rtems6/xilinx_zynq_a9_qemu all
Then application can be run in development QEMU by
qemu-system-arm -m 1G -M xilinx-zynq-a9 \
-kernel "$APP_BINARY" \
-initrd ramdisk.cpio \
-nographic \
-serial mon:stdio -serial null \
-object can-bus,id=canbus0-bus \
-object can-host-socketcan,if=can0,canbus=canbus0-bus,id=canbus0-socketcan \
-device ctucan_mm,iobase=0x43c30000,irqnum=29,irqctrl=/machine/unattached/device[3],canbus=canbus0-bus \
-device ctucan_mm,iobase=0x43c70000,irqnum=30,irqctrl=/machine/unattached/device[3],canbus=canbus0-bus \
-device ctucan_mm,iobase=0x43bf0000,irqnum=31,irqctrl=/machine/unattached/device[3],canbus=canbus0-bus \
-device ctucan_mm,iobase=0x43bb0000,irqnum=32,irqctrl=/machine/unattached/device[3],canbus=canbus0-bus \
Even device tree CAN be passed which is necessary for use with Linux kernel, but it is not used by RTEMS Zynq target for now.
-dtb zynq-microzed-uart1-2x-xcan-4x-ctu-axi.dtb
When argument '-s' in appended then GDB debugging is activated, when '-s -S' is appended, QEMU stops and waits for GDB connection. GDB can be started with path to the application image ``rtems_app_elf.elf and next command attaches debugger (distribution gdb-multiarch
or `arm-rtems6-gdb`)
target remote localhost:1234
The breakpoints can be specified by hbreak
command which does not need to modify emulated target memory and is breakpoint is resolved on QEMU emulation level.
There is issue with serial console input for some reasons. The output seems to be fully correct and evens are delivered trough zynq_uart_interrupt
correctly. The workaround and for continuous integration even advantage is build applications which start given test directly or select it on base of command line option. The next modification to run the test has been used successfully
--- a/rtems_can_test/init.c
+++ b/rtems_can_test/init.c
@@ -202,6 +202,9 @@ rtems_task Init(rtems_task_argument ignored) {
rtems_shell_add_cmd("ctu_1w", "app", "ctu_1w [count] [delay] [burst]", ctucanfd_can_test_1w);
rtems_shell_add_cmd("ctu_2w", "app", "ctu_2w [count] [delay] [burst]", ctucanfd_can_test_2w);
+ char *argv[] = {"ctucanfd_can_test_2w"};
+ ctucanfd_can_test_2w(1, argv);
+
rtems_task_delete(RTEMS_SELF);
exit(0);