Skip to content

Commit 19315f5

Browse files
DerekSnellkartben
authored andcommitted
boards: nxp: frdm_mcxn947_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 <[email protected]>
1 parent 7c77d0e commit 19315f5

File tree

3 files changed

+148
-44
lines changed

3 files changed

+148
-44
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/frdmmcxn947")
14+
zephyr_library_sources(${BOARD_DIR}/xip/mcxn_flexspi_nor_config.c)
15+
zephyr_library_include_directories(${BOARD_DIR}/xip)
16+
endif()

boards/nxp/frdm_mcxn947/doc/index.rst

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

209-
Flashing to QSPI
210-
================
211-
212-
Here is an example for the :zephyr:code-sample:`hello_world` application.
213-
214-
.. zephyr-app-commands::
215-
:app: zephyr/samples/hello_world
216-
:board: frdm_mcxn947/mcxn947/cpu0/qspi
217-
:gen-args: -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"bootloader/mcuboot/root-rsa-2048.pem\" -DCONFIG_BOOTLOADER_MCUBOOT=y
218-
:goals: flash
219-
220-
221-
In order to load Zephyr application from QSPI you should program a bootloader like
222-
MCUboot bootloader to internal flash. Here are the steps.
223-
224-
.. zephyr-app-commands::
225-
:app: bootloader/mcuboot/boot/zephyr
226-
:board: frdm_mcxn947/mcxn947/cpu0/qspi
227-
:goals: flash
228-
229-
Open a serial terminal, reset the board (press the RESET button), and you should
230-
see the following message in the terminal:
231-
232-
.. code-block:: console
233-
234-
*** Booting MCUboot v2.1.0-rc1-2-g9f034729d99a ***
235-
*** Using Zephyr OS build v3.6.0-4046-gf279a03af8ab ***
236-
I: Starting bootloader
237-
I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
238-
I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
239-
I: Boot source: none
240-
I: Image index: 0, Swap type: none
241-
I: Bootloader chainload address offset: 0x0
242-
I: Jumping to the first image slot
243-
*** Booting Zephyr OS build v3.6.0-4046-gf279a03af8ab ***
244-
Hello World! frdm_mcxn947/mcxn947/cpu0/qspi
245-
246209
Debugging
247210
=========
248211

@@ -269,6 +232,122 @@ then a debugger can be attached.
269232
As a reference please see (`AN13264`_, section 4.2.3 for more information).
270233
The reference is for the RT1170 but similar technique can be also used here.
271234

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

@@ -301,3 +380,15 @@ Troubleshooting
301380

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

boards/nxp/frdm_mcxn947/frdm_mcxn947_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 "frdm_mcxn947_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)