cancel
Showing results for 
Search instead for 
Did you mean: 

Splitting system from application

mjroeq
Associate II

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.

mjroeq_0-1758112501387.png

 

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.

6 REPLIES 6
Saket_Om
ST Employee

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.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

>>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() 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pavel A.
Super User

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.

 

Thank you for the reply,
 
I am sure you are right, and I believe my issue is a result om my lacking understanding of how libraries are compiled:
  • I started over, and created two project in cubeIDE: "system_project" and "application_project"
  • I configured both projects for my board hardware and created a simple blink example in both projects
  • Both projects compile without issues and can be flashed to the board, and works as intended. 
  • I modified the "system_project" so that the "blink()" method is weak
  • I modified the "application_project" so that the "blink()" method resides in a separate "application.c"
  • I then compiled the "system_project" as a static library "libsystem_project.a"
  • I modified the "application_project" settings:
    • to include the "libsystem_project" library 
    • to include the "libsystem_project" library path in the workspace
    • to include all header files in the "system_project"
  • I then started to delete files in the "application_project" to see when either compilation or execution would break
  • In the "application_project" i am able to delete everything, except:
    • appplication.c and application.h - Which are of course required to provide the application specific override of blink()
    • the linker script STM32F412VGTX_FLASH.ld - Which I guess is required for linking the final executable
    • the file: stm32f4xx_it.c - If I delete this, I run into the issue with a missing interrupt handler - A screenshot of the call stack is attached below as you suggestedmjroeq_0-1758187318426.png

       

    • the file: syscalls.c - If I delete this, the compilation fails 
      • With errors like this:
      • .../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(libc_a-closer.o): note: the message above does not take linker garbage collection into account
      • And warnings like this:
      • _close is not implemented and will always fail
Except the files listed above, everything can be deleted and the "application_project" still builds and works correctly - Including main.c, the startup script, all HAL and CMSIS drivers, etc.
 
I do not understand why I cannot delete the "stm32f4xx_it.c" and "syscalls.c" files, since both are present and identical in the "system_project", so I would have thought that the content of the files would be included in the static "libsystem_project" library?
 
Is there a  better to do what I am trying to achieve here? 
 
I do realise this is a somewhat backwards way of using static libraries, in that in my case, the static library contains the entire setup and runtime execution, and the application only contributes a single method to be called at runtime. In a traditional context, I guess the application would contain the runtime execution, and the library would contain the method to be called at runtime.
 
Thank you for the help!

 

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?

The ARM TRM or ST Programming Manual cover the *CORE*

https://www.st.com/resource/en/programming_manual/pm0214-stm32-cortexm4-mcus-and-mpus-programming-manual-stmicroelectronics.pdf#page=225

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..