Skip to main content

Zephyr on NXPs MCX-N

First announced in 2022, I finally have an MCX-N evalboard fron NXP on my table. The FRDM-MCXN947 eval board has a nice form factor and so I am eager to see if I can Zephyr to run on that board. The Zephyr documentation for the eval board seems to indicate that this should be easy to do. Let's find out.

FRDM-MCXN947-TOP.png

Compiling blinky

Let's try compiling the blinky example in a detached directory:

dzu@krikkit:~/src/zephyr/blinky$ west build -b frdm_mcxn947
-- west build: generating a build system
Loading Zephyr default modules (Zephyr base).
-- Application: /home/dzu/src/zephyr/blinky
-- CMake version: 3.28.3
-- Found Python3: /usr/local/bin/python3 (found suitable version "3.11.8", minimum required is "3.8") found components: Interpreter 
-- Cache files will be written to: /home/dzu/.cache/zephyr
-- Zephyr version: 3.6.99 (/opt/src/git/zephyrproject/zephyr)
-- Found west (found suitable version "1.1.0", minimum required is "0.14.0")
CMake Error at /opt/src/git/zephyrproject/zephyr/cmake/modules/boards.cmake:320 (message):
  Board qualifiers `/mcxn947` for board `frdm_mcxn947` not found.  Please
  specify a valid board target.

  Valid board targets for are:

  frdm_mcxn947/mcxn947/cpu0

  frdm_mcxn947/mcxn947/cpu1

Call Stack (most recent call first):
  /opt/src/git/zephyrproject/zephyr/cmake/modules/zephyr_default.cmake:132 (include)
  /opt/src/git/zephyrproject/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
  /opt/src/git/zephyrproject/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
  CMakeLists.txt:4 (find_package)


-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/bin/cmake -DWEST_PYTHON=/usr/local/bin/python3 -B/home/dzu/src/zephyr/blinky/build/frdm_mcxn947 -GNinja -DBOARD=frdm_mcxn947 -S/home/dzu/src/zephyr/blinky
dzu@krikkit:~/src/zephyr/blinky$ 

Ok, so we specify that we want to run on core0:

dzu@krikkit:~/src/zephyr/blinky$ west build -b frdm_mcxn947/mcxn947/cpu0
-- west build: generating a build system
Loading Zephyr default modules (Zephyr base).
-- Application: /home/dzu/src/zephyr/blinky
-- CMake version: 3.28.3
-- Found Python3: /usr/local/bin/python3 (found suitable version "3.11.8", minimum required is "3.8") found components: Interpreter 
-- Cache files will be written to: /home/dzu/.cache/zephyr
-- Zephyr version: 3.6.99 (/opt/src/git/zephyrproject/zephyr)
-- Found west (found suitable version "1.1.0", minimum required is "0.14.0")
-- Board: frdm_mcxn947, qualifiers: mcxn947/cpu0
-- Found host-tools: zephyr 0.16.5 (/opt/zephyr-sdk-0.16.5-1)
-- Found toolchain: zephyr 0.16.5 (/opt/zephyr-sdk-0.16.5-1)
-- Found Dtc: /opt/zephyr-sdk-0.16.5-1/sysroots/x86_64-pokysdk-linux/usr/bin/dtc (found suitable version "1.6.0", minimum required is "1.4.6") 
-- Found BOARD.dts: /opt/src/git/zephyrproject/zephyr/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0.dts
-- Generated zephyr.dts: /home/dzu/src/zephyr/blinky/build/frdm_mcxn947/mcxn947/cpu0/zephyr/zephyr.dts
-- Generated devicetree_generated.h: /home/dzu/src/zephyr/blinky/build/frdm_mcxn947/mcxn947/cpu0/zephyr/include/generated/devicetree_generated.h
-- Including generated dts.cmake file: /home/dzu/src/zephyr/blinky/build/frdm_mcxn947/mcxn947/cpu0/zephyr/dts.cmake
Parsing /opt/src/git/zephyrproject/zephyr/Kconfig
Loaded configuration '/opt/src/git/zephyrproject/zephyr/boards/nxp/frdm_mcxn947/frdm_mcxn947_mcxn947_cpu0_defconfig'
Merged configuration '/home/dzu/src/zephyr/blinky/prj.conf'
Configuration saved to '/home/dzu/src/zephyr/blinky/build/frdm_mcxn947/mcxn947/cpu0/zephyr/.config'
Kconfig header saved to '/home/dzu/src/zephyr/blinky/build/frdm_mcxn947/mcxn947/cpu0/zephyr/include/generated/autoconf.h'
-- Found GnuLd: /opt/zephyr-sdk-0.16.5-1/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd (found version "2.38") 
-- The C compiler identification is GNU 12.2.0
-- The CXX compiler identification is GNU 12.2.0
-- The ASM compiler identification is GNU
-- Found assembler: /opt/zephyr-sdk-0.16.5-1/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc
Load components for MCXN947_cm33_core0:
driver_common component is included.
driver_reset component is included.
device_CMSIS component is included.
CMSIS_Include_core_cm component is included.
device_system component is included.
driver_ostimer component is included.
driver_lpflexcomm component is included.
driver_lpuart component is included.
driver_mcx_spc component is included.
driver_cache_cache64 component is included.
driver_port component is included.
-- Using ccache: /usr/bin/ccache
-- Configuring done (6.1s)
-- Generating done (0.1s)
-- Build files have been written to: /home/dzu/src/zephyr/blinky/build/frdm_mcxn947/mcxn947/cpu0
-- west build: building application
[1/135] Preparing syscall dependency handling

[3/135] Generating include/generated/version.h
-- Zephyr version: 3.6.99 (/opt/src/git/zephyrproject/zephyr), build: v3.6.0-2573-g58de48741aff
[135/135] Linking C executable zephyr/zephyr.elf
Memory region         Used Size  Region Size  %age Used
           FLASH:       22918 B         2 MB      1.09%
             RAM:        4136 B       320 KB      1.26%
           SRAM1:          0 GB        96 KB      0.00%
        IDT_LIST:          0 GB        32 KB      0.00%
Generating files from /home/dzu/src/zephyr/blinky/build/frdm_mcxn947/mcxn947/cpu0/zephyr/zephyr.elf for board: frdm_mcxn947
dzu@krikkit:~/src/zephyr/blinky$

Excellent, the app compiled and we are ready to test it on our target.

Flashing blinky

As compilation was easy, I do not expect problems flashing the binary:

dzu@krikkit:~/src/zephyr/blinky$ west flash -d build/frdm_mcxn947/mcxn947/cpu0/
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner linkserver
FATAL ERROR: required program LinkServer not found; install it or add its location to PATH
dzu@krikkit:~/src/zephyr/blinky$ west flash -r openocd -d build/frdm_mcxn947/mcxn947/cpu0/
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner openocd
FATAL ERROR: board frdm_mcxn947/mcxn947/cpu0 does not support runner openocd
To fix, configure this runner in /opt/src/git/zephyrproject/zephyr/boards/nxp/frdm_mcxn947/board.cmake and rebuild.
dzu@krikkit:~/src/zephyr/blinky$ west flash -r pyocd -d build/frdm_mcxn947/mcxn947/cpu0/
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner pyocd
FATAL ERROR: board frdm_mcxn947/mcxn947/cpu0 does not support runner pyocd
To fix, configure this runner in /opt/src/git/zephyrproject/zephyr/boards/nxp/frdm_mcxn947/board.cmake and rebuild.
dzu@krikkit:~/src/zephyr/blinky$

Ouch. No support for openocd or pyocd, only LinkServer is supported. This means that we have to install the LinkServer package or MCUXpressoIDE which also contains this package. Maybe I want to look at other functionality in MCUXpressoIDE, I will install this.

Installing MCUXpressoIDE

Just download the latest version of MCUXpressoIDE from NXP. It is not a Debian package itself, but a self extracting installer required to be run with "sudo sh". Once you have done this, you will then have these packages installed:

dzu@krikkit:~/src/zephyr/blinky$ dpkg -l mcuxpressoide jlink linkserver | tee
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version      Architecture Description
+++-==============-============-============-=====================================================================================================
ii  jlink          7.963        amd64        SEGGER J-Link tools
ii  linkserver     1.5          amd64        LinkServer installer
ii  mcuxpressoide  11.9.1       amd64        MCUXpresso IDE is an Eclipse-based IDE for development of software for NXP LPC and Kinetis platforms.
dzu@krikkit:~/src/zephyr/blinky$ 

Setting up LinkServer

In order for LinkServer to be picked up, we need to add it to our PATH. I do this in my profiles, but for this post, I use my add_path bash function:

dzu@krikkit:~/src/zephyr/blinky$ type add_path
add_path is a function
add_path () 
{ 
    echo $PATH | tr ":" "\n" | grep -q $1 || PATH=$1:$PATH
}
dzu@krikkit:~/src/zephyr/blinky$ add_path /usr/local/LinkServer
dzu@krikkit:~/src/zephyr/blinky$ 

So let's retry

dzu@krikkit:~/src/zephyr/blinky$ west flash -d build/frdm_mcxn947/mcxn947/cpu0/
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner linkserver
-- runners.linkserver: LinkServer: /usr/local/LinkServer/LinkServer, version v1.5.30
CRITICAL: Critical error
ERRMSG: Exception: Device query can have at most 2 parts (3 found): ['MCXN947', 'FRDM-MCXN947', 'cm33_core0']
FATAL ERROR: command exited with status 255: /usr/local/LinkServer/LinkServer flash --probe '#1' -o /device/memory/1/flash-driver=MCXN9xx_S.cfx -o /device/memory/1/location=0x10000000 -o '/device/memory/-={"location":"0x30000000",                               "size":"0x00060000","type":"RAM"}' -o '/device/memory/-={"location":"0x30060000",                               "size":"0x00008000","type":"RAM"}' -o '/device/memory/-={"location":"0x50000000",                               "size":"0x00140000","type":"RAM"}' MCXN947:FRDM-MCXN947:cm33_core0 load --addr 268435456 build/frdm_mcxn947/mcxn947/cpu0/zephyr/zephyr.bin
dzu@krikkit:~/src/zephyr/blinky$ 

Urgs. Ok, still some problems left in the port to this board. LinkServer complains about the triple "MCXN947:FRDM-MCXN947:cm33_core0" generated by west for the flash command. Let's try to correct this argument manually to "MCXN947:FRDM-MCXN947" and call LinkServer manually without the help of west:

dzu@krikkit:~/src/zephyr/blinky$ /usr/local/LinkServer/LinkServer flash --probe '#1' -o /device/memory/1/flash-driver=MCXN9xx_S.cfx -o /device/memory/1/location=0x10000000 -o '/device/memory/-={"location":"0x30000000",                               "size":"0x00060000","type":"RAM"}' -o '/device/memory/-={"location":"0x30060000",                               "size":"0x00008000","type":"RAM"}' -o '/device/memory/-={"location":"0x50000000",                               "size":"0x00140000","type":"RAM"}' MCXN947:FRDM-MCXN947 load --addr 268435456 build/frdm_mcxn947/mcxn947/cpu0/zephyr/zephyr.bin
INFO: Exact match for MCXN947:FRDM-MCXN947 found
INFO: Selected device MCXN947:FRDM-MCXN947
INFO: Getting available probes
INFO: Selecting probe by index
INFO: Selected probe #1 XCNMKAX0KS13T (MCU-LINK FRDM-MCXN947 (r0E7) CMSIS-DAP V3.128)
INFO: MCU-Link firmware update CHECK: local firmware [3.140] can be programmed on the selected probe ([XCNMKAX0KS13T] [MCU-LINK FRDM-MCXN947 (r0E7) CMSIS-DAP V3.128])
Firmware update CHECK: - the update can be performed using `AUTO` mode
Ns: MCUXpresso IDE RedlinkMulti Driver v11.9 (Apr  5 2024 19:50:07 - crt_emu_cm_redlink build 47)
Pc: (  0) Reading remote configuration
Wc(03). No cache support.
Nc: Found chip XML file in /tmp/tmpgoju9qng/MCXN947.xml
Pc: (  5) Remote configuration complete
Nc: Reconnected to existing LinkServer process.
Nc: Probe Firmware: MCU-LINK FRDM-MCXN947 (r0E7) CMSIS-DAP V3.128 (NXP Semiconductors)
Nc: Serial Number:  XCNMKAX0KS13T
Nc: VID:PID:  1FC9:0143
Nc: USB Path: 0005:0060:00
Nc: Using memory from core 0 after searching for a good core
Pc: ( 30) Emulator Connected
Nc: processor is in secure mode
Pc: ( 40) Debug Halt
Pc: ( 50) CPU ID
Nc: debug interface type      = CoreSight DP (DAP DP ID 6BA02477) over SWD TAP 0
Nc: processor type            = Cortex-M33 (CPU ID 00000D21) on DAP AP 0
Nc: number of h/w breakpoints = 8
Nc: number of flash patches   = 0
Nc: number of h/w watchpoints = 4
Nc: Probe(0): Connected&Reset. DpID: 6BA02477. CpuID: 00000D21. Info: <None>
Nc: Debug protocol: SWD. RTCK: Disabled. Vector catch: Disabled.
Ns: Content of CoreSight Debug ROM(s):
Nc: RBASE E00FE000: CID B105100D PID 0000095000 ROM (type 0x1)
Nc: ROM 1 E00FF000: CID B105100D PID 04000BB4C9 ROM (type 0x1)
Nc: ROM 2 E000E000: CID B105900D PID 04000BBD21 CSt ARM ARMv8-M type 0x0 Misc - Undefined
Nc: ROM 2 E0001000: CID B105900D PID 04000BBD21 CSt ARM DWTv2 type 0x0 Misc - Undefined
Nc: ROM 2 E0002000: CID B105900D PID 04000BBD21 CSt ARM FPBv2 type 0x0 Misc - Undefined
Nc: ROM 2 E0000000: CID B105900D PID 04000BBD21 CSt ARM ITMv2 type 0x43 Trace Source - Bus
Nc: ROM 2 E0041000: CID B105900D PID 04002BBD21 CSt ARM ETMv4.0 type 0x13 Trace Source - Core
Nc: ROM 2 E0042000: CID B105900D PID 04000BBD21 CSt ARM CTIv2 type 0x14 Debug Control - Trigger, e.g. ECT
Nc: ROM 1 E0040000: CID B105900D PID 04000BBD21 CSt type 0x11 Trace Sink - TPIU
Nc: ROM 1 E0044000: CID B105900D PID 04003BB908 CSt CSTF type 0x12 Trace Link - Trace funnel/router
Nc: ROM 1 E0045000: CID B105900D PID 04001BB961 CSt type 0x21 Trace Sink - ETB
Nc: NXP: MCXN947
Nc: DAP stride is 1024 bytes (256 words)
Nc: Inspected v.2 On-chip Flash Memory MCXN9xx.cfx
Nc: Image 'MCXNxxx Apr  5 2024 18:23:07'
Nc: Opening flash driver MCXN9xx.cfx
Nc: VECTRESET requested, but not supported on ARMv8-M CPUs. Using SOFTRESET instead.
Nc: Using SOFT reset to run the flash driver
Nc: Flash variant 'MCXNxxx (2048KB)' detected (2MB = 256*8K at 0x0)
Nc: Closing flash driver MCXN9xx.cfx
Nc: Inspected v.2 On-chip Flash Memory MCXN9xx_S.cfx
Nc: Image 'MCXNxxx_S (Secure) Apr  5 2024 18:23:16'
Nc: Opening flash driver MCXN9xx_S.cfx
Nc: VECTRESET requested, but not supported on ARMv8-M CPUs. Using SOFTRESET instead.
Nc: Using SOFT reset to run the flash driver
Nc: Flash variant 'MCXNxxx (2048KB) (Secure)' detected (2MB = 256*8K at 0x10000000)
Nc: Closing flash driver MCXN9xx_S.cfx
Nc: Inspected v.2 On-chip Flash Memory MCXN9xx.cfx
Nc: Image 'MCXNxxx Apr  5 2024 18:23:07'
Nc: Opening flash driver MCXN9xx.cfx
Nc: VECTRESET requested, but not supported on ARMv8-M CPUs. Using SOFTRESET instead.
Nc: Using SOFT reset to run the flash driver
Nc: Flash variant 'MCXNxxx (2048KB)' detected (2MB = 256*8K at 0x0)
Nc: Closing flash driver MCXN9xx.cfx
Nc: Inspected v.2 On-chip Flash Memory MCXN9xx_S.cfx
Nc: Image 'MCXNxxx_S (Secure) Apr  5 2024 18:23:16'
Nc: Opening flash driver MCXN9xx_S.cfx
Nc: VECTRESET requested, but not supported on ARMv8-M CPUs. Using SOFTRESET instead.
Nc: Using SOFT reset to run the flash driver
Nc: Flash variant 'MCXNxxx (2048KB) (Secure)' detected (2MB = 256*8K at 0x10000000)
Nc: Closing flash driver MCXN9xx_S.cfx
Nc: Inspected v.2 External Flash Device on SPI using SFDP JEDEC ID MCXN9xx_SFDP_FlexSPI.cfx
Nc: Image 'MCXN9xx_SFDP_FlexSPI Apr  5 2024 18:10:20'
Nc: Opening flash driver MCXN9xx_SFDP_FlexSPI.cfx
Nc: VECTRESET requested, but not supported on ARMv8-M CPUs. Using SOFTRESET instead.
Nc: Using SOFT reset to run the flash driver
Nc: Flash variant 'JEDEC_FlexSPI_Device' detected (8MB = 128*64K at 0x80000000)
Nc: Closing flash driver MCXN9xx_SFDP_FlexSPI.cfx
Nc: Inspected v.2 External Flash Device on SPI using SFDP JEDEC ID MCXN9xx_SFDP_FlexSPI_S.cfx
Nc: Image 'MCXN9xx_SFDP_FlexSPI (Secure) Apr  5 2024 18:10:10'
Nc: Opening flash driver MCXN9xx_SFDP_FlexSPI_S.cfx
Nc: VECTRESET requested, but not supported on ARMv8-M CPUs. Using SOFTRESET instead.
Nc: Using SOFT reset to run the flash driver
Nc: Flash variant 'JEDEC_FlexSPI_Device' detected (8MB = 128*64K at 0x90000000)
Nc: Closing flash driver MCXN9xx_SFDP_FlexSPI_S.cfx
Pc: ( 65) Chip Setup Complete
Pc: ( 70) License Check Complete
Nt: Loading 'zephyr.bin' Binary 0x10000000 len 0x5986
Nc: Opening flash driver MCXN9xx_S.cfx
Nc: VECTRESET requested, but not supported on ARMv8-M CPUs. Using SOFTRESET instead.
Nc: Using SOFT reset to run the flash driver
Nc: Flash variant 'MCXNxxx (2048KB) (Secure)' detected (2MB = 256*8K at 0x10000000)
Pb: 1 of 1 (  0) Writing sectors 0-2 at 0x10000000 with 22920 bytes
Ps: (  0) at 10000000: 0 bytes - 0/22920
Wc: failed read ChecksumSectors message readyness - rc Em(12). Target rejected debug access at location 0x04004860

Wc: failed to send op EraseSector message - rc Em(12). Target rejected debug access at location 0x04004850

Nc: Closing flash driver MCXN9xx_S.cfx
Ec: Flash driver "Terminate" timeout (500 ms)  PC: 000008F8
Nc: There was a problem after a flash driver operation timed out, so we are going to compare the flash driver code with the memory where it was loaded. 
Nc: Note that, after driver initialization, some difference is normal in 'generic' drivers.
Nc:
Nc: Driver from AXF file:
Nc: 04000378: 20202028 29424b20 65532820 65727563    (    KB) (Secure
Nc: 04000388: 00000029 00000000 00000000 00000000    )...............
Nc: 04000398: 00000000 00000000 00000000 00000000    ................
Nc: 040003A8: 00000000 00000000 00000000 00000000    ................
Nc: 040003B8: 00000000 00000000 00000000 00000000    ................
Nc: 040003C8: 00000000 00000000 00000000 00000000    ................
Nc: 040003D8: 00000000 00000000                      ........        
Nc: Driver code in memory:
Nc: 04000378: 34303228 29424b38 65532820 65727563    (2048KB) (Secure
Nc: 04000388: 00000029 00000000 00200000 00000001    )......... .....
Nc: 04000398: 00000080 00002000 00000000 00000000    ..... ..........
Nc: 040003A8: 00000000 00000000 00000000 00000000    ................
Nc: 040003B8: 00000000 00000000 00000000 00000000    ................
Nc: 040003C8: 00000000 00000000 040003e0 04000370    ............p...
Nc: 040003D8: 00000000 00000000                      ........        
Pb: (100) Writing Flash ended with an error.
Ed:05: File 'zephyr.bin' load failure: Em(12). Target rejected debug access at location 0x04000850
Pc: (100) Target Operation Failed
CRITICAL: Critical error
ERRMSG: subprocess.CalledProcessError: Command '['/usr/local/LinkServer_1.5.30/binaries/crt_emu_cm_redlink', '--redlink-port', '11111', '--flash-dir', '/usr/local/LinkServer_1.5.30/binaries/Flash', '-x', '/tmp/tmpgoju9qng', '-pMCXN947', '--vendor', 'NXP', '-g', '--cache', 'dis', '--probeserial', 'XCNMKAX0KS13T', '--coreindex', '0', '--romstall', '0x50000040', '--romstalldelay', '600', '--flash-load-exec', '/home/dzu/src/zephyr/blinky/build/frdm_mcxn947/mcxn947/cpu0/zephyr/zephyr.bin', '--base', '0x10000000']' returned non-zero exit status 1.
dzu@krikkit:~/src/zephyr/blinky$ 

Better, but still no luck. It seems the device does not accept our request to program the secure storage.

At this point I am stuck and I headed over to Zephyrs Discord server and asked the question in the "nxp" channel.

Still Some Rough Edges

Only a few hours later, an NXP employee told me that brand new boards have shown this behaviour, but there is a known workaround:

  1. Unplug the board
  2. Hold the SW3 "ISP" button for the next steps
  3. Plug the board back in. Holding SW3 will prevent any app in the flash from booting
  4. Run west flash
  5. Release SW3
  6. Recycle power to the board and the new app should execute

And indeed this helped also in my case, so finally I have blinky working on the board!

Although the workaround looks complicated, it turns out that I need to follow it only once. After the new Zephyr app has been flashed successfully, LinkServer can flash other samples without going through these steps again.

Also the problem with the wrong LinkServer invocation is known and a pull request is pending to fix this for good. Using the fix locally allows me to work in a regular way with this board.

Trying A Second UART

Here is a simple test of the UART available on the J1 Arduino header on the board. Connecting it to an FTDI serial to USB adapter looks like this on the hardware side:

Pin Function FTDI Pin
J1.2 FC2_UART_RXD-ARD_D0 TX
J1.4 FC2_UART_TXD-ARD_D1 RX
J2.14 GND GND

On the Zephyr side, it is enough to create an overlay named frdm_mcxn947_mcxn947_cpu0.overlay in the app diectory:

/ {
        chosen {
                zephyr,console = &flexcomm2_lpuart2;
                zephyr,shell-uart = &flexcomm2_lpuart2;
        };
};

Flashing the shell_module example application with this overlay indeed will expose the console and shell interaction on the FTDI UART connected to the board. Very nice!

Summary

It seems NXP has done their homework for Zephyr on the new MCX-N platform. There are still some rough edges, but as Zephyr support for MCX-N has not even been announced officially, it is cool to already be able to test Zephyr on the new eval boards available now.

Let's see how the support of the platform evolves over time.

Comments

Comments powered by Disqus