Skip to main content

Running FreeRTOS on the Cortex-M4 of a Colibri iMX8X

Introduction

The objective of this article is to guide you through case-oriented examples on the implementation of FreeRTOS on the Cortex-M of a Colibri iMX8X System on Module, focusing on the execution of a sample application firmwares leveraging the Heterogeneous Multicore Processing architecture.

The use cases described in this article were tested and validated with FreeRTOS on the Cortex-M running alongside an embedded Linux image (Linux BSP) on the A-cores.

Prerequisites

Preparing the Environment

  1. Download the MCUXpresso SDK as described at Setting Up MCUXpresso SDK and Toolchain for Cortex-M development. For Colibri iMX8X, you should download:

    • Colibri iMX8DX: MIMX8UX5xxxFZ
    • Colibri iMX8QXP: MIMX8QX5xxxFZ
  2. Verify the source code structure from the boards/mekmimx8qx folder

    $ cd <colibri-imx8x-sdk>/boards/
    $ tree -L 2
    .
    └── mekmimx8qx
    ├── cmsis_driver_examples
    ├── demo_apps
    ├── driver_examples
    ├── lwip_examples
    ├── mekmimx8qx.png
    ├── mmcau_examples
    ├── multicore_examples
    ├── project_template
    └── rtos_examples
  3. Download and setup the GCC toolchain as explained at Setting Up MCUXpresso SDK and Toolchain for Cortex-M development. We recommend the Arm GNU Toolchain AArch32 bare-metal target (arm-none-eabi) for your host OS.

Case-oriented Examples

To understand and execute the examples below, make sure that you are in the root folder <colibri-imx8x-sdk>, unless specified.

Hello World Example

  1. Go to the demo directory on the SDK folder.

    $ cd ./boards/mekmimx8qx/demo_apps/hello_world
    $ tree -L 1
    .
    ├── armgcc
    ├── board.c
    ├── board.h
    ├── clock_config.c
    ├── clock_config.h
    ├── empty_rsc_table.c
    ├── hello_world.bin
    ├── hello_world.c
    ├── hello_world.mex
    ├── hello_world_TCM.bin
    ├── hello_world_v3_8.xml
    ├── pin_mux.c
    ├── pin_mux.h
    └── readme.txt
  2. Change the pin_mux.c and pin_mux.h accordingly as explained at Run the Firmware.

  3. Run the script to build the demo

    $ export ARMGCC_DIR=<PATH_TO_GCC_TOOLCHAIN>/<GCC_TOOLCHAIN_FOLDER>
    $ cd armgcc/
    $ ./build_debug.sh
  4. Copy the generated binary to your device

    $ scp debug/hello_world.bin root@<board-ip>:/home/root
  5. Load the firmware on Flash. On U-boot terminal, run the following commands

    > setenv load_cmd "ext4load mmc 0:2"
    > setenv m4_0_image "/home/root/hello_world.bin"
    > saveenv
  6. Start the firmware at boot level

    > run m4boot_0

Multicore Examples

Before diving into the examples:

  1. Apply the related devicetree overlay: colibri-imx8x_hmp_overlay.dtbo. Refer to Cortex-M RPMsg Guide.

  2. Make sure that the rpmsg driver is loaded.

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

RPMsg TTY Example

  1. Go to the demo directory on the SDK folder.

    $ cd ./boards/evkmimx8mm/multicore_examples/rpmsg_lite_str_echo_rtos
    $ tree -L 2
    .
    ├── app_srtm.c
    ├── app_srtm.h
    ├── armgcc
    ├── board.c
    ├── board.h
    ├── clock_config.c
    ├── clock_config.h
    ├── FreeRTOSConfig.h
    ├── main_remote.c
    ├── pin_mux.c
    ├── pin_mux.h
    ├── readme.txt
    ├── remoteproc.h
    ├── rpmsg_config.h
    ├── rpmsg_lite_str_echo_rtos_imxcm4_v3_8.xml
    ├── rsc_table.c
    ├── rsc_table.h
    └── srtm
  2. Run the script to build the demo

    $ export ARMGCC_DIR=<PATH_TO_GCC_TOOLCHAIN>/<GCC_TOOLCHAIN_FOLDER>
    $ cd armgcc/
    $ ./build_debug.sh
  3. Copy the generated binary to your device

    $ scp debug/rpmsg_lite_str_echo_rtos_imxcm4.elf root@<board-ip>:/home/root
  4. Reset the module and load the firmware on U-boot:

    > setenv load_cmd "ext4load mmc 0:2"
    > setenv m4_0_image "/home/root/rpmsg_lite_str_echo_rtos_imxcm4.elf"
    > saveenv
    > run m4boot
  5. Boot and then load the imx_rpmsg_tty kernel module.

    # sudo modprobe imx_rpmsg_tty

    After the kernel module has been loaded, the Cortex-M should print a "Hello World" in the screen, showing that the channel has been created correctly.

    RPMSG String Echo FreeRTOS RTOS API Demo...

    Nameservice sent, ready for incoming messages...
    Get Message From Master Side : "hello world!" [len : 12]
  6. Check if ttyRPMSG device was created:

    # ls /dev/ | grep -i rpmsg
    rpmsg_ctrl0
    ttyRPMSG30
  7. Write through this device and check on the serial port connected to Cortex-M4

    # echo Toradex! > /dev/ttyRPMSG30

    Which results in

    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 Ping Pong Example

  1. Go to the demo directory on the SDK folder.

    $ cd ./boards/mekmimx8qx/multicore_examples/rpmsg_lite_pingpong_rtos
    $ tree -L 2
    .
    └── linux_remote
    ├── app_srtm.c
    ├── app_srtm.h
    ├── armgcc
    ├── board.c
    ├── board.h
    ├── clock_config.c
    ├── clock_config.h
    ├── FreeRTOSConfig.h
    ├── main_remote.c
    ├── pin_mux.c
    ├── pin_mux.h
    ├── readme.txt
    ├── remoteproc.h
    ├── rpmsg_config.h
    ├── rpmsg_lite_pingpong_rtos_linux_remote_v3_8.xml
    ├── rsc_table.c
    ├── rsc_table.h
    └── srtm
  2. Run the script to build the demo

    $ export ARMGCC_DIR=<PATH_TO_GCC_TOOLCHAIN>/<GCC_TOOLCHAIN_FOLDER>
    $ cd linux_remote/armgcc/
    $ ./build_debug.sh
  3. Copy the generated binary to your device

    $ scp debug/rpmsg_lite_pingpong_rtos_linux_remote.elf root@<board-ip>:/home/root
  4. Reset the module and load the firmware on U-boot:

    > setenv load_cmd "ext4load mmc 0:2"
    > setenv m4_0_image "/home/root/rpmsg_lite_pingpong_rtos_linux_remote.elf"
    > saveenv
    > run m4boot
  5. Boot the module and then you will be able to see the following message on the Cortex-M4

    RPMSG Ping-Pong FreeRTOS RTOS API Demo...
    RPMSG Share Base Addr is 0xb8000000
    Link is up!
    Nameservice announce sent.
  6. Load the kernel module:

    # sudo modprobe imx_rpmsg_pingpong

    And on the Cortex-M4 side you can see

    Sending pong...
    Waiting for ping...
    Sending pong...
    Waiting for ping...
    Sending pong...
    Waiting for ping...


Send Feedback!