2025-09-17 5:36 AM
Hello,
I have made a custom STM32F412 board, intended for safety applications within various types of machinery.
I have completed the hardware and I am now working on the software, which I need some help to organize correctly.
Since all applications running on the board are safety related, most of the software is not related to the actual application (type of machinery) being operated.
Rather, the majority of the code is running various monitoring and diagnostics routines to ensure that both hardware and software functions as intended; e.g. timing constraints on code execution, monitoring of RAM and Flash memory, etc.
All of this "system monitoring" is maintained by me, and must be certified independently. It must not be modified, accidentally or intentionally, by the programmers that subsequently write the code for the specific applications running on top of the system monitoring.
For that matter, I would like to statically compile everything, including peripheral configuration, interrupt routines, clock setup, main function, etc. and then subsequently have the application be provided externally as a single function .
My initial thought was to create a "system" project in cubeIDE that contains the entire system setup, main function, startup script, etc., along with the application defined as an empty __weak function, and then compile this project as a static library.
I would then create a secondary "application" project, to include the static system library, while overriding the _weak application method, with the business logic of the actual application being implemented. The "application" project would not be supposed to include any setup, main function, startup script, or anything, since this should all be available from the "system" library.
I have however not been able to get this to work:
- I can compile the static "system" library as wall as the "application" program, seemingly without issues
- I can flash the board, also without issues
- I can get the board to run, and enter the main function, while single stepping through the application
- When I let the program run without single stepping, I get an exception that sends me to the Default_Handler in the startup script
I am not sure if what I am trying to do is a viable approach for getting the separation I need.
Any inputs on getting this to work, or for an alternative approach, would be greatly appreciated.
2025-09-17 8:28 AM
Hello @mjroeq
Could you please inspect the call stack at the moment the default handler is triggered. By examining the call stack, you can identify the last function or instruction executed before the default handler was invoked, which often points directly to the source of the issue. Additionally, it is important to check the interrupt vector table to determine if any handler is missing or misconfigured.
2025-09-17 1:41 PM
>>When I let the program run without single stepping, I get an exception that sends me to the Default_Handler in the startup script
You could perhaps check the source, by inspecting/reporting VECTACTIVE field in SCB->ICSR
You can instrument your library to provide a diagnostic build to identify what is going astray in the application.
You might consider a setup() / loop() type construct like Arduino if your library wants more control and doesn't disappear into a blocking function like application()
2025-09-17 2:34 PM
IMHO all this is not feasible on STM32F4. A separate MCU is needed, or MCU with trustzone.where your stuff and the user app run in different zones.
2025-09-18 2:24 AM
2025-09-18 2:28 AM
Thank you for the reply - I do not know "VECTACTIVE", what is this? I cannot find it in the RM, not can I find any mention of SCB or ICSR?
I think it is a good idea to structure the project in an arduino like fashion with a loop and setup method, but I am still not sure how to organize the various code components so that the application programmer only has access to modify the elements that he is supposed to?
2025-09-18 8:39 AM
The ARM TRM or ST Programming Manual cover the *CORE*
The linker should permit the type of build you propose, but you'll need to be attentive. Establish why it currently isn't outputting viable code.
Inspect the objects, libraries and executable files with tools like OBJDUMP or FROMELF, confirm linkage, and what's imported/exported by each. Do a disassembly and walk that to understand why it might be failing.