Skip to content

Commit c7e36f0

Browse files
DerekSnellkartben
authored andcommitted
boards: nxp: mcx_n9xx_evk_cpu0_qspi: boot directly from QSPI flash
Configures QSPI board variant to boot directly from external QSPI flash on the FlexSPI. Secondary bootloader is no longer required. Moves the MCUboot boot_partition to QSPI flash. Signed-off-by: Derek Snell <derek.snell@nxp.com>
1 parent 19315f5 commit c7e36f0

File tree

3 files changed

+148
-37
lines changed

3 files changed

+148
-37
lines changed
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
#
2-
# Copyright 2024 NXP
2+
# Copyright 2024-2025 NXP
33
#
44
# SPDX-License-Identifier: Apache-2.0
55
#
66

77
zephyr_library()
88
zephyr_library_sources(board.c)
9+
10+
if(CONFIG_FLEXSPI_CONFIG_BLOCK_OFFSET)
11+
# Include flash configuration block
12+
zephyr_compile_definitions(XIP_BOOT_HEADER_ENABLE=1)
13+
set(BOARD_DIR "${ZEPHYR_HAL_NXP_MODULE_DIR}/mcux/mcux-sdk-ng/boards/mcxn9xxevk")
14+
zephyr_library_sources(${BOARD_DIR}/xip/mcxn_flexspi_nor_config.c)
15+
zephyr_library_include_directories(${BOARD_DIR}/xip)
16+
endif()

boards/nxp/mcx_n9xx_evk/doc/index.rst

Lines changed: 128 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -207,36 +207,6 @@ Here is an example for the :zephyr:code-sample:`mbox_data` application.
207207
:goals: flash
208208
:west-args: --sysbuild
209209

210-
Flashing to QSPI
211-
================
212-
213-
In order to load Zephyr application from QSPI, program a bootloader like
214-
MCUboot bootloader to internal flash. Here are the steps for the
215-
:zephyr:code-sample:`hello_world` application.
216-
217-
.. zephyr-app-commands::
218-
:app: zephyr/samples/hello_world
219-
:board: mcx_n9xx_evk/mcxn947/cpu0/qspi
220-
:gen-args: --sysbuild -- -DSB_CONFIG_BOOTLOADER_MCUBOOT=y
221-
:goals: flash
222-
223-
Open a serial terminal, reset the board (press the RESET button), and you should
224-
see the following message in the terminal:
225-
226-
.. code-block:: console
227-
228-
*** Booting MCUboot vX.X.X ***
229-
*** Using Zephyr OS build vX.X.X ***
230-
I: Starting bootloader
231-
I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
232-
I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
233-
I: Boot source: none
234-
I: Image index: 0, Swap type: none
235-
I: Bootloader chainload address offset: 0x0
236-
I: Jumping to the first image slot
237-
*** Booting Zephyr OS build vX.X.X ***
238-
Hello World! mcx_n9xx_evk/mcxn947/cpu0/qspi
239-
240210
Debugging
241211
=========
242212

@@ -263,6 +233,122 @@ then a debugger can be attached.
263233
As a reference please see (`AN13264`_, section 4.2.3 for more information).
264234
The reference is for the RT1170 but similar technique can be also used here.
265235

236+
Using QSPI board variant
237+
========================
238+
The MCX-N9XX-EVK board includes an external QSPI flash. The MCXN947 can boot and
239+
XIP directly from this flash using the FlexSPI interface. The QSPI variant
240+
enables building applications and code to execute from the QSPI.
241+
242+
Programming the ROM bootloader for external QSPI
243+
------------------------------------------------
244+
By default, the MCXN947 bootloader in ROM will boot using internal flash. But
245+
the MCU can be programmed to boot from external memory on the FlexSPI interface.
246+
Before using the QSPI board variant, the board should be programmed to boot from
247+
QSPI using the steps below.
248+
249+
To configure the ROM bootloader, the Protected Flash Region (PFR) must be
250+
programmed. Programming the PFR is done using NXP's ROM bootloader tools.
251+
Some simple steps are provided in NXP's
252+
`MCUXpresso SDK example hello_world_qspi_xip readme`_. The binary to program
253+
with blhost is found at `bootfromflexspi.bin`_. A much more detailed explanation
254+
is available at this post `Running code from external memory with MCX N94x`_.
255+
The steps below program the MCX-N9XX-EVK board. Note that these steps interface
256+
to the ROM bootloader through the UART serial port, but USB is another option.
257+
258+
1. Disconnect any terminal from the UART serial port, since these steps use that
259+
serial port.
260+
#. Connect a micro USB cable to the host computer and J5 on the board, in the
261+
upper left corner. This powers the board, connects the debug probe, and
262+
connects the UART serial port used for the ``blhost`` command.
263+
#. Place the MCU in ISP mode. On the MCX-N9XX-EVK board, the ISP button
264+
can be used for this. Press and hold the ISP button SW3, on the bottom right
265+
corner of the board. Press and release the Reset button SW1 on the lower left
266+
corner of the board. The MCU has booted into ISP mode. Release the ISP
267+
button.
268+
#. Run the ``blhost`` command:
269+
270+
.. tabs::
271+
272+
.. group-tab:: Ubuntu
273+
274+
This step assumes the MCU serial port is connected to `/dev/ttyACM0`
275+
276+
.. code-block:: shell
277+
278+
blhost -t 2000 -p /dev/ttyACM0,115200 -j -- write-memory 0x01004000 bootfromflexspi.bin
279+
280+
.. group-tab:: Windows
281+
282+
Change `COMxx` to match the COM port number connected to the MCU serial port.
283+
284+
.. code-block:: shell
285+
286+
blhost -t 2000 -p COMxx -j -- write-memory 0x01004000 bootfromflexspi.bin
287+
288+
Successful programming should look something like this:
289+
290+
.. code-block:: console
291+
292+
$ blhost -t 2000 -p /dev/ttyACM0,115200 -j -- write-memory 0x01004000 bootfromflexspi.bin
293+
{
294+
"command": "write-memory",
295+
"response": [
296+
256
297+
],
298+
"status": {
299+
"description": "0 (0x0) Success.",
300+
"value": 0
301+
}
302+
}
303+
304+
5. Reset the board with SW1 to exit ISP mode. Now the MCU is ready to boot from
305+
QSPI.
306+
307+
The ROM bootloader can be configured to boot from internal flash again. Repeat
308+
the steps above to program the PFR, and program the file `bootfromflash.bin`_.
309+
310+
Build, flash, and debug with the QSPI variant
311+
---------------------------------------------
312+
313+
Once the PFR is programmed to boot from QSPI, the normal Zephyr steps to build,
314+
flash, and debug can be used with the QSPI board variant. Here are some examples.
315+
316+
Here is an example for the :zephyr:code-sample:`hello_world` application:
317+
318+
.. zephyr-app-commands::
319+
:app: zephyr/samples/hello_world
320+
:board: mcx_n9xx_evk//cpu0/qspi
321+
:goals: flash
322+
323+
MCUboot can also be used with the QSPI variant. By default, this places the
324+
MCUboot bootloader in the ``boot-partition`` in QSPI flash, with the application
325+
images. The ROM bootloader will boot first and load MCUboot in the QSPI, which
326+
will load the app. This example builds and loads the :zephyr:code-sample:`blinky`
327+
sample with MCUboot using Sysbuild:
328+
329+
.. zephyr-app-commands::
330+
:app: zephyr/samples/basic/blinky
331+
:board: mcx_n9xx_evk//cpu0/qspi
332+
:west-args: --sysbuild
333+
:gen-args: -DSB_CONFIG_BOOTLOADER_MCUBOOT=y
334+
:goals: flash
335+
336+
Open a serial terminal, reset the board with the SW1 button, and the console
337+
will print:
338+
339+
.. code-block:: console
340+
341+
*** Booting MCUboot vX.Y.Z ***
342+
*** Using Zephyr OS build vX.Y.Z ***
343+
I: Starting bootloader
344+
I: Image index: 0, Swap type: none
345+
I: Bootloader chainload address offset: 0x14000
346+
I: Image version: v0.0.0
347+
I: Jumping to the first image slot
348+
*** Booting Zephyr OS build vX.Y.Z ***
349+
LED state: OFF
350+
LED state: ON
351+
266352
Troubleshooting
267353
===============
268354

@@ -292,3 +378,15 @@ Troubleshooting
292378

293379
.. _AN13264:
294380
https://www.nxp.com/docs/en/application-note/AN13264.pdf
381+
382+
.. _MCUXpresso SDK example hello_world_qspi_xip readme:
383+
https://github.com/nxp-mcuxpresso/mcuxsdk-examples/blob/main/_boards/mcxn9xxevk/demo_apps/hello_world_qspi_xip/example_board_readme.md
384+
385+
.. _bootfromflash.bin:
386+
https://github.com/nxp-mcuxpresso/mcuxsdk-examples/blob/main/_boards/mcxn9xxevk/demo_apps/hello_world_qspi_xip/cm33_core0/bootfromflash.bin
387+
388+
.. _bootfromflexspi.bin:
389+
https://github.com/nxp-mcuxpresso/mcuxsdk-examples/blob/main/_boards/mcxn9xxevk/demo_apps/hello_world_qspi_xip/cm33_core0/bootfromflexspi.bin
390+
391+
.. _Running code from external memory with MCX N94x:
392+
https://community.nxp.com/t5/MCX-Microcontrollers-Knowledge/Running-code-from-external-memory-with-MCX-N94x/ta-p/1792204

boards/nxp/mcx_n9xx_evk/mcx_n9xx_evk_mcxn947_cpu0_qspi.dts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "mcx_n9xx_evk_mcxn947_cpu0.dtsi"
1010

11+
/delete-node/ &boot_partition;
1112
/delete-node/ &slot0_partition;
1213
/delete-node/ &slot1_partition;
1314
/delete-node/ &storage_partition;
@@ -28,17 +29,21 @@
2829
#address-cells = <1>;
2930
#size-cells = <1>;
3031

31-
slot0_partition: partition@0 {
32+
boot_partition: partition@0 {
33+
label = "mcuboot";
34+
reg = <0x00000000 DT_SIZE_K(80)>;
35+
};
36+
slot0_partition: partition@14000 {
3237
label = "image-0";
33-
reg = <0x00000000 DT_SIZE_M(3)>;
38+
reg = <0x00014000 DT_SIZE_M(3)>;
3439
};
35-
slot1_partition: partition@300000 {
40+
slot1_partition: partition@314000 {
3641
label = "image-1";
37-
reg = <0x00300000 DT_SIZE_M(3)>;
42+
reg = <0x00314000 DT_SIZE_M(3)>;
3843
};
39-
storage_partition: partition@600000 {
44+
storage_partition: partition@614000 {
4045
label = "storage";
41-
reg = <0x00600000 DT_SIZE_M(2)>;
46+
reg = <0x00614000 DT_SIZE_K(1968)>;
4247
};
4348
};
4449
};

0 commit comments

Comments
 (0)