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​