Skip to main content

HMP RPMsg Guide

Introduction

This article describes how to use the Remote Processor Messaging (RPMsg) protocol for alternative cores using the MCUXpresso SDK.

This article complies with the Typographic Conventions for Toradex Documentation.

RPMsg

The RPMsg framework provides a virtio-based messaging bus that enables communication between Linux and remote processors. Each RPMsg device represents a communication channel identified by a name and source/destination addresses.

In the context of HMP, RPMsg is used to exchange messages between Linux and firmware running on the main and an alternative core, respectively.

For more information, refer to the Kernel documentation or the OpenAMP documentation.

Prerequisites

The MCUXpresso SDK and all required tools must be configured before proceeding. Refer to the Setting Up the MCUXpresso SDK and Toolchain for HMP Development article for more information about the installation process.

Device Tree Modifications

For RPMsg to work properly, the device tree must reserve the memory regions used for communication between Linux and the remote processor. These regions include the shared memory buffers used by the RPMsg framework and the resources required by the remote processor firmware.

Toradex provides device tree overlays that configure the required memory regions for HMP. These overlays are available for supported downstream and upstream-based modules starting from BSP and Torizon OS 6. For instructions on adding and enabling device tree overlays, refer to First Steps with Device Tree Overlays.

The following table lists the HMP-related device tree overlays available for supported Toradex modules:

OverlayStatusDevice Tree Overlays Repository Branch
verdin-imx8mp_hmp_overlay.dtsAvailabletoradex_6.6-2.2.x-imx
verdin-imx8mp_hmp_overlay.dtsComing soonmaster
verdin-imx8mm_hmp_overlay.dtsAvailabletoradex_6.6-2.2.x-imx
verdin-imx8mm_hmp_overlay.dtsAvailablemaster
verdin-am62_uart4-mcu_overlay.dts¹Availabletoradex_ti-linux-6.6.y
verdin-am62p_uart4-mcu_overlay.dts¹Availabletoradex_ti-linux-6.6.y
apalis-imx8_hmp_overlay.dtsNot AvailableN/A
colibri-imx8x_hmp_overlay.dtsAvailabletoradex_6.6-2.2.x-imx
colibri-imx7_hmp_overlay.dtsNot AvailableN/A

¹ In the latest Kernel, the remoteproc and memory nodes are defined directly in the base device tree. The overlay only reserves the Cortex-M UART, which remains available for debugging.

Available overlays are precompiled as *.dtbo files in Torizon OS and Toradex BSP reference images for the corresponding branch. The overlay source files are available in the Toradex device-tree-overlays.git repository.

info

For overlays marked as Coming soon, contact Toradex through the Support channels.

RemoteProc Framework Usage with i.MX 95 Modules

The RemoteProc framework is enabled by default on i.MX 95 modules, so no additional configuration is required to use the remoteproc with these modules.

RemoteProc Framework Usage with i.MX 8M Plus and i.MX 8M Mini Modules

To be able to use the RemoteProc framework with i.MX 8M Plus and i.MX 8M Mini modules, a Kernel command line argument is required. It is possible to update the Kernel environment variables from the Linux user space using the fw_setenv command.

# fw_setenv tdxargs "clk-imx8mp.mcore_booted=1"

After running the command, reboot the module for the changes to take effect.

How the Buffer Reservation Works

After the MCUXpresso SDK workspace is installed, it is possible to check the memory addresses used for RPMsg communication with the rpmsg_lite_str_echo_rtos example, located under the examples/multicore_examples/ directory.

The app.h file, located under examples/_boards/imx95lp4xevk15/multicore_examples/rpmsg_lite_str_echo_rtos/remote/cm7/, contains the following definitions:

app.h
...
#define RPMSG_LITE_LINK_ID (RL_PLATFORM_IMX95_M7_A55_USER_LINK_ID)
#define RPMSG_LITE_SHMEM_BASE (VDEV1_VRING_BASE)
#define RPMSG_LITE_NS_ANNOUNCE_STRING "rpmsg-virtual-tty-channel"
...

And the board.h file, located under examples/_boards/imx95lp4xevk15/, contains the following definitions:

board.h
...
#define VDEV0_VRING_BASE (0x88000000U)
#define VDEV1_VRING_BASE (0x88010000U)
...

These definitions indicate that the shared memory base address for RPMsg communication is 0x88010000U and the link ID used for communication is RL_PLATFORM_IMX95_M7_A55_USER_LINK_ID. The nameservice announcement string is rpmsg-virtual-tty-channel.

Using the information obtained from the SDK, it is possible to modify the device tree file to reserve the memory regions used for RPMsg communication, if needed. The reserved memory regions should match the shared memory base address defined in the SDK.

Load the RPMsg Linux Driver

After the device tree has been modified and the module has been rebooted, the driver should appear as "registered" in the dmesg log:

# dmesg | grep -i rpmsg
[ 0.045742] imx rpmsg driver is registered.

Once the driver is registered, the remote core firmware built with the MCUXpresso SDK can then use RPMsg to communicate with Linux.

Follow the instructions of the How To Compile Firmware for Alternative Cores (NXP) article and compile a demo that uses RPMsg for communication, then follow the instructions of the How To Load and Run Firmwares Into Alternative Cores (NXP) article to load the firmware to the target module.

RPMsg-Lite Echo Example

Compile and load the rpmsg_lite_str_echo_rtos example from the SDK.

After loading the firmware, it should print the following message in the debug UART:

RPMSG String Echo FreeRTOS RTOS API Demo...

After booting Linux, if the RPMsg is correctly configured, the following message should appear on the Cortex-M side:

RPMSG String Echo FreeRTOS RTOS API Demo...

Nameservice sent, ready for incoming messages...

The dmesg log also shows if RPMsg has been correctly configured:

# dmesg | grep -i rpmsg
[ 0.045793] imx rpmsg driver is registered.
[ 1.329068] virtio_rpmsg_bus virtio0: rpmsg host is online
[ 1.329111] virtio_rpmsg_bus virtio0: creating channel rpmsg-virtual-tty-channel-1 addr 0x1e

Load the imx_rpmsg_tty Kernel module using modprobe:

# sudo modprobe imx_rpmsg_tty

After the Kernel module has been loaded, the Cortex-M should print a "Hello World" on the screen, showing that the RPMsg channel has been created successfully:

RPMSG String Echo FreeRTOS RTOS API Demo...

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

A new tty device is also created:

# ls /dev/ | grep -i rpmsg
rpmsg_ctrl0
ttyRPMSG30

Finally, it is possible to exchange data by writing to the tty device:

# echo Toradex! > /dev/ttyRPMSG30

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 : 8]
Get New Line From Master Side

RPMsg-Lite Ping-Pong Example

Compile and load the rpmsg_lite_pingpong_rtos_linux example from the SDK.

After loading the firmware, it should print the following message in the debug UART:

RPMSG Ping-Pong FreeRTOS RTOS API Demo...
RPMSG Share Base Addr is 0xb8000000

After loading the firmware, it should print the following message in the debug UART:

RPMSG Ping-Pong FreeRTOS RTOS API Demo...
RPMSG Share Base Addr is 0xb8000000
Link is up!
Nameservice announce sent.

Load the imx_rpmsg_pingpong Kernel module using modprobe:

# sudo modprobe imx_rpmsg_pingpong

After the Kernel module has been loaded, the Cortex-M should print the ping-pong messages on the screen, showing that the RPMSg channel has been created successfully:

Sending pong...
Waiting for ping...
Sending pong...
Waiting for ping...
Sending pong...
Waiting for ping...
Sending pong...
Waiting for ping...
Sending pong...
Waiting for ping...
Sending pong...
Waiting for ping...
Sending pong...
Waiting for ping...
Sending pong...
Ping pong done, deinitializing...
Looping forever...

The dmesg log also shows that the ping-pong demo ran successfully:

# dmesg | grep ping
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 516096
[ 0.920924] SMCCC: SOC_ID: ARCH_SOC_ID not implemented, skipping ....
[ 122.533450] imx_rpmsg_pingpong virtio0.rpmsg-openamp-demo-channel.-1.30: new channel: 0x400 -> 0x1e!
[ 122.704607] imx_rpmsg_pingpong virtio0.rpmsg-openamp-demo-channel.-1.30: goodbye!

Next Steps

Follow the How To Use RemoteProc article to learn how to use the RemoteProc framework to manage the firmware running on the alternative cores.

Send Feedback!