RPMSG on TorizonCore 6 with Verdin iMX8M-Mini

I started my job with Verdin iMX8M-Mini and TorizonCore 6.
I’ve able to use torizoncore-builder to start from
torizon-core-docker-verdin-imx8mm-Tezi_6.1.0-devel-202212+build.4.tar
and to add weston and chromium containers (bundled); I don’t need portainer.
Basically it’s a “reduced” TorizonCore with evaluation conatiners.

I’m going to add another container with my application (work in progress) and I need RPMSG communication between TorizonCore and Cortex-M.
I found some docs and topics on Toradex website, but some of them are old and so I don’t know where to find the update information flor TorizonCore 6.

As far as I understand, I need a device tree overlay, and I can edit tcbuild.yaml to use it while building my custom image.

customization:
  device-tree:
    overlays:

@hfranco.tx, can you help, please?

1 Like

Hi @vix,

Sorry for the delay. I was making sure everything worked on my side before posting the reply. Thanks for your patience.

I’ll describe the steps required and also the necessary file. Let me know if something is not clear.

First things first, we have two options to boot the cortex M4: using u-boot to launch the coprocessor with the “bootaux” command or using the remoteproc framework, which allows you to load the and start the M4 using the Linux Kernel userspace.

I managed to get both of them working, so let’s start with u-boot.

  1. On TorizonCore 6 and BSP 6, the “bootaux” command is not yet available on u-boot (more information here: Bootaux command in u-boot and boot m4/m7 aux cpu). We’re still under development and this feature will be enabled soon. So, in order to do that, I built my own TorizonCore image with Yocto where I enabled the bootaux with the following u-boot patch:
diff --git a/configs/verdin-imx8mm_defconfig b/configs/verdin-imx8mm_defconfig
index 46d4dd7210..6c3dbfbeaa 100644
--- a/configs/verdin-imx8mm_defconfig
+++ b/configs/verdin-imx8mm_defconfig
@@ -110,3 +110,4 @@ CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_IMX_WATCHDOG=y
 CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_IMX_BOOTAUX=y

As I already built the image, there is no need for you to build it too, I uploaded the TocrizonCore image with “bootaux” enabled here: Download - Toradex File Sharing Platform

  1. Now, you can follow this guide on how to load your rpmsg binary: https://developer.toradex.com/software/real-time/cortex-m/how-to-load-binaries/. Here I tested with the multicore_examples/rpmsg_lite_str_echo_rtos demo.

  2. In order to enable the rpmsg, please use this overlay:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
 * Copyright 2022 Toradex
 */

/dts-v1/;
/plugin/;

#include <dt-bindings/clock/imx8mm-clock.h>

/ {
    compatible = "toradex,verdin-imx8mm";
};

&{/} {
    /* Remote proc device */
    imx8mm-cm4 {
        compatible = "fsl,imx8mm-cm4";
        rsc-da = <0xb8000000>;
        clocks = <&clk IMX8MM_CLK_M4_DIV>;
        mbox-names = "tx", "rx", "rxdb";
        mboxes = <&mu 0 1
              &mu 1 1
              &mu 3 1>;
        memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>, <&m4_reserved>;
        syscon = <&src>;
        fsl,startup-delay-ms = <500>;
    };
};

/* M4 Code reserved area */
&resmem {

    m4_reserved: m4@0x80000000 {
        no-map;
        reg = <0 0x80000000 0 0x1000000>;
    };

    vdev0vring0: vdev0vring0@b8000000 {
        reg = <0 0xb8000000 0 0x8000>;
        no-map;
    };

    vdev0vring1: vdev0vring1@b8008000 {
        reg = <0 0xb8008000 0 0x8000>;
        no-map;
    };

    rsc_table: rsc_table@b80ff000 {
        reg = <0 0xb80ff000 0 0x1000>;
        no-map;
    };

    vdevbuffer: vdevbuffer@b8400000 {
        compatible = "shared-dma-pool";
        reg = <0 0xb8400000 0 0x100000>;
        no-map;
    };
};

/* Enable Mailbox Unit */
&mu {
    status = "okay";
};

You can download the compiled version here (which is also already enabled on the image that I sent you): Download - Toradex File Sharing Platform

  1. Finally, load the kernel module, and the rpmsg should work on your system:
$ sudo modprobe imx_rpmsg_tty

Now, if you don’t want to install the custom image to enable the bootaux feature, you can use the remoteproc device.

  1. Boot your device with the same overlay shown above.
  2. Compile your M4 binary with NXP SDK and copy it to your module. In this case, you will need to use the elf version, in this case, rpmsg_lite_str_echo_rtos_imxcm4.elf was used.
  3. You will need to copy this firmware to the /lib/firmware folder. TorizonCore is read-only, so you can remount this folder as “rw” and move the firmware there. Be aware that this approach should be used only for testing purposes.
$ sudo mount -o remount,rw /usr/
$ sudo mv rpmsg_lite_str_echo_rtos_imxcm4.elf /lib/firmware
  1. Now execute the following commands to boot your remote processor:
$ sudo -s
$ cd /sys/class/remotreproc/remoteproc0/
$ echo stop > state
$ echo rpmsg_lite_str_echo_rtos_imxcm4.elf > firmware
$ echo start > state

Now your M4 will boot with the RPMSG demo (don’t forget to sudo modprobe imx_rpmsg_tty as well).

torizon@verdin-imx8mm-06827384:~$ dmesg | grep -i -E "(rpmsg|rproc)"
[    0.030312] imx rpmsg driver is registered.
[    1.303734] remoteproc remoteproc0: imx-rproc is available
[    1.303780] remoteproc remoteproc0: attaching to imx-rproc
[    1.304347] virtio_rpmsg_bus virtio0: creating channel rpmsg-virtual-tty-channel-1 addr 0x1e
[    1.304435] virtio_rpmsg_bus virtio0: rpmsg host is online
[    1.304466] remoteproc remoteproc0: remote processor imx-rproc is now attached
[   45.078466] imx_rpmsg_tty virtio0.rpmsg-virtual-tty-channel-1.-1.30: new channel: 0x400 -> 0x1e!
[   45.078989] Install rpmsg tty driver!
[   45.084112] rpmsg_tty_cb68 65 6c 6c 6f 20 77 6f 72 6c 64 21              hello world!
[   53.630543] rpmsg_tty_cb68 69 61 67 6f                                   hiago
[   53.632899] rpmsg_tty_cb0d 0a      

Now about the TorizonCore part,

Were you able to use the tcbuild.yaml?
Reference: TorizonCore Builder Tool - Customizing TorizonCore Images | Toradex Developer Center

Sorry for the huge reply, we’re still working to improve our HMP documentation. Let me know if you need anything else.

Best Regards,
Hiago.

Hi Hiago

Thanks for your help.

I tried to flash TorizonCore image you built and I also confirmed bootaux and m4 works fine.

However, nothing is displayed on LCD with the new image. I am using 10"capasitive-touch LCD with Verdin DSI to LVDS Adapter which is not default.

In previously TorizonCore version I used(5.7.0-build.17), I set 3 LCD overlays which worked fine and they are

touch-atmel-mxt_overlay.dtbo, verdin-imx8mm_sn65dsi84-lt170410_overlay.dtbo and verdin-imx8mm_sn65dsi84_overlay.dtbo.

However, in your image, only verdin-imx8mm_hmp_overlay.dtbo is available on /boot/…

verdin-imx8mm_hmp_overlay.dtbo is loaded without error at boot but LCD does not work.

I rollbacked OS to 5.7.0-build.17 but LCD still did not work.

I assume that reconfiguration for overlays is needed or 2nd option should be chosen.

Since currently I and colleges are working separately with linux and m4 firmware, we will try 2nd option sometimes later(next year).

Anyway, I expect LCD works fine with next releasing Torizon version.

If you have a solution to make LCD work, please kindly advise.

PS:

I did not try tcbuild.yaml yet.

BR

UJsugi

Hi @hfranco.tx
thank you.
I started testing and I have some preliminary questions/doubts:

  1. I replaced your image instead of the standard torizon-core-docker-verdin-imx8mm-Tezi_6.1.0-devel-202212+build.4.tar (no changes to the containers) but now nothing is shown on HDMI display.
    On the Verdin docker image ls show the three images as expected (chromium, vivante and my custom next-js), but docker container ls shows nothing. So, no container is running.
    Should I upgrade vivante container too?
    Or do you have idea of the problem?

  2. You refer to multicore_examples/rpmsg_lite_str_echo_rtos, but which target should I use (debug/release vs debug_ddr/release_ddr vs debug_flash/release_flash)?

Hi @vix and @ujsugi,

I created the image only to demonstrate the RPMsg, so I didn’t include the other overlays.
Please, download this image instead: Download - Toradex File Sharing Platform.
This is the image with TorizonCore 6 with only the u-boot patch applied. Then you will need to get the overlay that I sent in my previous reply and copy yourself to TorizonCore (verdin-imx8mm_hmp_overlay.dtbo).

This image doesn’t contain the default evaluation containers because it was built with Yocto. But you can download all the containers from Toradex Docker Hub with the docker pull command.

I recommend you use the release or debug (depends on which case you want to run, the difference is basically the compiler optimization which is higher for “release”) without DDR or flash: ./build_debug.sh or ./build_release.sh.

The difference here is where the binary will be allocated. You can check the linker scripts inside the NXP SDK for more information (inside devices/MIMX8MM3/gcc/). For example, the DDR script will place your binary inside DDR memory and the script without DDR will place your binary inside TCM memory, which has limited space (128 KB) but is faster than DDR.

Please check the i.MX 8M Mini Applications Processor Reference Manual from NXP for more information.

Best Regards,
Hiago.

Hiago

Thanks for quick prompt.

Regarding overlays:

With my environment(Development board and DSI to LVDS adaptor), LCD works fine and GUI is displayed correctly.

(Default setting for Verdin Mini is for DSI to HDMI adaptor and native HDMI is not supported in terms of CPU H/W.)

Overlays I set is “fdt_overlays=verdin-imx8mm_dsi-to-lvds_panel-cap-touch-10inch-lvds_overlay.dtbo verdin-imx8mm_spidev_overlay.dtbo”

I guess that if you use DSI to HDMI adaptor, verdin-imx8mm_dsi-to-hdmi_overlay.dtbo is applied instead of verdin-imx8mm_dsi-to-lvds_panel-cap-touch-10inch-lvds_overlay.dtbo.

Do I make sense?

Regarding rpmsg example:

I have not reached it yet and may be struggling with this issue near future.

In that case, please help and advice.

BR

UJSugi

Hi @ujsugi,

Yes, this overlay should work in this case. Also, you would disable the verdin-imx8mm_dsi-to-lvds_panel-cap-touch-10inch-lvds_overlay.dtbo since you’re using DSI to HDMI now, correct?

Ok no problem, come back when you tested so we can discuss any problems.

Regarding the custom image, I forgot to send the custom layer, (@vix and @ujsugi), so you guys can download it here: Download - Toradex File Sharing Platform

Best Regards,
Hiago.

Hi @hfranco.tx
I have another question:
since the firmware for multicore_examples/rpmsg_lite_str_echo_rtos example uses UART_4 for its debug console (if I’m right - otherwise it could be UART_2), should I disable this UART for Cortex-A processor (in Linux)?
I’m worried about conflicts os possibile issues/contentions.
Canm this be done in the overlay?

Hi @vix,

Yes, you are correct, I missed this part. You can disable the UART4 with your device tree overlay. Although it works without it, the best practice is to disable this node.

Please download the compiled dtbo here: Download - Toradex File Sharing Platform

Source code:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
 * Copyright 2022 Toradex
 */

// Enable RPMSG and the M4 driver

/dts-v1/;
/plugin/;

#include <dt-bindings/clock/imx8mm-clock.h>

/ {
	compatible = "toradex,verdin-imx8mm";

	imx8mm-cm4 {
		compatible = "fsl,imx8mm-cm4";
		rsc-da = <0xb8000000>;
		clocks = <&clk IMX8MM_CLK_M4_DIV>;
		mbox-names = "tx", "rx", "rxdb";
		mboxes = <&mu 0 1
			  &mu 1 1
			  &mu 3 1>;
		memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>, <&m4_reserved>;
		syscon = <&src>;
        	fsl,startup-delay-ms = <500>;
	};
};

&mu {
	status = "okay";
};

&uart4 {
	status = "disabled";
};

&resmem {
	#address-cells = <2>;
	#size-cells = <2>;

	m4_reserved: m4@0x80000000 {
		no-map;
		reg = <0 0x80000000 0 0x1000000>;
	};

	vdev0vring0: vdev0vring0@b8000000 {
		reg = <0 0xb8000000 0 0x8000>;
		no-map;
	};

	vdev0vring1: vdev0vring1@b8008000 {
		reg = <0 0xb8008000 0 0x8000>;
		no-map;
	};

	rsc_table: rsc_table@b80ff000 {
		reg = <0 0xb80ff000 0 0x1000>;
		no-map;
	};

	vdevbuffer: vdevbuffer@b8400000 {
		compatible = "shared-dma-pool";
		reg = <0 0xb8400000 0 0x100000>;
		no-map;
	};

};

Best Regards,
Hiago.

Hi @hfranco.tx

there is an issue with the new dto you uploaded.
If I apply the old one you posted, after I reboot the device I see remoteproc0 under /sys/class/remoteproc
If I apply the new one, remoteproc0 is not creatred under /sys/class/remoteproc

Can you verify, please?

Hi @vix,

Sorry, I missed a closing bracket. This is the new source code (I’ve also added the disable for the uart 4):

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
 * Copyright 2022 Toradex
 */

// Enable RPMSG and the M4 driver

/dts-v1/;
/plugin/;

#include <dt-bindings/clock/imx8mm-clock.h>

/ {
	compatible = "toradex,verdin-imx8mm";
};

&{/} {
	imx8mm-cm4 {
		compatible = "fsl,imx8mm-cm4";
		rsc-da = <0xb8000000>;
		clocks = <&clk IMX8MM_CLK_M4_DIV>;
		mbox-names = "tx", "rx", "rxdb";
		mboxes = <&mu 0 1
			  &mu 1 1
			  &mu 3 1>;
		memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>, <&m4_reserved>;
		syscon = <&src>;
		/*
		 * The "fsl,startup-delay-ms" is required in case of
		 * "fsl,auto-boot" is used. It will make sure the
		 * /lib/firmware is mounted before the imx_rproc driver
		 * tries to launch the M4 firmware.
		 */
		fsl,startup-delay-ms = <500>;
	};
};

&mu {
	status = "okay";
};

&uart4 {
	status = "disabled";
};

&resmem {
	#address-cells = <2>;
	#size-cells = <2>;

	m4_reserved: m4@0x80000000 {
		no-map;
		reg = <0 0x80000000 0 0x1000000>;
	};

	vdev0vring0: vdev0vring0@b8000000 {
		reg = <0 0xb8000000 0 0x8000>;
		no-map;
	};

	vdev0vring1: vdev0vring1@b8008000 {
		reg = <0 0xb8008000 0 0x8000>;
		no-map;
	};

	rsc_table: rsc_table@b80ff000 {
		reg = <0 0xb80ff000 0 0x1000>;
		no-map;
	};

	vdevbuffer: vdevbuffer@b8400000 {
		compatible = "shared-dma-pool";
		reg = <0 0xb8400000 0 0x100000>;
		no-map;
	};

};

Please download the newly compiled dtbo here: Download - Toradex File Sharing Platform

Best Regards,
Hiago.

Hi @hfranco.tx
sorry for the late answer.

Now the overlay is correct and I was able to load the firmware on Cortex-M from Linux (remoteproc). bootaux approach is a little bit confusing to me (I don’t understand ext4ls commands) and I’ve never been able to use it.

When the firmware is started with echo start > state I see that ttyRPMSG30 is created.
Then the output from Cortex-M debug UART shows

RPMSG String Echo FreeRTOS RTOS API Demo...

Nameservice sent, ready for incoming messages...
Get Message From Master Side : "hello world!" [len : 12]

First qauestion: who sends “hello world!” to ttyRPMSG30 from the Linux side?
More or less after 20 seconds doing nothing, I see that the iMX8M-Mini reboots (I don’t know why).
Do you have anhy idea of the reason?

Hi @vix,

Good to know that now it works! The bootaux command to launch the Cortex M4 through u-boot was added to our latest version. If you want, you can test it on nightly builds, but only for testing. The best approach is to wait for a more stable release with this feature enabled. For more information about the ext4 commands, you can check this guide: How to load compiled binaries into Cortex-M | Toradex Developer Center.

The TTY driver from NXP sends the “hello world” message, when you load it with the modprobe command, for example. As soon as the driver is loaded and it detected the RPMSG channel, the Linux driver sends this message. You can check the source code here.

...
/* this needs to be less then (RPMSG_BUF_SIZE - sizeof(struct rpmsg_hdr)) */
#define RPMSG_MAX_SIZE		256
#define MSG		"hello world!"
...

I haven’t seen this behavior. As you’re using TorizonCore 6, can you send me the output of these two commands?

# sudo tdx-info
# sudo tdx-info -dt

This will output information about your module, which will help me to check the versions and try to reproduce it on my side. Thanks!

One more thing I would like to mention, after you opened this thread we added the overlay to our repository, so in our nightly builds the HMP overlay will be inside our image by default, from now on. As I said before, you can test it, but it’s better to wait for a more stable build. You can check the source code here: verdin-imx8mm_hmp_overlay.dts « overlays - device-tree-overlays.git - Sources for Device Tree Overlays

One thing to mention, the

&mu {
	status = "okay";
};

node was removed since the mailbox is already enabled. But this won’t be a problem for you, enabling again won’t cause any issues.

Best Regards,
Hiago.

Hi @hfranco.tx

here is the output from sudo tdx-info

Software summary
------------------------------------------------------------
Bootloader:               U-Boot
Kernel version:           5.15.77-6.1.0-devel+git.a8d2c55c6ae7 #1-TorizonCore SMP PREEMPT Wed Nov 30 05:37:42 -03 2022
Kernel command line:      root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3 ostree=/ostree/boot.1/torizon/d499c845f87aefa8a06a05cbaf558465d77b88a4a65745a7bfd33db07acf1218/0
Distro name:              NAME="TorizonCore"
Distro version:           VERSION_ID=6.1.0-devel-20221222151753-build.0
Hostname:                 verdin-imx8mm-06827409
------------------------------------------------------------

Hardware info
------------------------------------------------------------
HW model:                 Toradex Verdin iMX8M Mini on Verdin Development Board
Toradex version:          0057 V1.1A
Serial number:            06827409
Processor arch:           aarch64
------------------------------------------------------------

and here is the output from sudo tdx-info -dt

Device tree
------------------------------------------------------------
Device tree enabled:      imx8mm-verdin-nonwifi-dev.dtb
Compatible string:        toradex,verdin-imx8mm-nonwifi-devtoradex,verdin-imx8mm-nonwifitoradex,verdin-imx8mmfsl,imx8mm
Device trees available:   
                          imx8mm-verdin-nonwifi-dahlia.dtb
                          imx8mm-verdin-nonwifi-dev.dtb
                          imx8mm-verdin-wifi-dahlia.dtb
                          imx8mm-verdin-wifi-dev.dtb
------------------------------------------------------------

Device tree overlays
------------------------------------------------------------
Overlays enabled:         fdt_overlays=verdin-imx8mm_dsi-to-hdmi_overlay.dtbo verdin-imx8mm_spidev_overlay.dtbo verdin-imx8mm_hmp_overlay.dtbo
Overlays available:
                          display-dpi-lt170410_overlay.dtbo
                          display-edt5.7_overlay.dtbo
                          display-edt7_overlay.dtbo
                          display-fullhd_overlay.dtbo
                          display-lt161010_overlay.dtbo
                          display-lt170410_overlay.dtbo
                          display-vga_overlay.dtbo
                          verdin-imx8mm_20mhz_can1.dtbo
                          verdin-imx8mm_disable_can1.dtbo
                          verdin-imx8mm_dsi-to-hdmi_overlay.dtbo
                          verdin-imx8mm_dsi-to-lvds_panel-cap-touch-10inch-lvds_overlay.dtbo
                          verdin-imx8mm_hmp_overlay.dtbo
                          verdin-imx8mm_ov5640_overlay.dtbo
                          verdin-imx8mm_spidev_overlay.dtbo
------------------------------------------------------------
1 Like

Hi @vix,

Thank you, I will get back to you once I have something.

Best Regards,
Hiago.

Hi @vix,

Unfortunately, I couldn’t reproduce the reboot issue. Here, the code is running for 2 hours almost and nothing happened. Here are the commands that I ran:

$ sudo mount -o remount,rw /usr/
$ sudo mv rpmsg_lite_str_echo_rtos_imxcm4.elf /lib/firmware/
$ cd /sys/class/remoteproc/remoteproc0
$ sudo -s
# echo rpmsg_lite_str_echo_rtos_imxcm4.elf > firmware
# echo start > state
# modprobe imx_rpmsg_tty
# exit
exit
$ echo test > /dev/ttyRPMSG30

First I had to remount the /usr/ to copy my firmware since TorizonCore is read-only inside /usr/. Next, copied the firmware and had to log in as root to access the remoteproc framework. Everything worked as expected:

RPMSG String Echo FreeRTOS RTOS API Demo...

Nameservice sent, ready for incoming messages...
Get Message From Master Side : "hello world!" [len : 12]
Get Message From Master Side : "test" [len : 4]
Get New Line From Master Side
Get Message From Master Side : "test" [len : 4]
Get New Line From Master Side
Get Message From Master Side : "test" [len : 4]
Get New Line From Master Side
Get Message From Master Side : "test" [len : 4]
Get New Line From Master Side

Did you do something different? Or there is something enabled in your image that might be causing this issue?

I would recommend you test in a nightly build, to check if the problem still occurs, like this one: Toradex Download Links (Torizon, Linux BSP, WinCE and Partner Demos) | Toradex Developer Center

Can you also send me your dmesg log?

Let me know if there is something different that I can test on my side.

Best Regards,
Hiago.