1. Introduction
When working with the Secure Manager, incorporating an RTOS can be a valuable approach to ensure secure and efficient thread management. In this wiki article, we will explore the specific steps required to successfully integrate an RTOS with the Secure Manager, with a focus on the mechanism that guarantees secure and thread-safe function calls.
2. Prerequisite
- Installed Secure Manager
- Have a nonsecure application compatible with the Secure Manager
- Have the RTOS library chosen by the user integrated in the nonsecure application
3. Implementation example
Using the Secure Manager from a nonsecure application can be done in a single thread, which eliminates the possibility of concurrent access.
However, when working with a real-time operating system and a multi-threaded application, it is essential to protect the calls made to the Secure Manager. This protection guarantees that only one call can be made to the Secure Manager at a time, ensuring secure and efficient thread management.
In this section, we will provide an implementation example of how to protect calls made to the Secure Manager in a multi-threaded environment.
3.1. Thread-safe secure calls
To prevent multiple calls from the nonsecure application to the Secure Manager interface functions, a mechanism is included in tfm_ns_interface.c which can be found in the middleware secure_manager_api.
This mechanism, which is based on __weak functions, needs to be re-implemented with a mutex protection to ensure secure and efficient thread management.
The ns_ipc_seq_begin and ns_ipc_seq_end functions, which are declared by default in the Secure Manager, must be re-implemented in the RTOS project to support multi-threaded use.
3.2. Step by step implementation
The following steps outline how to implement mutex in the Secure Manager with RTOS in your project.
- Initialize the mutex
- Create the mutex
- Implement the acquisition and release of the mutex in the interface functions.
3.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.
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.
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, actual implementations can be found in X-Cube-AWS & X-Cube-Azure using the Secure Manager with a real-time operating system.