Hi @Alice_Yang , thanks so much for your response. Please disregard the error I posted in my first post. I was trying different things and that was one of the bad outputs.
I basically use the FreeRTOS blinky demo as my base code for RTOS and TrustZone. I tried using the Hello World TZ example but that did not come with FreeRTOS setup so it was harder to adjust.
Here's what I did to the FreeRTOS blinky demo:
(1) I integrate the functions and options etc. from the qca_demo with the blinky demo. I also resized the memory partitions, especially for NSC since it might need to contain more non-secure callable functions (the S and NS levels are kept to preserve the levels, e.g., S-Priv, NSC-Priv, etc.).
(2) I keep the S and NS code and I modified the prvCreateTasks() to instead create the task from the qca_demo. Please see the code below.
...
void task_main(void *param)
{
/* This task calls secure side functions. So allocate a
* secure context for it. */
portALLOCATE_SECURE_CONTEXT(configMINIMAL_SECURE_STACK_SIZE);
int32_t result = 0;
(void)result;
/* Initialize WIFI shield */
result = WIFISHIELD_Init_NSE();
assert(A_OK == result);
/* Initialize the WIFI driver (thus starting the driver task) */
//result = wlan_driver_start_NSE();
result = wlan_driver_start();
assert(A_OK == result);
...
}
...
static void prvCreateTasks(void)
{
/* Create the WiFi task. */
BaseType_t result =
// xTaskCreate(task_main, "main", TASK_MAIN_STACK_SIZE, task_main_stack, TASK_MAIN_PRIO, &task_main_task_handler);
xTaskCreate(task_main, "main", TASK_MAIN_STACK_SIZE, task_main_stack, portPRIVILEGE_BIT | tskIDLE_PRIORITY, &task_main_task_handler);
assert(pdPASS == result);
}(3) The original FreeRTOSConfig.h from qca_demo contains the following options.
#define configENABLE_MPU 0
#define configENABLE_FPU 0
#define configENABLE_TRUSTZONE 0
#define configRUN_FREERTOS_SECURE_ONLY 1
I changed it into the following.
#define configENABLE_MPU 0
#define configENABLE_FPU 0
#define configENABLE_TRUSTZONE 1
#define configRUN_FREERTOS_SECURE_ONLY 0
Initially the configEnable_MPU and configENABLE_FPU were also set for the blinky demo but I set them to 0 instead to simplify the setup for now since I realized partitioning the code into privilege levels based on MPU made things worse.
This all compiles and runs (please see the source code attached), and it goes well and creates the first task for task_main as shown in (1). However, currently the code gets the HardFault when trying to create the second task for the Atheros driver in driver_main.c.
status = xTaskCreate(Atheros_Driver_Task, "Atheros_Wifi_Task", ATHEROS_TASK_STACKSIZE, pCxt, ATHEROS_TASK_PRIORITY,
&atheros_wifi_task_id);Upon stepping into this function, I followed the execution path and found that the following function might be the problem.
void vPortYield( void ) /* PRIVILEGED_FUNCTION */
{
/* Set a PendSV to request a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
/* Barriers are normally not required but do ensure the code is
* completely within the specified behaviour for the architecture. */
__asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "isb" );
}Basically, it looks to me that the first task is already running, and the scheduler wants to run this task as it is given a higher priority. But when the scheduler tries to perform this yield function to yield the first task and run the second task instead, it gives the HardFault. Please let me know if you have any thoughts on what the problem could be.
Thanks so much for the attached document. I'll have a look and follow what's inside. Looking forward to hearing back from you again.