The i.MX8M Nano CPU includes a Cortex-M7 low-power processor that features a single ARMĀ® Cortex-M7 processor. The Cortex-M7 processor is a highly efficient, high-performance, embedded processor that features low interrupt latency, low-cost debug, and has backwards compatibility with existing Cortex-M profile processors. The processor has an in-order superscalar pipeline that can execute dual instructions, including load/load and load/store instruction pairs.

Features

The Cortex-M7 on the i.MX8M Nano CPU includes the following features:

  • Arm Cortex-M7 CPU Processor

    • 32 KB L1 instruction cache

    • 32 KB L1 data cache

    • 256 KB tightly coupled memory (TCM)

  • Low-power standby mode

  • IoT features including Weave

  • Manage IR or wireless remote

  • Machine learning (ML) inference applications (enhanced for i.MX8M Nano)

Messaging Unit (MU) Features

The processors communicate through the Messaging Unit (MU), which enables two processors within the SoC to communicate and coordinate by passing messages (e.g. data, status, and control). The MU also enables one processor to signal the other processor using interrupts.

The MU includes the following features:

  • Messaging control by interrupts or by polling.

  • Processor B can take Processor A out of low-power mode by asserting one of the twelve interrupts to Processor A, and vice versa.

  • Symmetrical processor interfaces, with each side supporting the following:

    • Four general-purpose interrupt requests reflected to the other side.

    • Three general-purpose flags reflected to the other side.

    • Four receive registers with maskable interrupt.

    • Four transmit registers with maskable interrupt.

Debug console UART

The Cortex-M7 can use UART4 as debug console. While UART4 is being used by the Cortex-M7, it is not available for the Cortex-A53.

On the ConnectCore 8M Nano Development Kit, UART4 is routed to the XBee socket via 0-ohm resistors.

UART4 multiplexing on the DVK

If you are not going to use the XBee socket, you can remove resistors R152 and R154 and populate 0-ohm resistors R151 and R153. This hardware change routes UART4 lines to connector J17 (at TTL level) and to the FTDI chip, making the UART available at the micro USB connector J16, in parallel with the system console. Once you have connected the Cortex-M7 UART to the FTDI chip, open another serial terminal application for this second serial device, setting the speed to 115200 bps, 8 data bits, 1 stop bit (115200, 8N1), no parity.

Pre-built demo applications

You can find several pre-built demo applications for the Cortex-M7 in the deploy images directory of your Digi Embedded Yocto project.

Cortex-M7 demo application Description

imx8mn_m7_TCM_hello_world.bin

Prints "Hello World!" on the Cortex-M7 debug console. (See Debug console UART.)

imx8mn_m7_TCM_rpmsg_lite_pingpong_rtos_linux_remote.bin

Demo of FreeRTOS running a ping-pong communication between Cortex-M7 and Cortex-A53.

imx8mn_m7_TCM_rpmsg_lite_str_echo_rtos.bin

Demo of FreeRTOS that prints on the console the received messages.

imx8mn_m7_TCM_sai_low_power_audio.bin

Audio demo for NXP EVK.

Download the SDK and toolchain

NXP offers an SDK that facilitates firmware development for the Cortex-M7 core. The SDK provides examples that demonstrate how to access the peripherals available on this subsystem.

You may need to register for an account on the NXP website.
  1. Go to https://mcuxpresso.nxp.com/en/builder.

  2. On the left sidebar, click Select Board.

  3. Select Boards > i.MX > EVK-MIMX8MN.

  4. Click Build MCUXpresso SDK.

  5. Select your Toolchain/IDE and your Host OS.

  6. Click Download SDK.

You must also download the toolchain to build your firmware application:

  1. Go to https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads.

  2. Select the latest supported version for your operating system, as described in the MCUXpresso SDK Release Notes.

Install the SDK and toolchain

  1. Decompress the SDK in a directory of your choice:

    $ tar -xvf <SDK_VER>_EVK-MIMX8MN.tar.gz -C <sdk-install-path>
  2. Decompress the toolchain in a directory of your choice:

    $ tar -xvf gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 -C <toolchain-install-path>

Build the "Hello World" demo application

  1. Export the variable ARMGCC_DIR with the absolute path to the GCC ARM Embedded toolchain.

    $ export ARMGCC_DIR=<toolchain-install-path>/gcc-arm-none-eabi-9-2019-q4-major
  2. Add the toolchain bin folder to the system $PATH

    $ export PATH=$PATH:$ARMGCC_DIR/bin
  3. Build the hello_world application.

    $ cd <sdk-install-path>/boards/evkmimx8mn/demo_apps/hello_world/armgcc
    $ ./build_all.sh

    Find the artifacts in the debug/release directory.

For more information, see the MCUXpresso Software Development Kit

Transfer and run the demo application

  1. Boot your device and stop in the U-Boot console.

  2. Transfer the application to RAM, for example via TFTP:

    => tftp $loadaddr <m7_firmware.bin>
    TFTP from server 192.168.1.1; our IP address is 192.168.1.2
    Filename 'm7_firmware.bin'.
    Load address: 0x40480000
    Loading: #
              1.6 MiB/s
    done
    Bytes transferred = 6528 (1980 hex)

    where <m7_firmware.bin> is the binary filename.

  3. Transfer the firmware to the Cortex-M7 memory:

    => cp.b $loadaddr 0x7e0000 $filesize
  4. Use the bootaux command to run the application on the Cortex-M7:

    => bootaux 0x7e0000
    ## Starting auxiliary core stack = 0x20020000, pc = 0x00000305...

Auto-run the firmware on every boot

The Cortex-M7 doesn’t have ROM memory. To instruct the Cortex-M7 to run an application every time the device boots, you must store the application on the eMMC and modify U-Boot’s default bootcmd to load the firmware to RAM and run it on the Cortex-M7 before booting the operating system.

To store the application on the linux partition:

=> updatefile linux tftp <m7_firmware.bin>

To auto-run the firmware application when the device is powered up:

=> setenv boot_cortexm "load mmc 0:1 ${loadaddr} <m7_firmware.bin>; cp.b ${loadaddr} 0x7e0000 ${filesize}; bootaux 0x7e0000"
=> setenv bootcmd "run boot_cortexm; ${bootcmd}"
=> saveenv

Linux remoteproc framework

Modern SoCs typically have remote processing devices on the same chip silicon. The remoteproc framework allows different platforms/architectures to control (power on, load firmware, power off) those remote processors.

The firmware file must be in ELF format to be used with the remoteproc framework.

Enable the remoteproc framework

remoteproc support is enabled as built-in on the ConnectCore 8M Nano Development Kit kernel configuration file.

  • Linux remoteproc framework (CONFIG_REMOTEPROC)

  • IMX remoteproc driver (CONFIG_IMX_REMOTEPROC)

Control remote processors with remoteproc framework

You can use the remoteproc framework to load firmware onto an SoC and power it off and on. The ConnectCore 8M Nano uses overlays to configure device tree entries for the remoteproc framework. To load the overlay, use the following command in U-Boot:

=> setenv overlays _ov_som_cm7_ccimx8mn.dtbo
=> saveenv

This creates a new device node in the sysfs that allows access to the Cortex-M7. The location of the remoteproc device is available in the file system at:

# /sys/class/remoteproc/remoteprocX

Where X is the index of the device node, by default 0.

Use the following commands to load, start, and stop the Cortex-M7 firmware:

# echo -n <firmware_name.elf> > /sys/class/remoteproc/remoteproc0/firmware
# echo start > /sys/class/remoteproc/remoteproc0/state
# echo stop > /sys/class/remoteproc/remoteproc0/state

You can monitor the state of the remoteproc firmware with:

# cat /sys/class/remoteproc/remoteproc0/state