Oberon RTK

Build and Load: STM32 (S/NS)

Building and loading programs with S/NS segregation on the STM32.

Overview

This document describes how to build, load, and run RTK-based programs with S/NS segregation for the Cortex-M33 STM32 series of MCUs for two scenarios:

  • simple loading, without debugger
  • with debugger

Tested with STM32U585 and STM32H573.

S/NS programs comprise two images, one for the Secure program and the NSC veneers, one for the Non-secure programs.

For programs without Secure/Non-secure segregation refer to Build and Load: STM32.

See also Practical Notes.

STM32 Configuration

We assume this MCU configuration:

  • TrustZone is enabled

  • the 2MB flash memory has been configured, via option bytes

    • block 1 of 1 MB is Secure (address alias: 0C000000H)
    • block 2 of 1 MB is Non-secure (address alias: 08100000H)

Project Set-up

  • Address ranges: see Build RTK-based Programs.

  • Directories:

    • S program in <project-dir>/sec
    • NS program in <project-dir>/nonsec
  • Commands as shown are run with cwd = <project-dir>.

  • For debugging, the additional tools must be installed and configured (see section Tools below).

Build and Load, no Debugging

Build the Secure Program

1. Insert Secure epilogues for each S-side module that is exposed to NS

> python -m sec-epilogue <M0>.mod <M1>.mod ...

Notes:

  • this only needs to be run when a module is changed
  • use --no-clear to omit the register clearing sequence

2. Build the S program.

3. Run gen-secure to create the NSC veneers binary, and the interface modules for the NS program:

> python -m gen-secure sec/<Sprogram>.map [options]

Notes:

  • options: see gen-secure
  • config file: in lieu of specifying the options a configuration file can be used – example:
[gen-secure]
nsc-addr = 00C0FE000H
ns-dir = nonsec/ns_
nsc-dir = sec
const-leaf = BASE
modules =
    S0

4. Make the ELF file for the S program

> python -m make-elf sec/<Sprogram>.bin:C000000 sec/NSC.bin:C0FE000

Build the Non-secure Program

5. Build the NS program

6. Make the ELF file for the NS program

> python -m make-elf nonsec/<NSprogram>.bin

Note: load address is read from the .map file

Load the Images

7. For loading, we have two options:

  • STM32CubeProgrammer GUI:

    • connect via ST-Link (right top green/yellow-ish button)
    • left hand side, tab "Memory & File editing"
    • two new tabs => open sec/<Sprogram>.elf and nonsec/<NSprogram>.elf
    • blue-ish Download button for each file
    • after downloading both files, press the board reset button to start the program
  • STM32_Programmer_CLI

    • run:
> STM32_Programmer_CLI.exe -c port=SWD -d nonsec/<NSprogram>.elf
> STM32_Programmer_CLI.exe -c port=SWD -d sec/<Sprogram>.elf -s

Build and Load for Debugging

Build the Secure Program

1. sec-epilogue: as above

2. Build: as above

3. gen-secure: as above

4. Run gen-rdb to create an .alst file for each module in the S program, plus _startup.alst for the startup sequence inserted by the linker at the end of the program; make-elf requires the .alst files to create symbols and DWARF debug data:

> python -m gen-rdb sec/<Sprogram>.map --rdb-dir sec/rdb --nsc-dir sec

5. Make the debug ELF file for the S program:

> python -m make-elf sec/<Sprogram>.bin:C000000 sec/NSC.bin:C0FE000 --rdb-dir sec/rdb --debug --sym-prefix S

Build the Non-secure Program

6. Build: as step 5 above in the non-debug scenario

7. Run gen-rdb to create an .alst file for each module in the NS program, plus _startup.alst:

> python -m gen-rdb nonsec/<NSprogram>.map --rdb-dir nonsec/rdb

8. Make the debug ELF file for the NS program:

> python -m make-elf nonsec/<NSprogram>.bin --rdb-dir nonsec/rdb --debug --sym-prefix NS

Load the Images

9. Load the two ELF files to the STM32:

  • Refer to Debugging:
    • GUI: Cortex-Debug inside VisualStudio Code
    • command line: OpenOCD and GDB

Tools

Examples (Repository)

  • <repo-root>/examples/v3.1/stm/u585i-iot/Secure5
  • <repo-root>/examples/v3.1/stm/h573i-dk/Secure5

Last updated: 17 April 2026