cancel
Showing results for 
Search instead for 
Did you mean: 

FreeRTOS with SBSFU is not working

PYada.1
Associate III

I am using the STM32L562E-DK development kit. I have taken reference to NUCLEO-L552ZE-Q and ported it for STM32L562E-DK. Also added External OSPI flash. without FreeRTOS it is working fine.

I have added FreeRTOS in the nonsecure application. For that, I have made the following changes

1) Adopt Middleware folder as provided in "FreeRTOS_ThreadCreation" example of STM32L562E-DK

2) Adopt stm32l5xx_hal_timebase_tim.c

3) Remove SysTick_Handler() definition in stm32l5xx_it.c file.

4) Add void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) API in main

5) Add osKernelInitialize(); and osKernelStart(); in main().

The same changes are working for the GPIO_IOToggle example. I am able to toggle GPIO in the thread. But in the case of the SBSFU Application is not working. Is there any specific change is required in bootloader or application?

@Frantz LEFRERE​ , @Jocelyn RICARD​  Can you please guide me regarding it?

24 REPLIES 24
PYada.1
Associate III

Thanks @alister​ for your input.

@Frantz LEFRERE​ , I have taken FreeRTOS_SecureIOToggle_TrustZone example but still not able to get the timer interrupt.

I have added the following code in SysTick_Handler() API.

void vFreeRtosContextSwitching()

{

SysTick->CTRL;

if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {

/* Call tick handler */

uint32_t ulPreviousMask;

ulPreviousMask = portSET_INTERRUPT_MASK_FROM_ISR();

{

/* Increment the RTOS tick. */

if( xTaskIncrementTick() != pdFALSE )

{

/* Pend a context switch. */

portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;

}

}

portCLEAR_INTERRUPT_MASK_FROM_ISR( ulPreviousMask );

}

}

And added following macro in FreeRTOSConfig.h file

#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 1

Now my FreeRTOS task is working fine.

But I am not able to use HAL_Delay() API.

After debugging I found that when HAL_Delay() is called SysTick_Handler(), which will prevent to increase tick and HAL_Delay's while loop doesn't exist. What can be the possible reason for this?

Can you please help me with it?

>I have added the following code in SysTick_Handler() API.

What is the "SysTick->CTRL;" for?

If you keep interrupts disabled until FreeRTOS starts, it shouldn't need to test xTaskGetSchedulerState.

>What can be the possible reason for this?

HAL can work on bare-metal and doesn't know about FreeRTOS.

Cube (my version's old, so it may have changed) works around that by assigning FreeRTOS a peripheral timer and HAL uses the SysTick.

As you're modifying SysTick_Handler, if it calls HAL_IncTick too, that should fix HAL_Delay.

PYada.1
Associate III

Thanks @alister​  for quick response.

>What is the "SysTick->CTRL;" for?

SysTick->CTRL is used to clear over flow flag. I have copied vFreeRtosContextSwitching() code form cmsis_os2.c file's SysTick_Handler() API.

>As you're modifying SysTick_Handler, if it calls HAL_IncTick too, that should fix HAL_Delay.

Yes I am modifying SysTick_Handler() in stm32l5xx_it.c file, It also calls HAL_IncTick() before calling vFreeRtosContextSwitching(). But when HAL_Delay() is called SysTick_Handler() is not triggered, so tick is not incrementing as HAL_IncTick() also will not be called. This cause HAL_Delay() stuck into while loop.

>But when HAL_Delay() is called SysTick_Handler() is not triggered, so tick is not incrementing

You've said FreeRTOS is working.

Superior FreeRTOS alternatives to HAL_Delay include vTaskDelay or vTaskDelayUntil or block on a notifier or semaphore and code an interrupt to unblock it.

[EDIT] HAL_Delay must be being called from a context the SysTick can't interrupt.

Before discussing solutions, would you like to explain the context HAL_Delay is being called?

>Superior FreeRTOS alternatives to HAL_Delay include vTaskDelay or vTaskDelayUntil or block on a notifier or semaphore and code an interrupt to unblock it.

TaskDelay is working fine as expected.

>would you like to explain the context HAL_Delay is being called?

HAL_Delay() is called in task.

void StartDefaultTask(void *argument)

{

/* USER CODE BEGIN 5 */

(void) argument;

printf("\r\n LED task Started \r\n");

for (;;)

{

      printf("\r\n LED Toggle \r\n");

      /* Insert delay 1000 ms */

      HAL_Delay (GPIO_TOGGLE_DELAY);

}

/* USER CODE END 5 */

}

If I replace HAL_Delay() with osDelay() it works fine and prints a message every 1 second

osDelay is a CMSIS-RTOS wrapper for vTaskDelay.

You would not want to use HAL_Delay  there. But it should work.

It's not working indicates timeouts in HAL function wouldn't work either. Check your SysTick_Handler calls HAL_IncTick and HAL_IncTick increments uwTick.

@alister​ Thanks for inputs,

As I have mentioned previously, 

when my task calls HAL_DELAY(), SysTick_Handler() interrupt callback is not triggered, so that tick count is not increasing and HAL_DELAY waits for infinite time.

During normal execution, when HAL_Delay() is not called SysTick_Handler() interrupt callback is triggered.

>when my task calls HAL_DELAY(), SysTick_Handler() interrupt callback is not triggered, so that tick count is not increasing and HAL_DELAY waits for infinite time.

And this requires fixing if you are to use HAL drivers because they use HAL_GetTick to implement timeout checking and would fail the same as HAL_Delay.

As I suggested previously,

Check your SysTick_Handler calls HAL_IncTick and HAL_IncTick increments uwTick.

I am unsure from your reply whether you are asserting HAL_Delay is the problem.

Beware HAL_Delay is a weak symbol (in my FW anyway) and so you may have more than one.

Please grep and see. If you have more than one, you can determine which one is being used by inspecting your map file.

Post the HAL_Delay source code (of the one you are using).

Jocelyn RICARD
ST Employee

Hello @PYada.1​ 

I'm not sure what your are exactly testing.

Systick should only be used by RTOS.

HAL_Delay should use another timer, like TIM6. If you use CubeMX to generate your project, the code for it will be provided automatically.

Best regards

Jocelyn

Thanks @Jocelyn RICARD​ ,

Yes, I have tried to use a timer for systick, but My timer interrupt is not getting triggered as mentioned in the previous discussion. Even without FreeRTOS if I create a timer in the nonsecure application, the interrupt of overflow is not triggered. During debugging I have seen timer is started and its count increased, overflows and started from zero as well. The main issue is "Not getting timer 6 interrupt triggered". I have taken reference from "FreeRTOS_SecureIOToggle_TrustZone" provided in "STM32CubeL5". Is there any specific configuration required to use a timer in the nonsecure application?

Note: Actual issue is not getting timer overflow interrupt in the nonsecure application.