M4 app stuck on rpmsg_lite_is_link_up

I am trying to use RPMSG to communicate with my linux host; however my M4 app is stuck on this line of code:

while (0 == rpmsg_lite_is_link_up(my_rpmsg));

I have my m4.bin placed in the /boot directory and I followed the following steps in uboot:

    dcache flush; bootaux ${loadaddr} 
    run bootcmd 

When I boot into linux I run the command:
modprobe imx_rpmsg_tty But I am not able to see RPMSG mounted in /dev.

I am using the latest Kirkstone Image: Image 6.3.0-devel-20230626+build.320.

I tried the same application on the latest dunfell (5.2.x) image and everything works as expected.

Colibri IMX8QXP 2GB
Colibri Evaluation Board
Colibri Reference Minimal Image 6.3.0-devel-20230626+build.320

Hi @nmohan86,

Do you have any device tree changes or overlays to share with us that will enable the rpmsg feature?
To correctly set up and enable rpmsg, a device tree node is needed.

Best Regards,
Hiago.

This is what I have:

&cm40_lpuart {
    status = "disabled";
};

&cm40_uart_lpcg {
    status = "disabled";
};

&adc0 {
    status = "disabled";
};

Is there anything else I need? I used the same changes in the dunfell image.

Hi @nmohan86,

Please, check this overlay instead:

// Enable RPMSG for Colibri iMX8X

/dts-v1/;
/plugin/;

/ {
	compatible = "toradex,colibri-imx8x";
};

&{/} {
	reserved-memory {

		#address-cells = <2>;
		#size-cells = <2>;
		ranges;

		m4_reserved: m4_reserved@0x34fe0000 {
			no-map;
			reg = <0 0x34fe0000 0 0x40000>;
		};

		rpmsg_reserved: rpmsg_reserved@90000000 {
			compatible = "shared-dma-pool";
			no-map;
			reg = <0 0x90000000 0 0x20000>;
		};

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

	rpmsg: rpmsg@0 {
		compatible = "fsl,imx8qxp-rpmsg";
		mbox-names = "tx", "rx", "rxdb";
		mboxes = <&lsio_mu5 0 1
			  &lsio_mu5 1 1
			  &lsio_mu5 3 1>;
		mub-partition = <3>;
		vdev-nums = <2>;
		reg = <0 0x90000000 0 0x20000>;
	};
};

Here is the compiled version for BSP 6/TorizonCore 6, if you need it:
colibri-imx8x_hmp_overlay.dtbo (1.3 KB)

Here I enabled this overlay and made a quick test with the following binary:

Colibri iMX8X # load mmc 0:2 ${loadaddr} /home/root/rpmsg_lite_str_echo_rtos.bin
67720 bytes read in 5 ms (12.9 MiB/s)
Colibri iMX8X # bootaux ${loadaddr} 
Power on aux core 0
Copy image from 0x95c00000 to 0x34fe0000
Start M4
bootaux complete

After I booted the module, I can see the dmesg messages about rpmsg and also I can modprobe the NXP driver:

root@colibri-imx8x-06760719:~# dmesg | grep -i rpmsg
[    0.000000] OF: reserved mem: initialized node rpmsg_reserved@90000000, compatible id shared-dma-pool
[    0.277831] imx rpmsg driver is registered.
[    2.075611] virtio_rpmsg_bus virtio0: rpmsg host is online
[    2.083779] virtio_rpmsg_bus virtio0: creating channel rpmsg-i2c-channel addr 0x1
[    2.096520] i2c-rpmsg virtio0.rpmsg-i2c-channel.-1.1: new channel: 0x400 -> 0x1!
[    2.119727] virtio_rpmsg_bus virtio1: rpmsg host is online
[    2.127902] virtio_rpmsg_bus virtio1: creating channel rpmsg-openamp-demo-channel addr 0x1e
root@colibri-imx8x-06760719:~# modprobe imx_rpmsg_tty
[  715.658073] imx_rpmsg_tty virtio1.rpmsg-openamp-demo-channel.-1.30: new channel: 0x400 -> 0x1e!
[  715.667135] Install rpmsg tty driver!
root@colibri-imx8x-06760719:~# 

Please, if you see an error on u-boot with this overlay, run these commands on your u-boot terminal:

# setenv fdt_high 0xffffffffffffffff
# saveenv
# reset

Then it should fix the issue.

Let me know if you have any questions.

Edit: One more thing to mention, I had to patch the MCUXpresso example from NXP to use the available UART pins on the Colibri Development board, since the default one are not available:

diff --git a/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.c b/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.c
index 7339c00..391d914 100644
--- a/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.c
+++ b/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.c
@@ -70,12 +70,12 @@ void BOARD_InitPins(sc_ipc_t ipc)                          /*!< Function assigne
   {
       assert(false);
   }
-  err = sc_pad_set_all(ipc, BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID, 1U, SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_ADC_IN2 register modification value */
+  err = sc_pad_set_all(ipc, BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID, 2U, SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_ADC_IN2 register modification value */
   if (SC_ERR_NONE != err)
   {
       assert(false);
   }
-  err = sc_pad_set_all(ipc, BOARD_INITPINS_M40_UART0_TX_PIN_FUNCTION_ID, 1U, SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_ADC_IN3 register modification value */
+  err = sc_pad_set_all(ipc, BOARD_INITPINS_M40_UART0_TX_PIN_FUNCTION_ID, 2U, SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_ADC_IN3 register modification value */
   if (SC_ERR_NONE != err)
   {
       assert(false);
diff --git a/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.h b/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.h
index 900d8ef..dbda7f9 100644
--- a/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.h
+++ b/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.h
@@ -14,10 +14,10 @@
  **********************************************************************************************************************/
 
 /* ADC_IN2 (coord V32), M40_UART0_RX */
-#define BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID                 SC_P_ADC_IN2   /*!< Pin function id */
+#define BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID                 SC_P_SCU_GPIO0_00   /*!< Pin function id */
 
 /* ADC_IN3 (coord V30), M40_UART0_TX */
-#define BOARD_INITPINS_M40_UART0_TX_PIN_FUNCTION_ID                 SC_P_ADC_IN3   /*!< Pin function id */
+#define BOARD_INITPINS_M40_UART0_TX_PIN_FUNCTION_ID                 SC_P_SCU_GPIO0_01   /*!< Pin function id */
 
 /* ADC_IN0 (coord U35), M4_I2C0_1V8_SCL */
 #define BOARD_INITPINS_M4_I2C0_1V8_SCL_PIN_FUNCTION_ID              SC_P_ADC_IN0   /*!< Pin function id */

Best Regards,
Hiago.

I tried the above I am not getting past rpmsg_lite_is_link_up()

however I am not able to see rpmsg come up on the linux side:

root@colibri-imx8x:~# dmesg |grep -i rpmsg
[    0.000000] OF: reserved mem: initialized node rpmsg_reserved@90000000, compatible id shared-dma-pool
[    0.314247] imx rpmsg driver is registered.
[    2.079299] virtio_rpmsg_bus virtio0: rpmsg host is online
[    2.089087] virtio_rpmsg_bus virtio1: msg received with no recipient
[    2.097122] virtio_rpmsg_bus virtio1: rpmsg host is online
root@colibri-imx8x:~# modprobe imx_rpmsg_tty

Hi @nmohan86,

After the modprobe, does the device /dev/ttyRPSMG30 was created? Can you share the logs, please?
Also, can you please make sure the M4 Cortex is running with the correct binary?

Best Regards,
Hiago.

No `/dev/ttyRPSMG30 is not created after modprobe. Which logs do you need journctrl ? M4 code is definitely running.

dmeg.out (34.0 KB)

Attached full dmesg output

Can you share the m4 binary as well as the image that you used for testing?

Hi @nmohan86,

Sorry for the delay in my answer, I was out of the office last week.

From your dmesg log, I can see the rpmsg seems like it’s correctly configured:

[    0.000000] Reserved memory: created CMA memory pool at 0x00000000e6000000, size 416 MiB
[    0.000000] OF: reserved mem: initialized node linux,cma, compatible id shared-dma-pool
[    0.000000] Reserved memory: created DMA memory pool at 0x0000000090000000, size 0 MiB
[    0.000000] OF: reserved mem: initialized node rpmsg_reserved@90000000, compatible id shared-dma-pool
[    0.000000] Reserved memory: created DMA memory pool at 0x0000000090400000, size 1 MiB
[    0.000000] OF: reserved mem: initialized node vdevbuffer@90400000, compatible id shared-dma-pool
...
[    0.310448] imx mu driver is registered.
[    0.314291] imx rpmsg driver is registered.
...
[    2.095730] virtio_rpmsg_bus virtio0: rpmsg host is online
[    2.105392] virtio_rpmsg_bus virtio1: msg received with no recipient
[    2.105390] virtio_rpmsg_bus virtio1: rpmsg host is online

I’ve used the same binary from the SDK. Can you please show me how you’re compiling your binary? And where did you download it?

Best Regards,
Hiago.

I following the following steps:

  1. Download and Install 6.3.0-devel-20230626+build.320 onto the A35 via Easy Installer

  2. Copy colibri-imx8x_hmp_overlay.dtbo into /boot and update overlays.txt

  3. Download SDK_2.9.0_MIMX8QX5xxxFZ from: * https://mcuxpresso.nxp.com

     tar -xvf ~/Downloads/SDK_2_9_0_MIMX8QX5xxxFZ.tar.gz -C .
     cd boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/armgcc
     export ARMGCC_DIR=/usr
    ./build_debug.sh 
     scp debug/rpmsg_lite_str_echo_rtos.bin root@192.168.76.124:/boot/m4.bin
  1. Reboot Into Bootloader:
    setenv fdt_high 0xffffffffffffffff
    saveenv
    reset
    load mmc 0:1 ${loadaddr} m4.bin
    bootaux ${loadaddr}
    run bootcmd
  1. modprobe imx_rpmsg_tty

  2. image

Hi @nmohan86,

On this step:

the full path should be provided:

load mmc 0:1 ${loadaddr} /boot/m4.bin

Reference: High performance, low power Embedded Computing Systems | Toradex Developer Center

Can you please check the path of the binary and try again?

Best Regards,
Hiago.

I am not able to use the full path:

image

m4.bin is in the uboot partition.

I don’t think loading the m4 is an issue. I ran a m4 program toggling a GPIO pin and that works fine. I believe rpmsg is the issue.

Hi @nmohan86,

Yes I agree, I could reproduce the issue on my side. I also tested some overlays getting information from NXP device-tree files and it still doesn’t work. For example, this is the overlay that I tested:

/dts-v1/;
/plugin/;

#include <dt-bindings/firmware/imx/rsrc.h>

/ {
	compatible = "toradex,colibri-imx8x";
};

&{/} {
	imx8x_cm4: imx8x_cm4@0 {
		compatible = "fsl,imx8qxp-cm4";
		rsc-da = <0x90000000>;
		mbox-names = "tx", "rx", "rxdb";
		mboxes = <&lsio_mu5 0 1
			  &lsio_mu5 1 1
			  &lsio_mu5 3 1>;
		mub-partition = <3>;
		memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
				<&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
		core-index = <0>;
		core-id = <IMX_SC_R_M4_0_PID0>;
		status = "okay";
	};

	reserved-memory {
		#address-cells = <2>;
		#size-cells = <2>;
		ranges;

		vdev0vring0: vdev0vring0@90000000 {
			reg = <0 0x90000000 0 0x8000>;
			no-map;
		};

		vdev0vring1: vdev0vring1@90008000 {
			reg = <0 0x90008000 0 0x8000>;
			no-map;
		};

		vdev1vring0: vdev1vring0@90010000 {
			reg = <0 0x90010000 0 0x8000>;
			no-map;
		};

		vdev1vring1: vdev1vring1@90018000 {
			reg = <0 0x90018000 0 0x8000>;
			no-map;
		};

		rsc_table: rsc_table@900ff000 {
			reg = <0 0x900ff000 0 0x1000>;
			no-map;
		};

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

This one is also enabling remote proc driver, but in general, it shouldn’t be too different from the one that I sent you.

I can see the same behavior, after loading the imx_rpmsg_tty kernel module, nothing happens. I suspect there might be something related to the memory regions that we are trying to allocate, but I couldn’t fully understand it yet.

This code I got from “imx8x-mek.dtsi” device-tree file from NXP.

I will do more tests and will let you know if I find something.

Best Regards,
Hiago.

Looking forward to hearing from you.

The earlier example you sent where everything was working what image were you using ?

Hi @nmohan86,

It was BSP 6, but a version before the ones that we trying right now. I’m still trying to debug the rpmsg and checking the NXP docs, but still facing the same issue.

Best Regards,
Hiago.

Hi @nmohan86,

Sorry for the delay, after debugging the driver, I was able to solve this issue. Turns out there is a property on the device tree that is required and I missed, even though is not well documented as required on the iMX RPMSG documentation from NXP. Here is the new overlay:

/dts-v1/;
/plugin/;

#include <dt-bindings/firmware/imx/rsrc.h>

/ {
	compatible = "toradex,colibri-imx8x";
};

&{/} {
	reserved-memory {
		#address-cells = <2>;
		#size-cells = <2>;
		ranges;

		vdev0vring0: vdev0vring0@90000000 {
			reg = <0 0x90000000 0 0x8000>;
			no-map;
		};

		vdev0vring1: vdev0vring1@90008000 {
			reg = <0 0x90008000 0 0x8000>;
			no-map;
		};

		vdev1vring0: vdev1vring0@90010000 {
			reg = <0 0x90010000 0 0x8000>;
			no-map;
		};

		vdev1vring1: vdev1vring1@90018000 {
			reg = <0 0x90018000 0 0x8000>;
			no-map;
		};

		rsc_table: rsc_table@900ff000 {
			reg = <0 0x900ff000 0 0x1000>;
			no-map;
		};

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

	rpmsg: rpmsg@0 {
		compatible = "fsl,imx8qxp-rpmsg";
		reg = <0 0x90000000 0 0x20000>;
		mbox-names = "tx", "rx", "rxdb";
		mboxes = <&lsio_mu5 0 1
			  &lsio_mu5 1 1
			  &lsio_mu5 3 1>;
		memory-region = <&vdevbuffer>;
		mub-partition = <3>;
		vdev-nums = <2>;
	};
};

Although I separated the vdev buffers, I don’t think that’s really necessary in this case. But anyways, the missing part was:

		memory-region = <&vdevbuffer>;

where we need to tell the driver where is our shared DMA memory.

Now, when I boot the Colibri iMX8X with this overlay enabled, I can see the channel being created:

root@colibri-imx8x-06995602:~# dmesg | grep -i rpmsg
[    0.314140] imx rpmsg driver is registered.
[    2.107181] imx-rpmsg 90000000.rpmsg: assigned reserved memory node vdevbuffer
[    2.120302] virtio_rpmsg_bus virtio0: rpmsg host is online
[    2.122296] virtio_rpmsg_bus virtio0: creating channel rpmsg-i2c-channel addr 0x1
[    2.140946] virtio_rpmsg_bus virtio1: rpmsg host is online
[    2.141067] i2c-rpmsg virtio0.rpmsg-i2c-channel.-1.1: new channel: 0x400 -> 0x1!
[    2.141130] virtio_rpmsg_bus virtio1: creating channel rpmsg-openamp-demo-channel addr 0x1e

Now I can modprobe the driver:

root@colibri-imx8x-06995602:~# modprobe imx_rpmsg_tty
[   27.582079] imx_rpmsg_tty virtio1.rpmsg-openamp-demo-channel.-1.30: new channel: 0x400 -> 0x1e!
[   27.591143] Install rpmsg tty driver!

And it works:

root@colibri-imx8x-06995602:~# echo -n Toradex > /dev/ttyRPMSG30

M4 debug UART:

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 : "Toradex" [len : 7]
Get New Line From Master Side
Get Message From Master Side : "Toradex" [len : 7]

Here are my enabled overlays:

root@colibri-imx8x-06995602:~# cat /boot/overlays.txt 
fdt_overlays=colibri-imx8x_vga-640x480_overlay.dtbo colibri-imx8x_hmp_overlay.dtbo

And I booted the M4 from the boot partition as well, with u-boot:

Colibri iMX8X # load mmc 0:1 ${loadaddr} rpmsg_lite_str_echo_rtos.bin
67720 bytes read in 6 ms (10.8 MiB/s)
Colibri iMX8X # dcache flush
Colibri iMX8X # bootaux ${loadaddr} 
Power on aux core 0
Copy image from 0x95c00000 to 0x34fe0000
Start M4
bootaux complete
Colibri iMX8X # setenv fdt_high 0xffffffffffffffff
Colibri iMX8X # 
Colibri iMX8X # saveenv 
Saving Environment to MMC... Writing to MMC(0)... OK
Colibri iMX8X # boot

I installed the Multimedia image from our feeds, version 6.3.0-build.7:

root@colibri-imx8x-06995602:~# tdx-info 

Software summary
------------------------------------------------------------
Bootloader:               U-Boot
Kernel version:           5.15.77-6.3.0+git.ddc6ca4d76ea #1 SMP PREEMPT Thu Jun 29 10:14:22 UTC 2023
Kernel command line:      root=PARTUUID=3cccb3bf-02 ro rootwait console=tty1 console=ttyLP3,115200 consoleblank=0 earlycon video=imxdpufb5:off video=imxdpufb6:off video=imxdpufb7:off
Distro name:              NAME="TDX Wayland with XWayland"
Distro version:           VERSION_ID=6.3.0-build.7
Hostname:                 colibri-imx8x-06995602
------------------------------------------------------------

Hardware info
------------------------------------------------------------
HW model:                 Toradex Colibri iMX8QXP on Colibri Evaluation Board V3
Toradex version:          0038 V1.0D
Serial number:            06995602
Processor arch:           aarch64
------------------------------------------------------------

Finally, because I’m using the Colibri Development Board, I changed the UART pins in the MCUXpresso M4 code so I could see the debug messages from Cortex-M on pin SODIMM_146:

diff --git a/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.c b/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.c
index 7339c00..391d914 100644
--- a/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.c
+++ b/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.c
@@ -70,12 +70,12 @@ void BOARD_InitPins(sc_ipc_t ipc)                          /*!< Function assigne
   {
       assert(false);
   }
-  err = sc_pad_set_all(ipc, BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID, 1U, SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_ADC_IN2 register modification value */
+  err = sc_pad_set_all(ipc, BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID, 2U, SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_ADC_IN2 register modification value */
   if (SC_ERR_NONE != err)
   {
       assert(false);
   }
-  err = sc_pad_set_all(ipc, BOARD_INITPINS_M40_UART0_TX_PIN_FUNCTION_ID, 1U, SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_ADC_IN3 register modification value */
+  err = sc_pad_set_all(ipc, BOARD_INITPINS_M40_UART0_TX_PIN_FUNCTION_ID, 2U, SC_PAD_CONFIG_NORMAL, SC_PAD_ISO_OFF, 0x0 ,SC_PAD_WAKEUP_OFF);/* IOMUXD_ADC_IN3 register modification value */
   if (SC_ERR_NONE != err)
   {
       assert(false);
diff --git a/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.h b/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.h
index 900d8ef..b76b299 100644
--- a/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.h
+++ b/boards/mekmimx8qx/multicore_examples/rpmsg_lite_str_echo_rtos/pin_mux.h
@@ -14,10 +14,10 @@
  **********************************************************************************************************************/
 
 /* ADC_IN2 (coord V32), M40_UART0_RX */
-#define BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID                 SC_P_ADC_IN2   /*!< Pin function id */
+#define BOARD_INITPINS_M40_UART0_RX_PIN_FUNCTION_ID                 SC_P_SCU_GPIO0_00    /*!< Pin function id */
 
 /* ADC_IN3 (coord V30), M40_UART0_TX */
-#define BOARD_INITPINS_M40_UART0_TX_PIN_FUNCTION_ID                 SC_P_ADC_IN3   /*!< Pin function id */
+#define BOARD_INITPINS_M40_UART0_TX_PIN_FUNCTION_ID                 SC_P_SCU_GPIO0_01   /*!< Pin function id */
 
 /* ADC_IN0 (coord U35), M4_I2C0_1V8_SCL */
 #define BOARD_INITPINS_M4_I2C0_1V8_SCL_PIN_FUNCTION_ID              SC_P_ADC_IN0   /*!< Pin function id */

I did this because we don’t have access to the default pins from MCUXpresso.

if you want to try it yourself, here is the compiled overlay: Download - Toradex File Sharing Platform (it will be available for 3 months).

Let me know if you have any questions!

Best Regards,
Hiago.

Thanks! That solved my issue.

1 Like

Hi @nmohan86,

Thanks for the update, I marked my last reply as “solution”.

Let me know if you have any questions.

Best Regards,
Hiago.