ARMv8-M in non secure context

I am a bit confused by the effect of the configENABLE_TRUSTZONE flag.
According to this (sorry for the spaces but apparently even internal links are blocked for new users):
https: // www .freertos.org /2020/04/ using-freertos-on-armv8-m-microcontrollers .html
I should set this also to enabled if I want to run FreeRTOS in the nonsecure world but be able to call functions from an RTOS-less(!) secure world.
But what I get (in V10.4.x) are dependencies on secure_context and secure_init, which from my understanding consist of function entry points to be defined in the secure world (since they use the cmse_nonsecure_entry attribute).
So do I have to put those c-files in my secure project even though I do not want to have FreeRTOS there or should I actually disable the configENABLE_TRUSTZONE flag for my usecase?

The build process on ARMv8-M is somewhat tricky compared to ARMv7-M, so I recommend reading some of the articles provided by Arm or tool vendors to understand how to create your secure and non secure projects so that one can call into the other. I’m not sure which tools you are using, but some include built-in workflows that make it simpler.

Most use cases will run FreeRTOS on the non-secure side and non RTOS code on the secure side. For example: https://freertos.org/2020/07/security-for-arm-cortex-m-devices-with-freertos.html. To do that you must have configENABLE_TRUSTZONE set to 1. The hardware then enforces security by only allowing calls from non secure code to secure code through the secure gateway instruction - by design there is no software way around that so you need to see how your tools enable you to create those secure gateway entry points and place them in the correct place in memory.

The FreeRTOS download contains a few examples - which tools are you using?

If you want to run FreeRTOS on the non-secure side and want to call the functions exported from the secure side, you need to set configENABLE_TRUSTZONE to 1. Assuming that you are using GCC and Cortex-M33, you need to compile the following files:

On the other hand, if you do not want to use TrustZone to divide the environment into secure and non-secure, you have the following 2 options:

  1. Disable the TrustZone in hardware so that the MCU boots as non-secure and always remains non-secure. In this case, you need to compile the following files: https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/main/portable/GCC/ARM_CM33_NTZ/non_secure
  2. Do not disable TrustZone in hardware but instead run the FreeRTOS on the secure side and never jump to non-secure side. This way the MCU boots as secure and always remains secure. You will need to set configRUN_FREERTOS_SECURE_ONLY to 1 and compile the same files as above: https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/main/portable/GCC/ARM_CM33_NTZ/non_secure

Thanks.

I am using an STM32L5 in CubeIDE with GCC. What I wanted to confirm, and as I understand it that’s what you did confirm @aggarg, is that I actually need to build the secure part into the secure project. Even though I do not want to have FreeRTOS tasks in the secure space but only call separate secure functions from a non secure FreeRTOS task, which outside of FreeRTOS is normally possible with the cmse_nonsecure_entry bridge alone.
I guess this is about stable context switching inside FreeRTOS when preemption and/or TimeSlicing are active? What about a theoretical setup where FreeRTOS runs in non secure world but never needs to access the secure world at all(secure boot only)?

Yes, that is correct. You need to compile those files in the secure project so that FreeRTOS can manage secure context associated with a task (a task might be preempted when it was running on the secure side).

This is essentially the case of using FreeRTOS without TrustZone support. You need to compile the following files in the non-secure project - https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/main/portable/GCC/ARM_CM33_NTZ/non_secure

Thanks.

1 Like

(that link limit is really getting on my nerves, so a quote without links)

That’s what I expected as well. I think than I’ve got it figured out now :slightly_smiling_face:

Thank you for the fast support by the way.

Now I’ve finally come around to have my bootloader in a state that I am actually doing the context switch etc. and can boot from secure to unsecure.
But the FreeRTOS enabled application, which runs ok with disabled Trustzone, crashes while calling svc to start up the scheduler.


The following HardFault exception I get is back in secure state, which makes no sense at all to me since svc should be banked. Any ideas what I am missing?

EDIT: Ok, looks like this was a side effect from having the interrupts globally disabled before jumping to the application. Interestingly enough this was not a problem while starting from unsecure to unsecure. ( someone had a similar problem 10 month ago )

Glad that it worked for you. Thank you for taking time to report your solution.