How to use an RTOS with Secure Manager on STM32H5

Revision as of 18:47, 6 December 2023 by Registered User

1. Introduction

In the context of the Secure Manager, an RTOS can be used. This article will explore how an RTOS can be used with the Secure Manager, with a focus on the mechanism provided to ensure secure, thread-safe calls.


Prerequisite:


2. Implementation example

Using the secure manager from a non-secure application is used in a single thread, which does not pose any concurrent access to it. To have a real-time operating system multithreading application while making calls to the secure manager, it is necessary to protect these calls. This ensures that only one call at a time can be made in the secure manager.

2.1. Thread-safe secure calls

To protect shared resources, the implementation will protect calls through the interface functions between the secure manager and the non-secure application. There is a mechanism in the middleware secure_manager_api that interfacing with the secure manager.

This mechanism, based on functions defined as __weak, will need to be re-implemented by integrating our protection, on mutexes, refer to Figure 2. The use of mutex as a mechanism to synchronize access to the PSA API is essential when using multithreading.

The functions ns_ipc_seq_begin and ns_ipc_seq_end, which are declared by default in the secure manager library in the file tfm_ns_interface.c, will need to be re-implemented in the RTOS project due to multithreaded use.

Firmware
└───Middlewares
  └─── ST
     └─── secure_manager_api
         └───ipc
             └───nonsecure
                 └───src
                     └───tfm_ns_interface.c
Figure 1 : tfm_ns_interface.c directory
Figure 2 : tfm_ns_interface.c functions

2.2. Step by step implementation

Here are the different steps to follow, to implement mutex in the secure manager with RTOS,in your project in the file where you decide to reimplement interface function see above :

  1. Initialize the mutex
  2. Create the mutex
  3. Implement the acquisition and release of the mutex in interface functions.


2.2.1. Detailed example applied with FreeRTOS.

1. Declare a mutex and initialize it to 0 :

static SemaphoreHandle_t nsIpcMutex = { 0 };

2. Create a function that creates the mutex and assigns it to the nsIpcMutex variable. If the mutex creation fails, log an error:

void tfm_ns_interface_init( void )
{
  nsIpcMutex = xSemaphoreCreateMutex();
  if(nsIpcMutex == NULL)
  {
   // Logging Error
  }
}

3. Re-implement the acquisition and release of the mutex with functions defines in semphr.c from library FreeRTOS, in the ns_ipc_seq_begin and ns_ipc_seq_end functions reimplemented in your project.

void ns_ipc_seq_begin(const ns_ipc_seq_info_t* info)
{
  /* Lock mutex */
  if(nsIpcMutex != NULL)
  {
    xSemaphoreTake(nsIpcMutex, portMAX_DELAY );
  }
  ….
}
void ns_ipc_seq_end(const ns_ipc_seq_info_t* info)
{
  /* Unlock mutex */
  if(nsIpcMutex != NULL)
  {
    xSemaphoreGive(nsIpcMutex);
  }
  ….
}

For more concrete examples, an actual implementations can be found in X-Cube-AWS & X-Cube-Azure using the Secure Manager with a real-time operating system.

2.3. Memory Management

Memory management is an important aspect of any real-time operating system (RTOS). The RTOS kernel requires RAM to store tasks, queues, mutexes, software timers, semaphores, and event groups. RAM can be dynamically allocated from the RTOS heap or it can be user-defined.

For example with FreeRTOS, different heap implementations are provided that can be used to dynamically allocate memory using a different memory allocation strategy, allowing developers to choose the most appropriate one for their application. More information with the following link: FreeRTOS Heap



No categories assignedEdit