Skip to main content

FreeRTOS Porting Guide for AXON/EDM/PICO-IMX93

Applicable Platforms

This guide applies to the following SOMs.

  • AXON-IMX93
  • EDM-IMX93

Introduction

This article details the process of porting and running FreeRTOS on the Cortex-M33 core of the NXP i.MX93 platform. It covers booting the M33 core via binary loading with U-Boot, synchronizing boot parameters with Linux, and establishing inter-core communication using the remoteproc and RPMsg drivers. The setup is validated through successful execution of example applications: hello_world, rpmsg_lite_str_echo_rtos and rpmsg_lite_pingpong_rtos.

Part1: Set Up the Environment

NOTE

You can use our prebuilt image through the following link for verification. It includes the binary files, allowing directly run M33 core example without rebuilding.

PlatformImage
AXON-IMX93axon-imx93_axon-wb_yocto-5.0-qt6_iw416_lvds-1280x800_20250520.zip
EDM-IMX93edm-imx93_edm-wb_yocto-5.0-qt6_iw416_lvds-1280x800_20250520.zip

1.1 Clone the repository

git clone https://github.com/TechNexion/freertos-tn.git

1.2 Download the GNU Compiler Toolchain

  1. Download the GNU compiler toolchain for your environment from Arm Developer. Here we use the x86_64 Linux version. https://developer.arm.com/downloads/-/gnu-rm image(198).png

  2. Set the environment variables.

export ARMGCC_DIR=/home/platforms/Downloads/gcc-arm-none-eabi-10.3-2021.10
export PATH=$PATH:/home/platforms/Downloads/gcc-arm-none-eabi-10.3-2021.10/bin/

Part2: Build and run hello_world example

2.1 Build hello_world application

  1. Ensure you export the environment variable ARMGCC_DIR which is pointed to directory of tool chain .
cd freertos-tn/boards/${board_name}/demo_apps/hello_world/armgcc/
./build_release.sh
  1. Copy binary file to 1st FAT partition of eMMC :
cp ./release/sdk20-app.bin  /media/username/boot/

2.2 Run hello_world example

  1. Choose to load bin with cortex-m33 support.

In u-boot prompt:

run m33boot

You should see the following output from debug console: image(204).png

Part3: Build and run rpmsg_lite_str_echo_rtos example

3.1 Build rpmsg_lite_str_echo_rtos application:

  1. Ensure you export the environment variable ARMGCC_DIR which is pointed to directory of tool chain.
cd freertos-tn/boards/${board_name}/multicore_examples/rpmsg_lite_str_echo_rtos/linux_remote/armgcc
./build_release.sh
  1. Copy binary file to 1st FAT partition of eMMC :
cp ./release/rpmsg_lite_str_echo_rtos.bin  /media/username/boot/
  1. Copy .elf file to /lib/firmware
cp ./release/rpmsg_lite_str_echo_rtos_imxcm33.elf  /media/username/root/lib/firmware

3.2 Run rpmsg_lite_str_echo_rtos example

  1. Method 1 : Choose to load bin with cortex-m33 support.

In u-boot prompt:

setenv m33image rpmsg_lite_str_echo_rtos.bin
run m33boot

In Yocto prompt:

modprobe imx_rpmsg_tty
echo "this is a test" > /dev/ttyRPMSG30

You should see the following output from debug console:

image(200).png

  1. Method 2 : Choose to load elf with cortex-m33 support (Alternatively).

In Yocto prompt:

echo stop > /sys/class/remoteproc/remoteproc0/state
echo rpmsg_lite_str_echo_rtos_imxcm33.elf > /sys/class/remoteproc/remoteproc0/firmware
echo start > /sys/class/remoteproc/remoteproc0/state
modprobe imx_rpmsg_tty
echo "this is a test" > /dev/ttyRPMSG30

image(201).png

Part4: Build and run rpmsg_lite_pingpong_rtos example

4.1 Build rpmsg_lite_pingpong_rtos application

  1. Ensure you export the environment variable ARMGCC_DIR which is pointed to directory of tool chain.
cd freertos-tn/boards/${board_name}/multicore_examples/rpmsg_lite_pingpong_rtos/linux_remote/armgcc
./build_release.sh

2.Copy binary file to 1st FAT partition of eMMC :

cp ./release/rpmsg_lite_pingpong_rtos_linux_remote.bin  /media/username/boot/
  1. Copy .elf file to /lib/firmware
cp ./release/rpmsg_lite_pingpong_rtos_linux_remote.elf  /media/username/root/lib/firmware

4.2 Run rpmsg_lite_pingpong_rtos example

  1. Method 1 : Choose to load bin with cortex-m33 support.

In u-boot prompt:

setenv m33image rpmsg_lite_pingpong_rtos_linux_remote.bin
run m33boot

In Yocto prompt:

modprobe imx_rpmsg_pingpong

image(202).png

  1. Method 2 : Choose to load elf with cortex-m33 support (Alternatively).

In Yocto prompt:

echo stop > /sys/class/remoteproc/remoteproc0/state
echo rpmsg_lite_pingpong_rtos_linux_remote.elf > /sys/class/remoteproc/remoteproc0/firmware
echo start > /sys/class/remoteproc/remoteproc0/state
modprobe imx_rpmsg_pingpong

image(203).png

Troubleshooting

common problems and corresponding solutions:

  1. RPMsg Messages Cannot Be Sent or Received
  • Make sure clk-imx93.mcore_booted=1 is included in the bootargs to prevent Linux from restarting the M33 core.
  • Ensure the firmware loaded is the *_linux_remote version.
  • Load the imx_rpmsg_tty module using modprobe.
  • Check dmesg | grep rpmsg to verify if the RPMsg channel was successfully created.
  1. M33 Core Fails to Boot
  • Verify the fatload and cp.b memory addresses match the expected start address for M33.
  • Ensure the binary image is correctly built and linked for the M33 target.
  • Confirm the binary is loaded into the correct memory region (e.g., TCM or OCRAM).
  1. Failed to Load Firmware via Remoteproc
  • Ensure the firmware file is placed in /lib/firmware/ and matches the name specified.
  • If the error says Device or resource busy, it indicates M33 was already started by U-Boot, so remoteproc should not try to restart it.
  1. /dev/ttyRPMSG* Device Not Found
  • Ensure the Linux kernel is compiled with CONFIG_IMX_RPMSG_TTY.
  • Use dmesg | grep rpmsg to verify that rpmsg-virtual-tty-channel was successfully created.

Reference