QS93/TX93: Build and run of Multicore RPMsg-Lite demo for CM33

The Multicore RPMsg-Lite string echo project is a simple demonstration program that uses the MCUXpresso SDK software and the RPMsg-Lite library and shows how to implement the inter-core communicaton between cores of the multicore system.

It works with Linux RPMsg master peer to transfer string content back and forth. The name service handshake is performed first to create the communication channels. Next, Linux OS waits for user input to the RPMsg virtual tty. Anything which is received is sent to the CM33 core. The CM33 core sends a confirmation message via its local debug UART and echoes back the same message as an acknowledgement. The tty reader on the Linux side can get the message, and start another transaction. The demo demonstrates RPMsg’s ability to send arbitrary content back and forth.

precautions for the Linux build

The following precautions must be met to run the Multicore RPMsg-Lite demo:

  • the U-Boot must support the bootaux command

  • the Linux must provide imx_rpmsg_tty kernel module

  • the Linux device tree must support the Cortex®-M33 and reserved memory areas for communication of the two cores.

To support customers, Ka-Ro provides the distro feature copro. To add the distro feature to your build, go to your yocto build folder and open the file conf/bblayers.conf

then add these lines:

DISTRO_FEATURES:append = " copro"
KARO_BASEBOARD = "qsbase93"

please note

The baseboard definition in the example above is for the QS93-module, mounted on a QSBASE93 eval kit. For a TX93, a suitable baseboard would be the mainboard7. The KARO_BASEBOARD variable must be set to “mb7” in this case.

Furthermore, some special entries into the device tree are necessary. These are provided by the devicetree overlay karo-copro

To add the karo-copro overlay, the name of the copro-overlay should be added to the appropriate overlays_* variable:

setenv overlays_<baseboard> ${overlays_<baseboard>} karo-copro
saveenv
reset

Add clk_ignore_unused to the Linux boot arguments:

setenv append_bootargs debug clk_ignore_unused
saveenv

If you would like to suppress debug output replace debug by quiet in the Linux boot argument.

precautions for the CM33 firmware build

The multicore sample firmware uses a local UART to send out debug messages. The firmware definitions from the MCUXpresso SDK, does only work on NXP hardware, as the used IO-pins may not be available on Ka-Ro devkits. The following modifications use the LPUART3 mapped to the processor pads GPIO_IO14 and GPIO_IO15. Both pins are available on the exoansion headers of both the QSBASE93 and the MB7.

in board.h define lpUART3 as debugport:

/* The UART to use for debug messages. */
#define BOARD_DEBUG_UART_INSTANCE   3U
#define BOARD_DEBUG_UART_BAUDRATE   115200U
#define BOARD_DEBUG_UART_TYPE       kSerialPort_Uart
#define BOARD_DEBUG_UART_CLOCK_ROOT kCLOCK_Root_Lpuart3
#define BOARD_DEBUG_UART_CLOCK_GATE kCLOCK_Lpuart3
#define BOARD_DEBUG_UART_CLK_FREQ   CLOCK_GetIpFreq(BOARD_DEBUG_UART_CLOCK_ROOT)

in pin_mux.c do the appropriate pin muxing:

void BOARD_InitPins(void) {
   IOMUXC_SetPinMux(IOMUXC_PAD_GPIO_IO15__LPUART3_RX, 0U);
   IOMUXC_SetPinMux(IOMUXC_PAD_GPIO_IO14__LPUART3_TX, 0U);

   IOMUXC_SetPinConfig(IOMUXC_PAD_GPIO_IO15__LPUART3_RX,
                     IOMUXC_PAD_PD_MASK);
   IOMUXC_SetPinConfig(IOMUXC_PAD_GPIO_IO14__LPUART3_TX,
                     IOMUXC_PAD_DSE(15U));
}

boot CM33 coprocessor from Tightly-Coupled Memory (TCM)

Assuming the coprocessor firmware is stored in the bootfs partition, the coprocessor is booted with the following commands:

load mmc ${mmcdev}:1 ${loadaddr} rpmsg_lite_str_echo_rtos.bin
cp.b ${fileaddr} 0x201e0000 0x20000
bootaux 0x1ffe0000 0

When the CM33-core is started, it will output the message:

RPMSG String Echo FreeRTOS RTOS API Demo...

on the debug UART lpUART3.

Boot the Linux with the boot command from U-Boot. When Linux boots, and a rpmsg link will be established, the CM33-core will output:

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

After Linux has booted to the end, be sure that the imx_rpmsg_tty kernel module is loaded:

modprobe imx_rpmsg_tty

you should now find a virtual device /dev/ttyRPMSG30.

You may now send strings to it, with the command:

echo <test string> > /dev/ttyRPMSG30

Starting firmware using SYSFS interface

Linux uses a set of default search paths to load the firmware image. Please see here for detailed information.

You may also specify a custom path. There are two ways to do this. Either you pass the path in the kernel command line, or you use the SYSFS interface to specifiy the path.

Imagine the image is stored in the /mnt folder, then you can specify the path with the help of the kernel command line as follows:

     setenv append_bootargs debug clk_ignore_unused firmware_class.path=/mnt
     saveenv

Inside Linux, you can specify the same path with:

echo -n /mnt > /sys/module/firmware_class/parameters/path

Do not forget to load the imx_rpmsg_tty kernel module:

modprobe imx_rpmsg_tty

Specify the firmware filename:

echo -n rpmsg_lite_str_echo_rtos_imxcm33.elf > /sys/devices/platform/imx93-cm33/remoteproc/remoteproc0/firmware

Start the firmware image with:

echo start > /sys/devices/platform/imx93-cm33/remoteproc/remoteproc0/state

Stop it with:

echo stop > /sys/devices/platform/imx93-cm33/remoteproc/remoteproc0/state

Check the state of the remote processor before starting it with a new firmware. If it is online, it should be stopped.

cat /sys/class/remoteproc/remoteproc0/state