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
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.
| Platform | Image |
|---|---|
| AXON-IMX93 | axon-imx93_axon-wb_yocto-5.0-qt6_iw416_lvds-1280x800_20250520.zip |
| EDM-IMX93 | edm-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
-
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
-f7a83578174fd0a0d640eb25b344c90e.png)
-
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
- 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
- Copy binary file to 1st FAT partition of eMMC :
cp ./release/sdk20-app.bin /media/username/boot/
2.2 Run hello_world example
- Choose to load bin with cortex-m33 support.
In u-boot prompt:
run m33boot
You should see the following output from debug console:
-6820750bdce7a58f52f81b70799fc6bb.png)
Part3: Build and run rpmsg_lite_str_echo_rtos example
3.1 Build rpmsg_lite_str_echo_rtos application:
- 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
- Copy binary file to 1st FAT partition of eMMC :
cp ./release/rpmsg_lite_str_echo_rtos.bin /media/username/boot/
- 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
- 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:
-9d3e35fbca9161da8d87491ce46c1f06.png)
- 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
-949a8a04e9548c28a4619305817923a2.png)
Part4: Build and run rpmsg_lite_pingpong_rtos example
4.1 Build rpmsg_lite_pingpong_rtos application
- 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/
- 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
- 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
-27938b3f885598a038fd8bbb9b614859.png)
- 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
-1672d3bd023f81c1a60d7ea0ca4ee112.png)
Troubleshooting
common problems and corresponding solutions:
- RPMsg Messages Cannot Be Sent or Received
- Make sure
clk-imx93.mcore_booted=1is included in the bootargs to prevent Linux from restarting the M33 core. - Ensure the firmware loaded is the
*_linux_remoteversion. - Load the
imx_rpmsg_ttymodule usingmodprobe. - Check
dmesg | grep rpmsgto verify if the RPMsg channel was successfully created.
- M33 Core Fails to Boot
- Verify the
fatloadandcp.bmemory 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).
- 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.
/dev/ttyRPMSG*Device Not Found
- Ensure the Linux kernel is compiled with
CONFIG_IMX_RPMSG_TTY. - Use
dmesg | grep rpmsgto verify thatrpmsg-virtual-tty-channelwas successfully created.