Personal tools

Running a Cortex-M4 application on visionsom-8mm

From SomLabs Wiki

Jump to: navigation, search

Running a Cortex-M4 application on VisionSOM-8MM

This article explains how to configure the iMX Yocto system for running a Cortex-M4 application. In this tutorial an example code as well as the required kernel modules from NXP will be used. This tutorial was prepared for the iMX Yocto 5.4.3-2.0.0 with the SoMLabs zeus meta-layer available on github:

Modifying the device tree

To configure the Cortex-M4 access from Linux some changes in the SoMlabs meta-layer device tree are required. The modifications listed below add the memory regions reserved for the Cortem-M4 and the communication with application cores, the Cortex-M4 configuration with the mailboxes and the RPMSG channel setup. The proposed changes are added to the arch/arm64/boot/dts/freescale/visionsom-8mm.dtsi file in the kernel sources. They may be applied directly to the kernel sources or added to the kernel recipe in Yocto.

From c674b540f92a0c73e169223b2b15a9388b3826c7 Mon Sep 17 00:00:00 2001
From: Your Name <>
Date: Thu, 1 Oct 2020 14:49:17 +0200
Subject: [PATCH] Added support for Cortex-M4 rpmsg

 .../boot/dts/freescale/visionsom-8mm.dtsi     | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/visionsom-8mm.dtsi b/arch/arm64/boot/dts/freescale/visionsom-8mm.dtsi
index 7250e0778c6a..76b71285a672 100644
--- a/arch/arm64/boot/dts/freescale/visionsom-8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/visionsom-8mm.dtsi
@@ -21,6 +21,42 @@
             reg = <0 0xb8000000 0 0x400000>;
+        m4_reserved: m4@0x80000000 {
+            no-map;
+            reg = <0 0x80000000 0 0x1000000>;
+        };
+        vdev0vring0: vdev0vring0@b8000000 {
+            compatible = "shared-dma-pool";
+            reg = <0 0xb8000000 0 0x8000>;
+            no-map;
+        };
+        vdev0vring1: vdev0vring1@b8008000 {
+            compatible = "shared-dma-pool";
+            reg = <0 0xb8008000 0 0x8000>;
+            no-map;
+        };
+        vdevbuffer: vdevbuffer@b8400000 {
+            compatible = "shared-dma-pool";
+            reg = <0 0xb8400000 0 0x100000>;
+            no-map;
+        };
+    };
+    imx8mm-cm4 {
+        compatible = "fsl,imx8mm-cm4";
+        rsc-da = <0xb8000000>;
+        clocks = <&clk IMX8MM_CLK_M4_DIV>;
+        mbox-names = "tx", "rx", "rxdb";
+        mboxes = <&mu 0 1
+                  &mu 1 1
+                  &mu 3 1>;
+        memory-region = <&vdev0vring0>, <&vdev0vring1>, <&vdevbuffer>;
+        syscon = <&src>;

     chosen {
@@ -359,6 +395,13 @@
     status = "okay";

+    vdev-nums = <1>;
+    reg = <0x0 0xb8000000 0x0 0x10000>;
+    memory-region = <&vdevbuffer>;
+    status = "okay";
 &uart1 { /* BT */
     pinctrl-names = "default";
     pinctrl-0 = <&pinctrl_uart1_bt>;

Modifying the iMX ATF (ARM Trusted Firmware)

If the processor peripherals need to be assigned to the real-time or application cores, the imx-atf module code has to be modified. In the following patch the Cortex-M4 core is assigned do the domain 1 in RDC (Resource Domain Controller) and the UART3 access from domain 0 (application core) is disabled. The details about the RDC and its registers may be found in the iMX8MM Reference Manual. The patch may be added to the imx-atf recipe in the somlabs meta-layer.

From 8e6622f05abebf1c08d26892ee0760d9b50accf7 Mon Sep 17 00:00:00 2001
From: Your Name <>
Date: Thu, 1 Oct 2020 15:54:29 +0200
Subject: [PATCH] Assign M4 and Uart3 to domain 1

 plat/imx/imx8mm/imx8mm_bl31_setup.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/plat/imx/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8mm/imx8mm_bl31_setup.c
index 8ad918aba..05ed8538d 100644
--- a/plat/imx/imx8mm/imx8mm_bl31_setup.c
+++ b/plat/imx/imx8mm/imx8mm_bl31_setup.c
@@ -315,9 +315,9 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,

        /* Assign M4 to domain 1 */
-       //mmio_write_32(IMX_RDC_BASE + 0x204, 0x1);
-       //mmio_write_32(IMX_RDC_BASE + 0x518, 0xfc);
-       //mmio_write_32(IMX_RDC_BASE + 0x5A4, 0xf3);
+       mmio_write_32(IMX_RDC_BASE + 0x204, 0x1);
+       /* Assign UART3 to domain 1 (M4) */
+       mmio_write_32(IMX_RDC_BASE + 0x5A0, 0xfc);

 #if defined (CSU_RDC_TEST)

Running the Cortex-M4 example

The ready to use binary file for Cortex-M4 may be downloaded from here: It has to be extracted to the boot partition of the target system (mounted as /run/media/mmcblk2p1/ in the running system). When it is available on the boot partition, the u-boot need to be stopped before automatic system boot to enter the u-boot console available on serial port. The following commands will load the binary and start the real-time core, as well as continue the Linux boot process:

fatload mmc 2:1 0x48000000 m4.bin
cp.b 0x48000000 0x7e0000 35000
bootaux 0x7e0000

In the example binary, the Cortex-M4 debug output is visible on UART3 port (Raspberry Pi Connector 8 (TXD), 10 (RXD) on VisionCB-8M-STD). After logging in to Linux console the imx_rpmsg_tty module needs to be loaded:

modprobe imx_rpmsg_tty

As a result a new serial port will be initialized - /dev/ttyRPMSG30. The example program reads the port on the Cortex-M4 side ad waits for two commands - on and off that enable and disable the LED IO05 on VisionCB-8M-STD.

echo "on" > /dev/ttyRPMSG30
echo "off" > /dev/ttyRPMSG30

Building new Cortex-M4 example

In order to build own Cortex-M4 binary the iMX SDK package is required. It may be downloaded from the website for the proper processor model. The required SDK version is given in the meta-imx/meta-sdk/recipes-fsl/m4-demos/README file of used NXP Yocto sources. The version 2.6.1 of the SDK is available here: This SDK contains the source of the example binary used in previous chapter. The SDK needs also a GCC cross compiler for Cortex-M4 that may be obtained for example from website. To use the SDK the following environmental variables need to be set:

export ARMGCC_DIR=<PATH_TO_THE_GCC_COMPILER>/gcc-arm-none-eabi-9-2020-q2-update
export PATH=$PATH:<PATH_TO_THE_GCC_COMPILER>/gcc-arm-none-eabi-9-2020-q2-update/bin

After that the example binary may be built by calling one of the building scripts, for example:

cd SDK_2.6.1_MIMX8MM6xxxKZ/boards/visionsom-8mm/multicore_examples/rpmsg_lite_str_echo_rtos/armgcc

The SDK details are explained in the documentation available to download from the website.

NXP Partner ST Partner