Last edited 2 weeks ago

How to build and debug secure project on STM32MP25 co-processor in STM32CubeIDE

Applicable for STM32MP25x lines

This article is a guideline to support secure project on Arm®-Cortex®-M33 core contained in the STM32MP25. The STM32MP25 support is provided in the release v1.16.0 of STM32CubeIDE.

It relies onto the project TFM_Protected_Storage, from STM32CubeMP2 Package v1.0.0, which offers "secure with TF-M" Build Configuration. It can be used from a Windows or a Linux® workstation.

This article focus on how to build secure firmware - trusted firmware-m together with nonsecure firmware and debug them.

1. Prerequisites[edit source]

1.1. Hardware prerequisites[edit source]

  • STM32MP257F-EV1 Rev C,
  • Linux® console,
  • Ethernet (or Ethernet over USB) for connection of PC workstation to Linux® Arm®-Cortex®-A .

For more information, refer to Getting started/STM32MP2 boards/STM32MP257x-EV1/Let's start/Unpack the STM32MP257x-EV1 board.

1.2. Software prerequisites[edit source]

  • Install build environment and python dependencies for TF-M as described in How to configure TF-M prerequisites chapter.
  • Install python libraries needed by OP-TEE signature python script
 pip install pyelftools
 pip install pycryptodomex

2. Importing[edit source]

Following steps are needed

2.1. Import TFM_Protected_Storage STM32CubeIDE project[edit source]

TFM_Protected_Storage STM32CubeIDE project is imported from STM32CubeMP2 Package using menu:

File > OpenProjects from File Systems...
Then, set Import source using Directory... to the STM32CubeMP2 firmware selecting:


Note that TFM Protected Storage project is available from STM32Cube repository on local disk or from Projects/STM32MP257F-EV1/Applications/TFM/TFM_Protected_Storage .
Resulting project structure contains two projects:

  • TFM_Protected_Storage_CM33_NonSecure, HAL-based project addressing non-secure part of application,
  • TFM_Protected_Storage_CM33_trusted-firmware-m, pre-set STM32CubeIDE CMake project for TF-M, with link to sources: trusted-firmware-m pointing inside STM32CubeMP2 Package Middlewares/Third_Party/trusted-firmware-m.
TFM_Protected_Storage imported project

2.2. TFM_Protected_Storage_CM33_trusted-firmware-m - final setup[edit source]

The only missing element is the access to trusted-firmware-m project source files.

As depicted hereafter, trusted-firmware-m link inside STM32CubeIDE project point to a path that has to be populated:

trusted-firmware-m link to source files

To populate it please follow Install Sources chapter from How to configure TF-M article.
Now you can refresh STM32CubeIDE project and view sources.

trusted-firmware-m sources from STM32CubeIDE

CMake trusted-firmware-m project is imported with already embedded setting for:

  • STM32MP257F-EV1 board - CMake project usage setting
-DTFM_PLATFORM=stm/stm32mp257f_ev1 -DTFM_TOOLCHAIN_FILE=toolchain_GNUARM.cmake -DTFM_PROFILE=profile_medium -DCMAKE_BUILD_TYPE=debug -DNS=OFF
  • STM32CubeIDE debug information added to CMake project

3. Build[edit source]

Now it is possible to build TFM_Protected_Storage_CM33_trusted-firmware-m:

Warning white.png Warning
Process running STM32CubeIDE must define http and https proxy in order CMake command to successfully access network.

On Linux® workstation it is recommended to launch STM32CubeIDE from xterm with configured proxy environment.

Select TFM_Protected_Storage_CM33_NonSecure project. This project has only one build configuration CA35TDCID_m33_ns_tfm_s_sign.
Build can be done using standard Eclipse "Build icon", it will generate TFM_Protected_Storage_CM33_NonSecure_tfm_s_sign.bin, visible after a project refresh.


Note that a post-build command is used to generated the bin object from the two sub-project elf:

  • TFM_Protected_Storage_CM33_NonSecure_stripped.elf
  • Middlewares/Third_Party/trusted-firmware-m/config_default/bin/tfm_s.elf

4. Debugging[edit source]

4.1. Prerequisite to debug[edit source]

Target is to debug in "production mode".
STM32MP257F-EV1 must be up and running, and connected to the workstation via network & console.
SD-Card has been initialized with Starter Package version 24-06-26.
The Cortex-M33 Secure and non secure firmware image are encapsulated and signed. The resulting binary file "TFM_Protected_Storage_CM33_NonSecure_tfm_s_sign.bin" has to be loaded by OP-TEE. To check OP-TEE security capabilities of the board, execute following command, into Linux console:

cat /sys/class/remoteproc/remoteproc0/fw_format

that should return "TEE".

Before using production mode debug, proxy network must be adjusted, for that refer to How to set up proxy and P2P Ethernet connection with STM32CubeIDE.

Target Status on the bottom right must show a green light, refer to How_to_use_the_Target_Status_widget_in_STM32CubeIDE.


4.2. Loading .bin object[edit source]

The generated ".bin" object has to be downloaded to STM32MP257F-EV1 and loaded via remoteproc framework.
This is done thanks to a "Run Configuration" set in Production Mode.

4.2.1. Run configuration setup[edit source]

Select TFM_Protected_Storage_CM33_NonSecure project and right click on Run As > Run Configurations...
Double click onSTM32 C/C++ Application to create a configuration.

  • In "main" tab:
  • "Workspace..." button allows to select ".bin" file

  • In "Debugger" tab:
  • "Load mode" should be "thru Linux core" (Production mode)
  • and for limitation reason, "GDB Connection Settings" should be "Connect to remote GDB server".

It is recommended to enrich the default "Run Configuration" name with for example (Run Cfg - Load). This is to distinguish from Debug Configuration.

4.2.2. Run[edit source]

Make run with this configuration in order transfer .bin and load it.
Here is the transfer pop up:


Open a console inside STM32CubeIDE in order to check that firmware has been loaded and is running on Arm®-Cortex®-M33:

  • cat /sys/class/remoteproc/remoteproc0/firmware
  • cat /sys/class/remoteproc/remoteproc0/state


In case of problem follow chapter How to trace and debug the framework from Linux remoteproc framework overview article.

4.3. Debugging Secure and Non Secure firmware[edit source]

For debugging those firmwares the debug configuration has to reference both secure and non secure ELF files.

4.3.1. Debug configuration setup[edit source]

Select TFM_Protected_Storage_CM33_NonSecure project and right click on Debug As > C/C++ STM32 Application
This menu creates a debug configuration for the selected project.


It is recommended to enrich the default "Debug Configuration" name with for example (Debug Cfg). This is to distinguish from Run Configuration.

In "Startup" tab

  • edit NonSecure elf and unset Download
  • Add TF-M elf definition with "Add" menu, and:
    • program path to: trusted-firmware-m/config_default/bin/tfm_s.elf,
    • disable "Download"
    • give "ARM.exidx" file offset "0x9c20". The file offset address is retrieved from tfm-s.elf:
  readelf -a tfm_s.elf | grep "Unwind section '.ARM.exidx' at offset"
Unwind section '.ARM.exidx' at offset 0x9c20 contains 1 entry: 
  objdump -hw ./config_default/bin/tfm_s.elf | grep ".ARM.exidx"
17 .ARM.exidx               00000008  80008c20  80008c20  00009c20  2**2  CONTENTS, ALLOC, LOAD, READONLY, DATA

Info white.png Information

A way to control entry point of debug session could be to add a debug loop. In picture hereafter a debug loop has been added at the begining of tfm_hal_platform_init() TFM_Protected_Storage_CM33_trusted-firmware-m/trusted-firmware-m/platform/ext/target/stm/common/stm32mp2/secure/tfm_hal_platform.c.

Debug session will start inside this debug loop and changing i variable to 0 it will be possible to step into tfm initialization code.

Debug loop inside TF-M init code

4.3.2. Debug[edit source]

Launching the debug configuration, it is recommended to select Switch to the Confirm Perspective Switch in order to enter "Debug Eclipse perspective". Then thanks to "Suspend" icon, the control of Arm®-Cortex®-M33 execution can be taken. First instructions are while loop onto a volatile variable, this allows to take control from code start.

Step into tf-m initialization code

4.3.3. Traces setup[edit source]

With debug loop in place, it is possible to switch MPU Serial console to Cortex-M33 and display tfm-s and NonSecure elf traces.
First right click onto Target Status widget and stop it.

Target Status stop

Window > Preferences
then inside STM32Cube > MPU Serial
Select Remove filter and force console to /dev/ttyACM1


Then, open MPU Serial console thanks to the dedicated icon to display Cortex-M33 traces.

Tracing TF-M & Non Secure elf