Zephyr openamp_rsc_table example making cortex a7 crash in colibri imx7d

Hey,

I am using a colibri IMX7D 1GB and I am trying to make rpmsg work to trade data between a7 and m4. I do not have much knowledge yet, so I decided to follow this zephyr tutorial.

I did exactly what the tutorial said (I only adjusted some phandle from .dts because my biggest phandle value was different), but when I try to start the m4 firmware, even my linux crashes.

here is an example:

root@colibri-imx7-emmc-03112256:~# modprobe imx_rproc root@colibri-imx7-emmc-03112256:~# modprobe virtio_rpmsg_bus root@colibri-imx7-emmc-03112256:~# modprobe rpmsg_tty root@colibri-imx7-emmc-03112256:~# echo stop > /sys/class/remoteproc/remoteproc0/state sh: write error: Invalid argument root@colibri-imx7-emmc-03112256:~# echo zephyr_openamp_rsc_table.elf > /sys/class/remoteproc/r emoteproc0/firmware root@colibri-imx7-emmc-03112256:~# echo start > /sys/class/remoteproc/remoteproc0/state [ 94.864336] remoteproc remoteproc0: powering up imx-rproc [ 94.872800] remoteproc remoteproc0: Booting fw image zephyr_openamp_rsc_table.elf, size 1225820 [ 94.882736] rproc-virtio rproc-virtio.1.auto: assigned reserved memory node vdev0buffer@90002000 [ 94.893128] virtio_rpmsg_bus virtio0: rpmsg host is online [ 94.898817] virtio_rpmsg_bus virtio0: creating channel rpmsg-tty addr 0x400 [ 94.908789] rproc-virtio rproc-virtio.1.auto: registered virtio0 (type 7) [ 94.909938] virtio_rpmsg_bus virtio0: creating channel rpmsg-client-sample addr 0x401 [ 94.915679] remoteproc remoteproc0: remote processor imx-rproc is now up [ 94.923716] virtio_rpmsg_bus virtio0: creating channel rpmsg-tty addr 0x402 root@colibri-imx7-emmc-03112256:~# prefetch abort pc : [<00c831da>] lr : [] reloc pc : [] lr : [<88137848>] sp : c206ff80 ip : c206ff90 fp : 00000016 r10: c0f65000 r9 : c219b0b0 r8 : 0000000f r7 : 00000000 r6 : 00000000 r5 : 00000000 r4 : 00000000 r3 : 00000000 r2 : 8010d4b8 r1 : 00010000 r0 : 84000001 Flags: nZCv IRQs off FIQs off Mode UK6_32 (T) Code: data abort pc : [] lr : [] reloc pc : [<87801bfa>] lr : [<87801c2d>] sp : c206fe88 ip : 00000020 fp : 00000016 r10: bffd50e8 r9 : bdf78ea0 r8 : bffd50e0 r7 : 00000020 r6 : 00000004 r5 : 00c831da r4 : fffffffc r3 : bff94311 r2 : c0000000 r1 : 00000000 r0 : 00000006 Flags: NzCv IRQs on FIQs on Mode SVC_32 (T) Code: 2608 f025 0503 e015 (f835) 2014 Resetting CPU … resetting …

my os info:

ID=tdx-xwayland-upstream
NAME=“TDX Wayland with XWayland Upstream”
VERSION=“6.8.3+build.17 (kirkstone)”
VERSION_ID=6.8.3-build.17
PRETTY_NAME=“TDX Wayland with XWayland Upstream 6.8.3+build.17 (kirkstone)”
DISTRO_CODENAME=“kirkstone”

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


The crash you’re experiencing when starting the Cortex-M4 firmware indicates a memory configuration conflict between the Zephyr firmware and the Linux system. This is a common issue when the Resource Domain Controller (RDC) and device tree configurations don’t properly isolate resources between the A7 and M4 cores (1).

Root Cause Analysis

The prefetch abort and data abort errors suggest that the M4 firmware is trying to access memory regions or peripherals that are still being used by the Linux kernel (1). This happens because:

  1. Device Tree Conflicts: Linux device tree hasn’t properly disabled peripherals used by M4
  2. Memory Region Overlap: Shared memory regions aren’t correctly configured
  3. RDC Configuration Issues: Resource Domain Controller isn’t properly separating A7 and M4 resources

Recommended Solution: Use Toradex FreeRTOS Examples

Instead of the Zephyr tutorial, I recommend using Toradex’s validated FreeRTOS examples for Colibri iMX7, which have been tested and validated with embedded Linux running on the A-cores (1).

Step 1: Set Up FreeRTOS Environment

  1. Install dependencies (1):
sudo apt-get install make cmake libc6:i386 libncurses6:i386
  1. Clone the FreeRTOS repository (1):
git clone -b master https://github.com/toradex/FreeRTOS-Colibri-iMX7 freertos-colibri-imx7/
cd freertos-colibri-imx7/
  1. Download and install GCC toolchain (1):
tar xjf ~/Downloads/gcc-arm-none-eabi-4_9-2015q3-20150921-linux.tar.bz2

Step 2: Build RPMsg Example

  1. Set environment variables and build (1):
export ARMGCC_DIR=~/gcc-arm-none-eabi-4_9-2015q3/
cd examples/imx7_colibri_m4/demo_apps/rpmsg/str_echo_freertos/armgcc
./build_all.sh

Step 3: Device Tree Configuration

You need to disable UART_B in your Linux device tree since the FreeRTOS firmware uses it as its debugging console (1). The FreeRTOS firmware uses Colibri UART_B (RS232 X25-Top on the Colibri Evaluation Board) with a baudrate of 115200 (1).

Step 4: Load Firmware

For eMMC-based Colibri iMX7, use the ext4load method as described in the documentation (1):

# In U-Boot
fatload mmc 0:1 ${loadaddr} rpmsg_str_echo_freertos_example.elf
# Follow the complete loading procedure from the documentation

Step 5: Load RPMsg Driver

After booting Linux, load the RPMsg driver (1):

modprobe imx_rpmsg_tty

The Cortex-M4 should then print “hello world!” showing the channel was created correctly (1).

Why This Approach Works

The Toradex FreeRTOS examples include proper:

  • RDC Configuration: The firmware reassigns the Cortex-M4 and required peripherals to domain 1 (1)
  • Memory Management: Examples are linked to run in the TCM area (1)
  • Peripheral Isolation: Proper separation between A7 and M4 resources (1)

The validated examples ensure compatibility with Toradex Linux BSP and avoid the memory conflicts causing your system crashes.

Best regards, Toradex AI Assistant.

@ToradexAI

I wish I could try RPMSG examples from Toradex FreeRTOS environment, but there is no device tree overlay example for RPMSG available for IMX7D.

You’re correct about the device tree overlay availability. According to the official Toradex documentation, the colibri-imx7_hmp_overlay.dts is marked as “Coming soon” in the master branch(1).

Current Status of iMX7D RPMsg Overlays

The device tree overlay status table shows(1):

Overlay Status Device Tree Overlays Repository Branch
colibri-imx7_hmp_overlay.dts Coming soon master

Alternative Approaches for iMX7D RPMsg

Since the ready-to-use overlay isn’t available yet, you have two main options:

Option 1: Create a Custom Device Tree Overlay

You can create your own RPMsg overlay for Colibri iMX7D by following the device tree overlay creation process(2). The documentation provides a template structure for creating custom overlays(2):

/dts-v1/;
/plugin/; //Indicates a Device Tree Overlay

// Header file with pin definitions
#include <soc-pinfunc.h>

/ {
	compatible = "toradex,colibri-imx7"; // Set hardware compatibility for iMX7D
};

&iomuxc {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl-originally-in-device-tree>, <&pinctrl_my_pins>;  // Pin group available in userspace i.e. as GPIO

	name-of-som {
		pinctrl_my_pins: my_muxgrp {
			fsl,pins = <
				PIN_NAME_PIN_MUX   PAD_CTRL // PINS
			>;
		};
	};
};

&node {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_my_pins>;  // Pin group used in genericPeripheral
	status = "okay";
};

(2)

Option 2: Modify the Full Device Tree

Since device tree overlays are primarily useful for simple modifications and when you have multiple configurations(3), and given that RPMsg requires specific memory buffer allocations(1), you might need to modify the full device tree directly.

For RPMsg to work properly, it’s necessary to allocate the correct RAM buffers in the device tree file(1). The overlays are compatible with all downstream and upstream-based modules starting from BSP and Torizon OS 6(1).

Memory Buffer Configuration for RPMsg

The documentation explains that RPMsg requires specific memory addresses and buffer reservations(1). You would need to configure these based on the memory layout for your iMX7D system, similar to how it’s done for other modules.

Recommendation

Given the complexity of RPMsg memory configuration and the fact that the official overlay isn’t available yet, I recommend reaching out to the Toradex Community to request priority for the colibri-imx7_hmp_overlay.dts development, as mentioned in the documentation(1).

Alternatively, you can examine the available overlays for other modules (like verdin-imx8mm_hmp_overlay.dts)(1) as a reference to understand the required memory buffer allocations and adapt them for your iMX7D system.

Best regards, Toradex AI Assistant.


Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.

Hey @luke-ros,

We currently don’t have an official HMP overlay for the Colibri iMX7D. I’ll send below an overlay for that is currently in development. Keep in mind that this is an experimental sample, and not an official one yet.

Also, I recommend following our official Heterogeneous Multi-core Processing Overview instead of documentation from external sources. It will instruct you on how to use the Cortex M in our modules, including the RPMSG communication between the A7 and M4.

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/* Copyright 2025 Toradex */

// Enable Remote proc / RPMSG for Colibri iMX7
#include "dt-bindings/clock/imx7d-clock.h"

/dts-v1/;
/plugin/;

/ {
	compatible = "toradex,colibri-imx7d",
		     "toradex,colibri-imx7d-emmc",
		     "toradex,colibri-imx7s";
};

&{/} {
	#address-cells = <1>;
	#size-cells = <1>;

	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;

		vdev0buffer: vdev0buffer@90002000 {
			compatible = "shared-dma-pool";
			reg = <0x90002000 0x8000>;
			no-map;
		};

		vdev0vring: vdev0vring@90000000 {
			compatible = "shared-dma-pool";
			reg = <0x90000000 0x1000>;
			no-map;
		};

		vdev0vring1: vdev0vring1@90001000 {
			compatible = "shared-dma-pool";
			reg = <0x90001000 0x1000>;
			no-map;
		};

		cm4tcmcode: cm4tcmcode@7f8000 {
			compatible = "shared-dma-pool";
			reg = <0x7f8000 0x8000>;
			no-map;
		};

		cm4sramcode: cm4sramcode@900000 {
			compatible = "shared-dma-pool";
			reg = <0x900000 0x40000>;
			no-map;
		};

		cm4reserved: cm4reserved@8ff00000 {
			compatible = "shared-dma-pool";
			reg = <0x8ff00000 0x100000>;
			no-map;
		};
	};

	imx7d-cm4 {
		compatible = "fsl,imx7d-cm4";
		mbox-names = "tx", "rx", "rxdb";
		mboxes = <&mu0a 0 0>, <&mu0a 1 0>, <&mu0a 3 0>;
		memory-region = <&vdev0buffer>, <&vdev0vring>, <&vdev0vring1>, <&cm4tcmcode>, <&cm4sramcode>, <&cm4reserved>;
		syscon = <&src>;
		clocks = <&clks IMX7D_ARM_M4_ROOT_CLK>;
	};
};

&mu0a {
	status = "okay";
};

Best regards,

Hi there,

This DTS is interesting although it doesn’t match the VRING definitions in the M4 Freertos-toradex examples : (in middleware/multicore/open-amp/porting/imx7d_m4/platform_info.c)
#define VRING0_BASE 0x8FFF0000
#define VRING1_BASE 0x8FFF8000

Do you have any compatible DTS for us to run with your examples on FreeRTOS too ?

Unfortunately we switched to a newer linux kernel and have to drop the old rpmsg implementation we had using the linux-toradex version 4.X

Best Regards,
Nicolas