2026-05-15 11:07 AM
This is some feedback for the STM32C5 OEMiRoT example provided by ST.
This is based on the STM32C5-MCU-HAL2.0.0 pack download 06-05-2026.
Attached you can also find the CMake Config files for the example, specifically for the NUCLEO-C542RC board.
General Bug Provisioning Python Script
The provisioning python script has a small bug when it comes to the prebuild script which adjusts the linker files.
These files are compiler specific so the correct adjustment function needs to be called.
This compiler dependent code is missing in the `_update_linker_define()` function in `STM32C5-MCU-HAL/rot/rot_provisioning/helper/project/project_generic.py` starting at line 318:
linker_path = self.config.get_compiler_linker(compiler)
value = f"0x{self.flash_layout.get_flash_layout(define):X}"
update_define_in_file(linker_path, define, value)change to
linker_path = self.config.get_compiler_linker(compiler)
value = f"0x{self.flash_layout.get_flash_layout(define):X}"
if (compiler == "gcc"):
update_variable_in_file(linker_path, define, value)
else:
update_define_in_file(linker_path, define, value)
Project Specific Configuration Bug
In the example configuration `provisioning/config/example.json' the last two "postflash" entries at the end of the file are missing the `"mode":"ur",` entry, so that programming is not successful, probably because the CubeProgrammer connection mode defaults to `hot plug` instead of `under reset`.
Change the two entries:
{
"reset":false,
"static_values":{
"BOOTADD":"0x080000"
}
},
{
"reset":false,
"static_values":{
"BOOT_LOCK":"0xB4"
}
}to:
{
"reset":false,
"mode":"ur",
"static_values":{
"BOOTADD":"0x080000"
}
},
{
"reset":false,
"mode":"ur",
"static_values":{
"BOOT_LOCK":"0xB4"
}
}
Compiler Errors
In CubeIDE with GCC there are 3 compiler errors, all because of size mismatches:
..../NUCLEO-C542RC/oemirot/low_level_flash.c:187:21: error: initialization of 'long unsigned int' from 'void *' makes integer from pointer without a cast [-Wint-conversion]
187 | .page_size = NULL, /* No page size defined */
| ^~~~FIX: `.page_size = 0,`
..../NUCLEO-C542RC/oemirot/low_level_flash.c:330:35: error: passing argument 3 of 'HAL_FLASH_ProgramByAddr' from incompatible pointer type [-Wincompatible-pointer-types]
330 | (uintptr_t *)buf,
| ^~~~~~~~~~~~~~~~
| |
| uintptr_t * {aka unsigned int *}FIX: `buf,`
..../NUCLEO-C542RC/oemirot/keys_map.c:77:12: error: initialization of 'unsigned int *' from incompatible pointer type 'uint32_t *' {aka 'long unsigned int *'} [-Wincompatible-pointer-types]
77 | .len = &pub_key_len,
| ^FIX: in line 48 change to `unsigned int pub_key_len;`
..../NUCLEO-C542RC/oemirot/generated/hal/mx_rcc.c:138:12: error: incompatible types when returning type 'void *' but 'system_status_t' was expected
138 | return NULL;FIX: `return SYSTEM_CLOCK_ERROR;`
CMake Configuration for the NUCLEO-C542RC
This config is for the OEMiRot examples, described here.
Since I have only a NUCLEO-C542RC board to test, the provided CMake configuration is only tested with this board.
It seems the following files need to changed for the other Nucleo boards of the example:
./cmake/flags_APP.cmake:target_compile_definitions(${CMAKE_PROJECT_NAME} PUBLIC STM32C542xx _RTE_ USE_TRACE=0)
./cmake/flags_OEMiROT.cmake:target_compile_definitions(${CMAKE_PROJECT_NAME} PUBLIC STM32C542xx _RTE_)
./cmake/files_APP.cmake: user_modifiable/Device/STM32C542RCT6/startup_stm32c542xx.c
./cmake/files_APP.cmake: user_modifiable/Device/STM32C542RCT6/system_stm32c5xx.c
./cmake/target_OEMiROT.cmake: set(CMSIS_Dname STM32C542RCT6)
./cmake/target_OEMiROT.cmake: set(CMSIS_Dname STM32C542RCT6)
./cmake/target_APP.cmake: set(CMSIS_Dname STM32C542RCT6)
./cmake/target_APP.cmake: set(CMSIS_Dname STM32C542RCT6)
./cmake/files_OEMiROT.cmake: user_modifiable/Device/STM32C542RCT6/startup_stm32c542xx.c
./cmake/files_OEMiROT.cmake: user_modifiable/Device/STM32C542RCT6/system_stm32c5xx.c
./appli/project_appli.ini:linker = ./user_modifiable/Device/STM32C542RCT6/stm32c542xc_flash.icf
./appli/project_appli.ini:linker = ./user_modifiable/Device/STM32C542RCT6/stm32c542xc_flash.ld
./oemirot/project_oemirot.ini:linker = ./user_modifiable/Device/STM32C542RCT6/stm32c542xc_flash.icf
./oemirot/project_oemirot.ini:linker = ./user_modifiable/Device/STM32C542RCT6/stm32c542xc_flash.ld
./appli/user_modifiable/Device/STM32C542RCT6/stm32c542xc_flash.ld
./oemirot/user_modifiable/Device/STM32C542RCT6/stm32c542xc_flash.ldPlease also checkt the linker files since I don't really know if this is all that is needed!!
Extract the `cmake_file.zi` file in your example directory. Extract the files in already existing directories (merge).
So for me I extract the files in the `.../oemirot_overwrite/NUCLEO-C542RC/` directory.
I tried to follow the STM example structure and the CubeMX2 CMake structure, so all the needed CMake files are located in `cmake` similar how CubeMX2 would generate the configuration.
The config assumes that the example is in `STM_PACK_DOWNLOAD/examples/advanced/rot/oemirot_overwrite/NUCLEO-C542RC/` and that the middleware, drivers and so on are under `STM_PACK_DOWNLOAD/...`.
You can get this by downloading the OEMiRoT example from the STM Pack Creator site https://dev.st.com/stm32pc or from Github.
There are two CMake projects, one in `oemirot` for the bootloader and one in `appli` for the example application.
Both need to imported, e.g. in CubeIDE via `Import > Import STM32 Project > STM32 CMake Project`.
Both use Python based pre-build scripts and the application also uses a Python based post-build script.
These scripts need the working provisioning setup. The CMake scripts assume there is a Python venv in `./venv`in the main example directory. The configuration should also work if you have the provisioning stuff installed globally, but this is not tested, see the `CMakeLists.txt` file.
In the `CMakeLists.txt` file is also the configuration of the CubeProgrammer Path! This path needs to be adjusted to your system configuration!
The build directories will be created in the `./cmake/` directory, similar to the EWARM config. So, you might want to create a `build` symlink in the two project folders, so e.g. the CubeIDE Build Analyser works properly.
In the `oemirot` project, MCUBoot middleware is intentionally imported as project files, so that the linker can find the `main()` function which is in the MCUBoot middleware.
Usage:
Firmware Updates on Linux / MACOS
Since `teraterm` is a Windows only program, the firmware update can be tested with the Python based YModTerm, e.g. installed in the same Python venv ....
The terminal supports YModem transfer needed for firmware upload.