Skip to content

Commit 3bf8484

Browse files
committed
boards: st: nucleo_h7s3l8: Add ext_flash_app variant
Add ext_flash_app variant to nucleo_h7s3l8 to allow building applications running on ext flash. Based on Erwan Gouriou's work on stm32h7s78_dk in PR zephyrproject-rtos#97992 (which is based on A.Jarmouni's work on stm32h750_dk in PR 97037). Signed-off-by: Thomas Decker <[email protected]>
1 parent eb71640 commit 3bf8484

9 files changed

+464
-246
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Copyright (c) 2024-2025 STMicroelectronics
2+
# Copyright (c) 2025 JB-Lighting Lichtanlagentechnik
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
if BOARD_NUCLEO_H7S3L8_STM32H7S3XX_EXT_FLASH_APP
6+
7+
choice BOOTLOADER
8+
default BOOTLOADER_MCUBOOT
9+
endchoice
10+
11+
choice BOOT_SIGNATURE_TYPE
12+
default BOOT_SIGNATURE_TYPE_NONE
13+
endchoice
14+
15+
choice MCUBOOT_MODE
16+
default MCUBOOT_MODE_SWAP_USING_OFFSET
17+
endchoice
18+
19+
endif # BOARD_NUCLEO_H7S3L8_STM32H7S3XX_EXT_FLASH_APP

boards/st/nucleo_h7s3l8/board.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# keep first
44
board_runner_args(stm32cubeprogrammer "--port=swd" "--reset-mode=hw")
5-
if(CONFIG_XIP AND (CONFIG_STM32_MEMMAP OR CONFIG_BOOTLOADER_MCUBOOT))
5+
if(CONFIG_STM32_MEMMAP OR CONFIG_BOOTLOADER_MCUBOOT)
66
board_runner_args(stm32cubeprogrammer "--extload=MX25UW25645G_NUCLEO-H7S3L8.stldr")
77
endif()
88
board_runner_args(openocd --target-handle=_CHIPNAME.cpu0)

boards/st/nucleo_h7s3l8/board.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ board:
44
vendor: st
55
socs:
66
- name: stm32h7s3xx
7+
variants:
8+
- name: ext_flash_app

boards/st/nucleo_h7s3l8/doc/index.rst

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ the ``--runner`` (or ``-r``) option:
213213
.. code-block:: console
214214
215215
$ west flash --runner openocd
216+
$ west flash --runner jlink
216217
217218
Flashing an application to Nucleo H7S3L8
218219
----------------------------------------
@@ -255,7 +256,7 @@ Blinky example can also be used:
255256
:goals: build flash
256257

257258
Debugging
258-
=========
259+
---------
259260

260261
You can debug an application in the usual way. Here is an example for the
261262
:zephyr:code-sample:`hello_world` application.
@@ -266,6 +267,112 @@ You can debug an application in the usual way. Here is an example for the
266267
:maybe-skip-config:
267268
:goals: debug
268269

270+
Application in External Flash
271+
=============================
272+
273+
Because of the limited amount of SoC Flash (64KB), you may want to store the application
274+
in external OSPI Flash instead, and run it from there. In that case, the MCUboot bootloader
275+
is needed to chainload the application. A dedicate board variant, ``ext_flash_app``, was created
276+
for this usecase.
277+
278+
:ref:`sysbuild` makes it possible to build and flash all necessary images needed to run a user application
279+
from external Flash.
280+
281+
The following example shows how to build :zephyr:code-sample:`hello_world` with Sysbuild enabled:
282+
283+
.. zephyr-app-commands::
284+
:tool: west
285+
:zephyr-app: samples/hello_world
286+
:board: nucleo_h7s3l8/stm32h7s3xx/ext_flash_app
287+
:goals: build
288+
:west-args: --sysbuild
289+
290+
By default, Sysbuild creates MCUboot and user application images.
291+
292+
Build directory structure created by Sysbuild is different from traditional
293+
Zephyr build. Output is structured by the domain subdirectories:
294+
295+
.. code-block::
296+
297+
build/
298+
├── hello_world
299+
| └── zephyr
300+
│ ├── zephyr.elf
301+
│ ├── zephyr.hex
302+
│ ├── zephyr.bin
303+
│ ├── zephyr.signed.bin
304+
│ └── zephyr.signed.hex
305+
├── mcuboot
306+
│ └── zephyr
307+
│ ├── zephyr.elf
308+
│ ├── zephyr.hex
309+
│ └── zephyr.bin
310+
└── domains.yaml
311+
312+
.. note::
313+
314+
With ``--sysbuild`` option, MCUboot will be re-built every time the pristine build is used,
315+
but only needs to be flashed once if none of the MCUboot configs are changed.
316+
317+
For more information about the system build please read the :ref:`sysbuild` documentation.
318+
319+
Both MCUboot and user application images can be flashed by running:
320+
321+
.. code-block:: console
322+
323+
$ west flash
324+
325+
You should see the following message in the serial host program:
326+
327+
.. code-block:: console
328+
329+
*** Booting MCUboot v2.2.0-224-g0a52195c8181 ***
330+
*** Using Zephyr OS build v4.3.0-937-ge0490cf53e03 ***
331+
I: Starting bootloader
332+
I: Image index: 0, Swap type: none
333+
I: Image index: 0, Swap type: none
334+
I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
335+
I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
336+
I: Boot source: none
337+
I: Image index: 0, Swap type: none
338+
I: Image index: 0, Swap type: none
339+
I: Image index: 0, Swap type: none
340+
I: Image index: 0, Swap type: none
341+
I: Bootloader chainload address offset: 0x0
342+
I: Image version: v0.0.0
343+
I: Jumping to the first image slot
344+
*** Booting Zephyr OS build v4.3.0-937-ge0490cf53e03 ***
345+
Hello World! nucleo_h7s3l8/stm32h7s3xx/ext_flash_app
346+
347+
To only flash the user application in the subsequent builds, Use:
348+
349+
.. code-block:: console
350+
351+
$ west flash --domain hello_world
352+
353+
With the default configuration, the board uses MCUboot's Swap-using-offset mode.
354+
To get more information about the different MCUboot operating modes and how to
355+
perform application upgrade, refer to `MCUboot design`_.
356+
To learn more about how to secure the application images stored in external Flash,
357+
refer to `MCUboot Encryption`_.
358+
359+
Debugging
360+
---------
361+
362+
You can debug the application in external flash using ``west`` and ``GDB``.
363+
364+
After flashing MCUboot and the app, execute the following command:
365+
366+
.. code-block:: console
367+
368+
$ west debugserver
369+
370+
Then, open another terminal (don't forget to activate Zephyr's environment) and execute:
371+
372+
.. code-block:: console
373+
374+
$ west attach
375+
269376
.. _Nucleo H7S3L8 website:
270377
https://www.st.com/en/evaluation-tools/nucleo-h7s3l8.html
271378

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
/*
2+
* Copyright (c) 2024 STMicroelectronics
3+
* Copyright (c) 2025 JB-Lighting Lichtanlagentechnik
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
/dts-v1/;
9+
#include <st/h7rs/stm32h7s3X8.dtsi>
10+
#include <st/h7/stm32h7s3l8hx-pinctrl.dtsi>
11+
#include "arduino_r3_connector.dtsi"
12+
#include <zephyr/dt-bindings/input/input-event-codes.h>
13+
14+
/ {
15+
chosen {
16+
zephyr,console = &usart3;
17+
zephyr,shell-uart = &usart3;
18+
zephyr,dtcm = &dtcm;
19+
zephyr,sram = &sram0;
20+
zephyr,canbus = &fdcan1;
21+
};
22+
23+
leds: leds {
24+
compatible = "gpio-leds";
25+
26+
green_led: led_1 {
27+
gpios = <&gpiod 10 GPIO_ACTIVE_HIGH>;
28+
label = "User LD1";
29+
};
30+
31+
yellow_led: led_2 {
32+
gpios = <&gpiod 13 GPIO_ACTIVE_HIGH>;
33+
label = "User LD2";
34+
};
35+
36+
red_led: led_3 {
37+
gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>;
38+
label = "User LD3";
39+
};
40+
};
41+
42+
gpio_keys {
43+
compatible = "gpio-keys";
44+
45+
user_button: button_0 {
46+
label = "User";
47+
gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>;
48+
zephyr,code = <INPUT_KEY_0>;
49+
};
50+
};
51+
52+
aliases {
53+
led0 = &green_led;
54+
led1 = &yellow_led;
55+
led2 = &red_led;
56+
sw0 = &user_button;
57+
watchdog0 = &iwdg;
58+
spi-flash0 = &mx25uw25645;
59+
};
60+
61+
ext_memory: memory@70000000 {
62+
compatible = "zephyr,memory-region";
63+
reg = <0x70000000 DT_SIZE_M(32)>;
64+
zephyr,memory-region = "EXTMEM";
65+
zephyr,memory-attr = <DT_MEM_ARM(ATTR_MPU_FLASH)>;
66+
};
67+
};
68+
69+
&clk_hse {
70+
clock-frequency = <DT_FREQ_M(24)>;
71+
status = "okay";
72+
};
73+
74+
&clk_lse {
75+
status = "okay";
76+
};
77+
78+
&pll {
79+
div-m = <12>;
80+
mul-n = <200>;
81+
div-p = <2>;
82+
div-q = <2>;
83+
div-r = <2>;
84+
div-s = <2>;
85+
div-t = <2>;
86+
clocks = <&clk_hse>;
87+
status = "okay";
88+
};
89+
90+
/* PLL2 for clocking the xspi peripheral */
91+
&pll2 {
92+
div-m = <12>;
93+
mul-n = <200>;
94+
div-p = <2>;
95+
div-q = <2>;
96+
div-r = <2>;
97+
div-s = <2>;
98+
div-t = <2>;
99+
clocks = <&clk_hse>;
100+
status = "okay";
101+
};
102+
103+
&rcc {
104+
clocks = <&pll>;
105+
clock-frequency = <DT_FREQ_M(200)>;
106+
dcpre = <1>;
107+
hpre = <1>;
108+
ppre1 = <2>;
109+
ppre2 = <2>;
110+
ppre4 = <2>;
111+
ppre5 = <2>;
112+
};
113+
114+
&pwr {
115+
power-supply = "ldo";
116+
};
117+
118+
&usart1 {
119+
pinctrl-0 = <&usart1_tx_pb14 &usart1_rx_pa10>;
120+
pinctrl-names = "default";
121+
current-speed = <115200>;
122+
status = "okay";
123+
};
124+
125+
&usart3 {
126+
pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>;
127+
pinctrl-names = "default";
128+
current-speed = <115200>;
129+
status = "okay";
130+
};
131+
132+
&iwdg {
133+
status = "okay";
134+
};
135+
136+
&wwdg {
137+
status = "okay";
138+
};
139+
140+
&adc1 {
141+
pinctrl-0 = <&adc1_inp15_pa3>; /* Arduino A0 */
142+
pinctrl-names = "default";
143+
st,adc-clock-source = "SYNC";
144+
st,adc-prescaler = <4>;
145+
status = "okay";
146+
};
147+
148+
&spi1 {
149+
status = "okay";
150+
pinctrl-0 = <&spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pb5>;
151+
pinctrl-names = "default";
152+
cs-gpios = <&gpiod 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
153+
};
154+
155+
&i2c1 {
156+
pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>;
157+
pinctrl-names = "default";
158+
status = "okay";
159+
clock-frequency = <I2C_BITRATE_FAST>;
160+
};
161+
162+
&fdcan1 {
163+
pinctrl-0 = <&fdcan1_rx_pd0 &fdcan1_tx_pd1>;
164+
pinctrl-names = "default";
165+
clocks = <&rcc STM32_CLOCK(APB1_2, 8)>,
166+
<&rcc STM32_SRC_HSE FDCAN_SEL(0)>;
167+
status = "okay";
168+
};
169+
170+
&mac {
171+
pinctrl-0 = <&eth_rmii_rxd0_pg4
172+
&eth_rmii_rxd1_pg5
173+
&eth_rmii_ref_clk_pb6
174+
&eth_rmii_crs_dv_pa7
175+
&eth_rmii_tx_en_pg11
176+
&eth_rmii_txd0_pg13
177+
&eth_rmii_txd1_pg12>;
178+
pinctrl-names = "default";
179+
phy-connection-type = "rmii";
180+
phy-handle = <&eth_phy>;
181+
status = "okay";
182+
};
183+
184+
&mdio {
185+
pinctrl-0 = <&eth_mdio_pa2 &eth_mdc_pg6>;
186+
pinctrl-names = "default";
187+
status = "okay";
188+
189+
eth_phy: ethernet-phy@0 {
190+
compatible = "ethernet-phy";
191+
reg = <0x00>;
192+
};
193+
};
194+
195+
&xspi2 {
196+
pinctrl-0 = <&xspim_p2_clk_pn6 &xspim_p2_ncs1_pn1
197+
&xspim_p2_io0_pn2 &xspim_p2_io1_pn3
198+
&xspim_p2_io2_pn4 &xspim_p2_io3_pn5
199+
&xspim_p2_io4_pn8 &xspim_p2_io5_pn9
200+
&xspim_p2_io6_pn10 &xspim_p2_io7_pn11
201+
&xspim_p2_dqs0_pn0>;
202+
pinctrl-names = "default";
203+
204+
status = "okay";
205+
206+
ext_flash_ctrl: xspi-nor-flash@0 {
207+
compatible = "st,stm32-xspi-nor";
208+
reg = <0>;
209+
size = <DT_SIZE_M(256)>; /* 256Mbits */
210+
ospi-max-frequency = <DT_FREQ_M(50)>;
211+
spi-bus-width = <XSPI_OCTO_MODE>;
212+
data-rate = <XSPI_DTR_TRANSFER>;
213+
four-byte-opcodes;
214+
status = "okay";
215+
216+
#address-cells = <1>;
217+
#size-cells = <1>;
218+
ranges = <0x0 0x70000000 DT_SIZE_M(32)>;
219+
220+
ext_flash: mx25uw25645: xspi-nor-flash@0 {
221+
compatible = "soc-nv-flash";
222+
reg = <0x0 DT_SIZE_M(32)>;
223+
write-block-size = <1>;
224+
erase-block-size = <DT_SIZE_K(4)>;
225+
226+
partitions {
227+
compatible = "fixed-partitions";
228+
#address-cells = <1>;
229+
#size-cells = <1>;
230+
};
231+
};
232+
};
233+
};

0 commit comments

Comments
 (0)