NXP i.MX RT1064-EVK

This is a step-by-step bring-up of the Mender MCU client on the NXP MIMXRT1064-EVK with Zephyr: clone the sources, build a signed image, flash it, enroll the device on hosted Mender, and deploy an over-the-air update with rollback protection. The board configuration and one client modification it needs are already prepared on a branch, so the path is mostly running commands and supplying your own tenant token.

What you need

  • A Zephyr development host with west and the Zephyr SDK 0.17.0
  • mender-artifact 4.2.0 or newer on your PATH — the build uses it to package the .mender Artifact
  • pyocd for flashing — the EVK’s onboard DAPLink (CMSIS-DAP) probe works with it as shipped, no reflashing
  • A MIMXRT1064-EVK connected by USB (this gives both the debug probe and a console serial port) and to your Ethernet network
  • A hosted Mender account and its tenant token

1. Get the sources

Everything is driven from one repository, the mender-mcu-integration fork branch that carries the board files. Cloning it and running west update pulls Zephyr 4.2.0, MCUboot, the NXP HAL and the mender-mcu module:

mkdir mender-imxrt && cd mender-imxrt
git clone -b imxrt1064-evk-support https://github.com/TheYoctoJester/mender-mcu-integration
west init -l mender-mcu-integration
west update
west zephyr-export
pip install -r zephyr/scripts/requirements.txt
export ZEPHYR_SDK_INSTALL_DIR=/path/to/zephyr-sdk-0.17.0

The manifest on this branch points mender-mcu at a fork branch rather than upstream. The reason is specific to this SoC: the i.MX RT executes in place from the same FlexSPI NOR that holds the MCUboot update slots, so writing a download straight to flash stalls the network mid-transfer. The fork branch stages the download in RAM and writes flash once at the end, which avoids the conflict. (This change is generally useful and should move upstream; when it does, repoint the mender-mcu entry back at the mender remote.)

2. What the board support provides

These files are already present in the branch; you do not need to create them. They are worth understanding if you intend to adapt the work to a related board.

boards/mimxrt1064_evk.conf enables the onboard Ethernet and sizes the network stack for the download:

# Onboard Ethernet (ENET MAC + Microchip KSZ8081 PHY). Only the L2 is set by hand;
# the NXP ENET driver auto-enables from devicetree.
CONFIG_NET_L2_ETHERNET=y
CONFIG_HWINFO=y

# The board's default TCP window (~1536 B) is too small for the TLS handshake and
# the Artifact download; these give the stack room. The RT1064 has 32 MB of SDRAM.
CONFIG_NET_PKT_RX_COUNT=40
CONFIG_NET_PKT_TX_COUNT=40
CONFIG_NET_BUF_RX_COUNT=120
CONFIG_NET_BUF_TX_COUNT=120
CONFIG_NET_BUF_DATA_SIZE=256
CONFIG_NET_TCP_MAX_RECV_WINDOW_SIZE=8192
CONFIG_NET_TCP_MAX_SEND_WINDOW_SIZE=8192
CONFIG_DNS_NUM_CONCUR_QUERIES=4

# Max out the ENET DMA ring (driver ceiling) so the MAC keeps up during the download.
CONFIG_ETH_NXP_ENET_RX_BUFFERS=16
CONFIG_ETH_NXP_ENET_TX_BUFFERS=8

boards/mimxrt1064_evk.overlay pins a fixed MAC address:

&enet_mac {
	/delete-property/ zephyr,random-mac-address;
	local-mac-address = [02 11 64 00 00 02];
};

The board devicetree otherwise uses a random MAC, generated fresh on every boot. Since the Mender client derives its device identity from the MAC, that would make the device re-register as new after each reset. A fixed, locally administered address (0x02 first octet) gives it a stable identity.

3. Supply your settings

Three settings are yours to provide. 0ne is a secret, so keep them outside the repository. Create mender-creds.conf in the workspace root:

# Your hosted Mender tenant token, from Organization & billing settings.
CONFIG_MENDER_SERVER_TENANT_TOKEN="<your-tenant-token>"

# Artifact name. Bump it for every build you intend to deploy.
CONFIG_MENDER_ARTIFACT_NAME="mimxrt1064-zephyr-v1"

# Use the standard device tier for development.
CONFIG_MENDER_DEVICE_TIER_STANDARD=y

During development, the standard tier, not the default micro tier: micro is metered separately on hosted Mender and, if your tenant has no micro-tier capacity, the device cannot be accepted at all (the accept call returns 422). The most important part is that standard accepts shorter polling intervals, which is extremely useful during development. Standard tier also lifts the micro tier’s 5 MB Artifact size cap which is nice for experimentation.

4. Build

The image is built with sysbuild so MCUboot is built and the application signed together. Pass the integration’s sysbuild config and your credentials fragment:

west build -b mimxrt1064_evk --sysbuild -d build/mender mender-mcu-integration \
    -- -DSB_CONF_FILE=$PWD/mender-mcu-integration/sysbuild-mcuboot.conf \
       -Dmender-mcu-integration_EXTRA_CONF_FILE=$PWD/mender-creds.conf

The build produces the bootloader, the signed application and the deployable Artifact:

build/mender/mcuboot/zephyr/zephyr.bin                        -> bootloader  -> 0x70000000
build/mender/mender-mcu-integration/zephyr/zephyr.signed.bin  -> application -> 0x70020000
build/mender/mender-mcu-integration/zephyr/zephyr.mender      -> Artifact (upload this)

5. Flash

MCUboot carries the FlexSPI boot header and goes at the start of the internal NOR; the signed application goes at the slot-0 offset. The mimxrt1064 target is built into pyocd, so no CMSIS pack is needed:

pyocd erase -t mimxrt1064 --chip
pyocd flash -t mimxrt1064 --base-address 0x70000000 build/mender/mcuboot/zephyr/zephyr.bin
pyocd flash -t mimxrt1064 --base-address 0x70020000 build/mender/mender-mcu-integration/zephyr/zephyr.signed.bin
pyocd reset -t mimxrt1064

Open the console — the DAPLink probe exposes it as a USB CDC port, usually /dev/ttyACM0, at 115200 baud.

6. Enroll the device

On boot the device acquires an address and contacts hosted Mender:

*** Booting Zephyr OS build v4.2.0 ***
<inf> mender_app: Identity: '{"mac": "02:11:64:00:00:02"}'
<inf> net_dhcpv4: Received: 192.168.1.52
<inf> mender: Checking for deployment...
<err> mender: [401] Unauthorized: dev auth: unauthorized

The 401 is expected: the device has submitted its authentication request and is now pending. Accept it in the Mender UI (or via the management API). The next poll then reads No deployment available, and the device’s inventory — including the Artifact name from your build — appears against it.

7. Deploy an update

Bump the Artifact name and rebuild:

# in mender-creds.conf: CONFIG_MENDER_ARTIFACT_NAME="mimxrt1064-zephyr-v2"
west build -b mimxrt1064_evk --sysbuild -d build/mender mender-mcu-integration \
    -- -DSB_CONF_FILE=$PWD/mender-mcu-integration/sysbuild-mcuboot.conf \
       -Dmender-mcu-integration_EXTRA_CONF_FILE=$PWD/mender-creds.conf

Upload the new build/mender/mender-mcu-integration/zephyr/zephyr.mender to hosted Mender and create a deployment for the device. The console shows the full cycle:

<inf> mender: Staging 337324 bytes in SDRAM before flashing
<inf> mender: Downloading 'zephyr-image' 10%... 50%... 90%...
<inf> mender: Writing 337324 staged bytes to flash
*** Booting MCUboot v2.2.0 ***
I: Swap type: test
<inf> mender: Application has been marked valid and rollback canceled
<dbg> mender_app: deployment_status_cb: success

MCUboot performs the test swap, the new image boots and confirms itself, and the deployment reports success. The device reports the new Artifact name and stays on it across reboots. If the new image had failed to confirm, MCUboot would have rolled back to the previous one automatically on the next boot.

That completes the cycle: build, flash, enroll, and OTA update with rollback protection on the i.MX RT1064-EVK.

Further reading