MCUXpresso
Overview
Release Notes
For full details about this release, refer to the Release Notes.
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 MEK-MIMX8QM.pdf.
Prerequisites
Before starting, prepare a Yocto boot SD card (with kernel 5.4.85 or newer).
To allow Cortex M4 accessing shared resources without experiencing Linux kernel conflicts, a dedicated device tree must be loaded, containing m4 label in the name, using the fdt_file environment variable in U-Boot.
This device tree disables some of the base device tree nodes in order to avoid conflicts between the main processor and Cortex M4.
File Name |
Description |
---|---|
imx8qm-var-som-symphony-dp-m4.dtb | DTB file for VAR-SOM-MX8 with DP display and Cortex-M4 on Symphony Board for kernel >= 5.10.72 (Yocto Hardknott) |
imx8qm-var-som-symphony-hdmi-m4.dtb | DTB file for VAR-SOM-MX8 with HDMI display and Cortex-M4 on Symphony Board for kernel >= 5.10.72 (Yocto Hardknott) |
imx8qm-var-som-symphony-lvds-m4.dtb | DTB file for VAR-SOM-MX8 with LVDS display and Cortex-M4 on Symphony Board for kernel >= 5.10.72 (Yocto Hardknott) |
imx8qm-var-spear-sp8customboard-dp-m4.dtb | DTB file for SPEAR-MX8 with DP display and Cortex-M4 on SP8CustomBoard for kernel >= 5.10.72 (Yocto Hardknott) |
imx8qm-var-spear-sp8customboard-hdmi-m4.dtb | DTB file for SPEAR-MX8 with HDMI display and Cortex-M4 on SP8CustomBoard for kernel >= 5.10.72 (Yocto Hardknott) |
imx8qm-var-spear-sp8customboard-lvds.m4.dtb | DTB file for SPEAR-MX8 with LVDS display and Cortex-M4 on SP8CustomBoard for kernel >= 5.10.72 (Yocto Hardknott) |
imx8qm-var-som-dp-m4.dtb | DTB file for VAR-SOM-MX8 with DP display and Cortex-M4 on Symphony Board for kernel = 5.4.142 (Yocto Dunfell) |
imx8qm-var-som-hdmi-m4.dtb | DTB file for VAR-SOM-MX8 with HDMI display and Cortex-M4 on Symphony Board for kernel = 5.4.142 (Yocto Dunfell) |
imx8qm-var-som-lvds-m4.dtb | DTB file for VAR-SOM-MX8 with LVDS display and Cortex-M4 on Symphony Board for kernel = 5.4.142 (Yocto Dunfell) |
imx8qm-var-spear-dp-m4.dtb | DTB file for SPEAR-MX8 with DP display and Cortex-M4 on SP8CustomBoard for kernel = 5.4.142 (Yocto Dunfell) |
imx8qm-var-spear-hdmi-m4.dtb | DTB file for SPEAR-MX8 with HDMI display and Cortex-M4 on SP8CustomBoard for kernel = 5.4.142 (Yocto Dunfell) |
imx8qm-var-spear-lvds-m4.dtb | DTB file for SPEAR-MX8 with LVDS display and Cortex-M4 on SP8CustomBoard for kernel = 5.4.142 (Yocto Dunfell) |
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 https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 $ tar xvf gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2
Download MCUXpresso SDK for the SOM:
$ cd ~/var-mcuxpresso $ git clone https://github.com/varigit/freertos-variscite -b mcuxpresso_sdk_2.9.x-var01 $ cd freertos-variscite
Documentation
Original NXP documentation is available online or in the following folder:
~/var-mcuxpresso/freertos-variscite/docs
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
~/var-mcuxpresso/freertos-variscite/boards/som_mx8qm
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 MEK-MIMX8QM.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-9-2020-q2-update $ ./build_all.sh > /dev/null
You can choose any <demo_folder> from the list available in the previous section.
Then copy the ".bin" to the boot media (either the SD card or eMMC) in the /boot folder already hosting the Linux device trees.
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.
https://github.com/varigit/meta-variscite-fslc/tree/dunfell/recipes-bsp/freertos-variscite
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
# Yocto Hardknott and older SRC_URI_remove = "git://github.com/varigit/freertos-variscite.git;protocol=git;branch=${MCUXPRESSO_BRANCH};" SRC_URI_append = " <your Git repository>" # Yocto Kirkstone and newer SRC_URI:remove = "git://github.com/varigit/freertos-variscite.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:
# Yocto Hardknott and older CM_DEMOS_append = "rtos_examples/freertos_hello" # Yocto Kirkstone and newer 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 build_all.sh 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
To allow Cortex-M accessing shared resources without experiencing Linux kernel conflicts, a dedicated device tree must be loaded.
To enable Cortex-M:
=> setenv use_m40 yes; saveenv => setenv use_m41 yes; saveenv
To disable Cortex-M:
=> setenv use_m40 no; saveenv => setenv use_m41 no; saveenv
Binary demos must be loaded to the memory type used for linking.
To use TCM:
(default setting) => setenv m40_addr 0x88000000; saveenv (TCM is at 0x34FE0000, but U-Boot load to 0x88000000) => setenv m41_addr 0x88800000; saveenv (TCM is at 0x38FE0000, but U-Boot load to 0x88800000)
To use DDR:
(default setting) => setenv m40_addr 0x88000000; saveenv => setenv m41_addr 0x88800000; saveenv
To set the name of the Cortex-M binary
=> setenv m40_bin myapp.bin; saveenv => setenv m41_bin myapp.bin; saveenv
The .bin file is expected in the folder /boot of the booting media.
The U-Boot boot command will handle loading the Cortex-M firmware and start Linux for VAR-SOM-MX8.
For testing, it is possible to run the firmware manually:
=> run loadm40bin && run runm40bin => run loadm41bin && run runm41bin
Additional details and step by step procedure to run each of the demos is available online or in the following document:
~/var-mcuxpresso/freertos-variscite/docs/Getting Started with MCUXpresso SDK for MEK-MIMX8QM.pdf
Please refer to the Yocto Scripts section below for more information
Running a demo from Linux
The Linux remoteproc framework can be used to load the Cortex m4 firmware from Linux userspace.
Follow these steps to verify the Linux remoteproc framework is supported for your release:
- Select the software release from the VAR-SOM-MX8 software overview page.
- Click on Release Notes.
- Look for the Cortex m4 Linux remoteproc support row in the release notes to see which version is supported. If Cortex m4 Linux remoteproc support is not in the release notes table, the Linux remoteproc framework is not supported.
After confirming Linux remoteproc support, follow these steps to use the framework:
Increase kernel loglevel while debugging:
# sysctl kernel.printk=7;
Check the state of the m4, it should be running already by U-Boot
# cat /sys/class/remoteproc/remoteproc0/state
If the state is 'running', stop the m4
# echo stop > /sys/class/remoteproc/remoteproc0/state
Load new firmware (.elf file must already exist in /lib/firmware directory)
# echo hello_world.elf > /sys/class/remoteproc/remoteproc0/firmware
Run the new firmware
# echo start > /sys/class/remoteproc/remoteproc0/state
For Example:
# echo cm_rpmsg_lite_pingpong_rtos_linux_remote.elf.ddr_debug > /sys/class/remoteproc/remoteproc0/firmware # echo start > /sys/class/remoteproc/remoteproc0/state # echo stop > /sys/class/remoteproc/remoteproc0/state
# echo cm_disable_cache.elf.debug > /sys/class/remoteproc/remoteproc0/firmware # echo start > /sys/class/remoteproc/remoteproc0/state # echo stop > /sys/class/remoteproc/remoteproc0/state
# echo cm_rpmsg_lite_str_echo_rtos_imxcm4.elf.ddr_debug > /sys/class/remoteproc/remoteproc0/firmware # echo start > /sys/class/remoteproc/remoteproc0/state # echo stop > /sys/class/remoteproc/remoteproc0/state
Please refer to the Yocto Scripts section below for more information
Running a Demo using Yocto Scripts
In Yocto Dunfell and newer, Variscite provides scripts to simplify loading firmware via U-Boot or Linux:
Script | Description |
---|---|
/etc/remoteproc/variscite-rproc-u-boot | Configure U-Boot to load firmware on boot |
/etc/remoteproc/variscite-rproc-linux | Load and run firmware using Linux remoteproc framework |
Examples variscite-rproc-u-boot example on imx8mm-var-dart:
root@imx8mm-var-dart:~# /etc/remoteproc/variscite-rproc-u-boot -f /boot/cm_hello_world.bin.ddr_debug Configuring for DDR memory + fw_setenv m4_addr 0x7E000000 + fw_setenv fdt_file imx8mm-var-som-symphony-m4.dtb + fw_setenv use_m4 yes + fw_setenv m4_bin cm_hello_world.bin.ddr_debug Finished: Please reboot, the m4 firmware will run during U-Boot
variscite-rproc-linux example on imx8mm-var-dart:
root@imx8mm-var-dart:~# /etc/remoteproc/variscite-rproc-linux -f /lib/firmware/cm_hello_world.elf.ddr_debug Cortex-M: Stopping [ 359.212638] remoteproc remoteproc0: stopped remote processor imx-rproc [ 359.219709] remoteproc remoteproc0: powering up imx-rproc Cortex-M: Loading cm_hello_world.elf.ddr_debug [ 359.227101] remoteproc remoteproc0: Booting fw image cm_hello_world.elf.ddr_debug, size 269100 [ 359.238493] imx-rproc imx8mm-cm4: m4 ddr @ 0x7e000000 [ 359.243584] remoteproc remoteproc0: no dtb rsrc-table [ 359.248797] imx-rproc imx8mm-cm4: Setting up stack pointer and reset vector from firmware in DDR [ 359.257626] imx-rproc imx8mm-cm4: Stack: 0x7e400000 [ 359.262542] imx-rproc imx8mm-cm4: Reset Vector: 0x7e00030d Cortex-M: Starting [ 359.318074] remoteproc remoteproc0: remote processor imx-rproc is now up
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 |
9 | JTAG_TRST_B_CONN | JTAG TAP reset | 10 | JTAG_SRST_B | JTAG System reset |
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 MEK-MIMX8QM.pdf
Developing with Visual Studio Code
Visual Studio Code, which is freely available, can be used to develop and debug MCUXpresso firmware:
For a full guide demonstrating how to get started, please refer to MCUXpresso Development with VS Code.