From Variscite Wiki
VAR-SOM-MX8 - MCUXpresso 2.5.2


MCUXpresso SDK

MCUXpresso SDK board support provides example applications for NXP development and evaluation boards for Arm Cortex-M cores. Board support packages are found inside of the top level boards folder, and each supported board has its own folder (MCUXpresso SDK package can support multiple boards). Within each <board_name> folder there are various sub-folders to classify the type of examples they contain. These may include (but are not limited to):

  • cmsis_driver_examples: Simple applications intended to concisely illustrate how to use CMSIS drivers.
  • demo_apps: Full-featured applications intended to highlight key functionality and use cases of the target MCU. These applications typically use multiple MCU peripherals and may leverage stacks and middleware.
  • driver_examples: Simple applications intended to concisely illustrate how to use the MCUXpresso SDK’s peripheral drivers for a single use case.
  • rtos_examples: Basic FreeRTOS OS examples showcasing the use of various RTOS objects (semaphores, queues, and so on) and interfacing with the MCUXpresso SDK’s RTOS drivers.
  • multicore_examples: Simple applications intended to concisely illustrate how to use middleware/multicore stack.


Here we describe how to use ARM GCC toolchain, officially supported following Getting Started with MCUXpresso SDK for i.MX 8QuadMax.pdf.

iMX8 QM/QX boot flow

The boot process for iMX8QM/QX SoCs begins at Power On Reset (POR) where the hardware reset logic forces the System Controller (SCU) to begin execution starting from its on-chip boot ROM.

The platform boot is performed by the SCU and the Security Controller (SECO), working in concert to ensure that the intended and authorized set of images are loaded and started on various processing domains contained by the SoC.

The SCU plays the role of platform manager: it's the core that will interpret the boot settings, configure the interfaces/boot sources, look for the containers with boot images, and load these to the target on-chip or external memories.

Both the SCU and the SECO start execution, upon SoC POR, in their respective ROM memories.

A firmware (FW) image will be loaded for each as part of the boot process.

The images that will be loaded as part of the boot process are stored in containers.

A container can contain one or multiple images, as blocks of data specifying the load address, target address, etc.

At least two containers are needed for the boot process:

  • The first container will only contain the SECO FW Image.
  • The second container will typically contain:
    • The SCU FW image (SCFW)
    • The DDR Initialization image (embedded in SCFW)
    • The Cortex-M4 FW image(s)
    • The FW image(s) for the Cortex-A processing domain


In this scenario, the SCU plays the critical role to assign the resources before loading the Cortex-M4 and Cortex-A images.

Once the SCFW assigns specific resource to the Cortex-M4, this resource is not even visible from the Cortex-A, avoiding the need of dedicated device trees to prevent resource contentions.


As explained above, the SCU is in charge to assign resources before loading the images.

This means that the SCFW must be customized and rebuilt in order to assign required resources and pins to the M4.

You can build it by following the Build SCFW from source code page, but remember the default build will not enable M4 resources.

For your convenience, you can enable some sample defines here,

allowing some sample resource assignments referenced in the BSP.

Installing required packages

Install cmake

$ sudo apt-get install cmake

Download and install GNU-ARM bare-metal toolchain:

$ mkdir ~/var-mcuxpresso
$ cd ~/var-mcuxpresso
$ wget
$ tar xvf gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2

Download MCUXpresso SDK for the SOM:

$ cd ~/var-mcuxpresso
$ git clone -b mcuxpresso_sdk_2.5.x-var01
$ cd freertos-variscite


Original NXP documentation is available online or in the following folder:


Demos pins

Default M4 pins used by the demos are:

Function SoC balls VAR-SOM-MX8 pins Symphony pins SPEAR-MX8 pins SP8CustomBoard pins Notes
M40_UART0 RX / TX AM44 / AU51 N/A N/A J3.32 / J3.38 J40 SP8CustomBoard requires SW8 ON, SW9 OFF
DMA_UART2 RX / TX BE35 / BE37 J1.175 / J1.124 J18.5 / J18.3 J1.80 / J1.82 J26.19 /J26.17
DMA_UART4 RX / TX AR47 / AU53 J1.115 / J1.171 J18.9 / J18.7 J3.34 / J3.29 J20.2 / J20.4 SPEAR-MX8 demos do not refer it
FLEXCAN0 RX/TX C5 / H6 J1.46 / J1.44 J16.18 / J16.20 J4.79 / J4.80 J26.1 / J26.3
M41_I2C0 SCL/SDA AR45 / AU49 N/A N/A J1.9 / J3.36 J20.18 / J20.20
DMA_I2C0 SCL/SDA BN9 / BN7 J1.174 / J1.176 J16.10 / J16.12 J2.88 / J1.90 J26.2 / J26.4
DMA_SPI0 CS0 / SCK / SDI / SDO BC1 / BB4 / BA5 / AY6 J1.79 / J1.75 / J1.77 / J1.70 J17.10 / J17.6 / J17.8 / J17.4 J2.78 / j2.74 / J2.72 / J2.76 J20.7 / J20.1 / J20.5 / J20.3
ADC_IN6 AL9 J1.39 J16.4 J4.62 J29.16 VAR-SOM-MX8 requires enabling a buffer (refer to the datasheet)
M40_TPM0 0 / 1 AR47 / AU53 J1.115 / J1.171 J18.9 / J18.7 J3.34 / J3.29 J20.2 / J20.4 pins are share with with DMA_UART4
GPIO3_IO06 BA3 J1.40 J17.2 J2.80 J20.9

Available demos

All of the Variscite examples are located under the following folder


The available demos for VAR-SOM-MX8 are:

  • cmsis_driver_examples/lpi2c/int_b2b_transfer/master
  • cmsis_driver_examples/lpi2c/int_b2b_transfer/slave
  • cmsis_driver_examples/lpi2c/edma_b2b_transfer/master
  • cmsis_driver_examples/lpi2c/edma_b2b_transfer/slave
  • cmsis_driver_examples/lpuart/edma_transfer
  • cmsis_driver_examples/lpuart/interrupt_transfer
  • cmsis_driver_examples/lpspi/edma_b2b_transfer/master
  • cmsis_driver_examples/lpspi/edma_b2b_transfer/slave
  • cmsis_driver_examples/lpspi/int_b2b_transfer/master
  • cmsis_driver_examples/lpspi/int_b2b_transfer/slave
  • demo_apps/hello_world
  • driver_examples/canfd/loopback_transfer
  • driver_examples/canfd/loopback
  • driver_examples/canfd/interrupt_transfer
  • driver_examples/edma/scatter_gather
  • driver_examples/edma/memory_to_memory
  • driver_examples/flexcan/loopback_edma_transfer
  • driver_examples/flexcan/loopback_transfer
  • driver_examples/flexcan/loopback
  • driver_examples/flexcan/interrupt_transfer
  • driver_examples/intmux
  • driver_examples/lpadc/interrupt
  • driver_examples/lpadc/polling
  • driver_examples/lpi2c/edma_b2b_transfer/slave
  • driver_examples/lpi2c/edma_b2b_transfer/master
  • driver_examples/lpi2c/interrupt_b2b_transfer/slave
  • driver_examples/lpi2c/interrupt_b2b_transfer/master
  • driver_examples/lpi2c/polling_b2b_transfer/slave
  • driver_examples/lpi2c/polling_b2b_transfer/master
  • driver_examples/lpi2c/read_accel_value_transfer
  • driver_examples/lpspi/edma_b2b_transfer/master
  • driver_examples/lpspi/edma_b2b_transfer/slave
  • driver_examples/lpspi/interrupt_b2b/master
  • driver_examples/lpspi/interrupt_b2b/slave
  • driver_examples/lpspi/interrupt_b2b_transfer/master
  • driver_examples/lpspi/interrupt_b2b_transfer/slave
  • driver_examples/lpspi/polling_b2b_transfer/master
  • driver_examples/lpspi/polling_b2b_transfer/slave
  • driver_examples/lpspi/polling_b2b_transfer/master
  • driver_examples/lpspi/polling_b2b_transfer/slave
  • driver_examples/lpit
  • driver_examples/lpuart/edma_transfer
  • driver_examples/lpuart/interrupt_rb_transfer
  • driver_examples/lpuart/polling
  • driver_examples/lpuart/interrupt_transfer
  • driver_examples/lpuart/interrupt
  • driver_examples/gpio/led_output
  • driver_examples/rgpio/led_output
  • driver_examples/sema42/uboot
  • driver_examples/sema42/dual_core
  • driver_examples/tpm/timer
  • driver_examples/tpm/simple_pwm
  • driver_examples/tpm/pwm_twochannel
  • driver_examples/tpm/output_compare
  • driver_examples/tpm/input_capture
  • driver_examples/tpm/dual_edge_capture
  • driver_examples/tpm/combine_pwm
  • driver_examples/tstmr
  • driver_examples/wdog32
  • mmcau_examples/mmcau_api
  • multicore_examples/rpmsg_lite_pingpong_rtos/linux_remote
  • multicore_examples/rpmsg_lite_str_echo_rtos
  • multicore_examples/rpmsg_lite_pingpong_rtos/sdk_remote
  • multicore_examples/rpmsg_lite_pingpong_rtos/sdk_master
  • rtos_examples/freertos_hello
  • rtos_examples/freertos_queue
  • rtos_examples/freertos_sem
  • rtos_examples/freertos_generic
  • rtos_examples/freertos_tickless
  • rtos_examples/freertos_mutex
  • rtos_examples/freertos_lpuart
  • rtos_examples/freertos_event
  • rtos_examples/freertos_swtimer
  • rtos_examples/freertos_lpi2c
  • rtos_examples/freertos_lpspi_b2b/master
  • rtos_examples/freertos_lpspi_b2b/slave
  • rtos_examples/freertos_lpspi

Additional demos are available as reference code, but require HW/SW customization.

Almost all of the above demos are also available for IMX8QM-MEK.

You can build and run the demos following official NXP documentation for IMX8QM-MEK, available online or in the following document:

~/var-mcuxpresso/freertos-variscite/docs/Getting Started with MCUXpresso SDK for i.MX 8QuadMax.pdf

Building a demo

Building Manually

For any demo, follow these steps:

$ cd ~/var-mcuxpresso/freertos-variscite/boards/som_mx8qm
$ cd <demo_folder>
$ cd armgcc
$ export ARMGCC_DIR=~/var-mcuxpresso/gcc-arm-none-eabi-7-2018-q2-update
$ ./ > /dev/null

You can choose any <demo_folder> from the list available in the previous section.

The (optional M4_0 and) M4_1 images need now to be integrated in the U-Boot.

You can build U-Boot by following the Build U-Boot from source code page, but remember that you need to use a different build target and link the M4 image.

To build boot image, replace the commands available in the above page (at the end of secion 3), with

ln -sf <full_path_to_M4_0_image.bin> m4_image.bin
ln -sf <full_path_to_M4_1_image.bin> m4_1_image.bin
make -f soc.mak clean
make -f soc.mak SOC=iMX8QM MKIMG=./mkimage_imx8 PAD_IMAGE=./ <flash_target>
mv flash.bin imx-boot-sd.bin

There are two possible flash_targets: the flash_target must match the linker options used to generate the binary (refer to the next section for further detains):

For BSP version 4.14.98_2.0.0

  • flash_regression_linux_m4: for M4 0 and M4 1 images generated in the release folder (M4 code located in TCM)
  • flash_regression_linux_m4_ddr: for M4 0 and M4 1 images generated in the ddr_release folder (M4 code located in DDR)
  • flash_regression_linux_m41: for M4 1 (only) images generated in the release folder (M4 code located in TCM)
  • flash_regression_linux_m41_ddr: for M4 1 (only) images generated in the ddr_release folder (M4 code located in DDR)

Fow new version of BSPs

  • flash_linux_m4: for M4 0 and M4 1 images generated in the release folder (M4 code located in TCM)

Building Using Yocto

In Yocto Dunfell and newer, Variscite provides a Yocto recipe for building and installing firmware into the Yocto image. Note, the examples below apply to the original release of this recipe in Dunfell and thus some of the syntax (such as the overrides) may need to be updated for newer versions.

This recipe installs the following firmware files:

File Memory Loaded Using...
/boot/cm_<demo name>.bin.debug TCM U-Boot
/boot/cm_<demo name>.bin.ddr_debug DDR U-Boot
/lib/firmware/cm_<demo name>.elf.debug TCM Linux Remoteproc Framework
/lib/firmware/cm_<demo name>.elf.ddr_debug DDR Linux Remoteproc Framework

If you have modified freertos-variscite in your own Git repository and kept the same directory structure, you can easily build your custom firmware by creating a bbappend file:

$ mkdir -p <your-layer>/recipes-bsp/freertos-variscite
$ nano <your-layer>/recipes-bsp/freertos-variscite/freertos-variscite_2.9.x.bbappend

Append SRC_URI and SRCREV to use your freertos-variscite Git repository

SRC_URI_remove = "git://;protocol=git;branch=${MCUXPRESSO_BRANCH};"
SRC_URI_append = " <your Git repository>"
SRCREV = "<your Git commit id>"

Append CM_DEMOS to build your firmware. For example, to build rtos_examples/freertos_hello:

CM_DEMOS_append = "rtos_examples/freertos_hello"

Rebuild fsl-image-gui:

$ bitbake -c cleansstate freertos-variscite && bitbake fsl-image-gui

The firmware binary files should now be installed to /boot/ and elf files to /lib/firmware/

Memory types

The SDK allow linking using 2 different memory types: DDR, TCM.

Here is available a short summary of memory areas used by Cortex-M4 as described in related linker file.

memory type M4 if M4 memory area memory lentgh linker file
DDR 0 0x88000000-0x881FFFFF (code)
0x88200000-0x883FFFFF (data)
0x88400000-0x887FFFFF (data2)
8MB (DDR) MIMX8QM6xxxFF_cm4_core0_ddr_ram.ld
DDR 1 0x88800000-0x88BFFFFF (code)
0x88C00000-0x88FFFFFF (data)
0x89000000-0x8FFFFFFF (data2)
120MB (DDR) MIMX8QM6xxxFF_cm4_core1_ddr_ram.ld
TCM 0 0x1FFE0000-0x1FFFFFFF (code)
0x20000000-0x2001FFFF (data)
0x88000000-0x887FFFFF (data2)
256kB (TCM) + 8MB (DDR) MIMX8QM6xxxFF_cm4_core0_ram.ld
TCM 1 0x1FFE0000-0x1FFFFFFF (code)
0x20000000-0x2001FFFF (data)
0x88800000-0x8FFFFFFF (data2)
256kB (TCM) + 120MB (DDR) MIMX8QM6xxxFF_cm4_core1_ram.ld

All linker files are locate in the armgcc folder of each demo.

After launching the command the following folder will be created in the armgcc folder

  • ddr_debug: containing DDR binaries compiled in debug mode (not stripped: symbols available)
  • ddr_release: containing DDR binaries compiled in release mode (stripped: no symbols available)
  • debug: containing TCM binaries compiled in debug mode (not stripped: symbols available)
  • release: containing TCM binaries compiled in release mode (stripped: no symbols available)

Running a demo

Running a demo from U-Boot

Since the SCU will automatically read and load the Cortex-M application, no actions are required by the users.

For Yocto Dunfell and newer, this process can be simplified using /etc/remoteproc/variscite-rproc-u-boot
Please refer to the Yocto Scripts section below for more information

Debugging a demo

JTAG Hardware

The Cortex-M firmware can be debugged using a JTAG debugger. Variscite recommends using a Segger J-Link Ultra+, J-Link Pro, or J-Link Wi-Fi debugger. You may also need a 9-pin Cortex-M adapter from Segger.

JTAG interface

The VAR-SOM-MX8 and SPEAR-MX8 exposes JTAG interface via an optional 10-pin header

Here is the pinout:

pin signal description pin signal (ball) description
1 JTAG_VREF JTAG reference voltage (3.3V) 2 JTAG_TMS (AG35) JTAG Mode Select
3 GND Digital Ground 4 JTAG_TCK (AE31) JTAG Clock
5 GND Digital Ground 6 JTAG_TDO (AF32) JTAG Data Out
7 RTCK JTAG Return clock 8 JTAG_TDI (AH34) JTAG Data In

Please refer to SOM datasheet for further details.

Developing with IAR Embedded Workbench

NXP provides a detailed step by step procedure to develop and debug MCUXpresso firmware using IAR Embedded Workbench and SEGGER SEGGER J-Link. Please refer to online or in the following document:

~/var-mcuxpresso/freertos-variscite/docs/Getting Started with MCUXpresso SDK for i.MX 8QuadMax.pdf

Developing with Visual Studio Code

Visual Studio Code, which is freely available, can be used to develop and debug MCUXpresso firmware:

Vscode MCUXpresso StoppedAtBreakPoint.png

For a full guide demonstrating how to get started, please refer to MCUXpresso Development with VS Code.