cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32f407+freertos tickless mode

totti001
Associate II
Posted on May 08, 2014 at 23:04

Hello everybody.

I have a working code with stm32f407 and freertos. I want to use stop mode at the microcontroller. I read the tickless mode at freertos, this is for use the sleep mode. If I define this mode, my code goes to default handler, without this working well. The tickless mode need more irq handler?

#stm32f4-freertos
8 REPLIES 8
chen
Associate II
Posted on May 09, 2014 at 10:42

Hi

I personally would advice people to NOT use tickless mode unless you know what you are doing!

I know what I am doing - I do not like using it!

STM32 Sleep mode (check the reference manual) only puts the ARM core into a suspended state. The peripherals can be suspended (clock gating) or not depending on how you configure them.

With FreeRTOS - be very careful. The version of FreeRTOS I am using clocks the SysTick from the ARM core, so once the ARM is in sleep mode - the SysTick stops!

I have to modify FreeRTOS code to fix this. Now I use Sleep mode and I do not need to use Tickless mode.

''I want to use stop mode''

The STM STOP mode is a very deep low power mode (check the reference manual).

It pretty much puts the whole STM32 (ARM core and peripherals) into a suspended mode.

It can only be woken up by a LIMITED number of interrupts!

''I read the tickless mode at freertos, this is for use the sleep mode.''

No exactly. 'Tickless' mode is for when the SysTick has been stopped. It can be used for any of the STM low power modes if the SysTick has been stopped.

Basically, FreeRTOS keeps a counter going, incremented by the SysTick. This helps to do timing in the OS.

If the SysTick is stopped, the count must be manually (by the code yo write) adjusted on wake up. Something must count while the SysTick is stopped. The count that FreeRTOS maintains MUST be updated correctly when the processor wakes.

''The tickless mode need more irq handler?''

Something needs to count while the SysTick is stopped. This does not necessarily need to generate an IRQ (since this may wake the processor).

martinmartin9
Associate II
Posted on February 12, 2015 at 19:23

I am also doing this and seem to be missing something fundamental.  Background, my system is using FreeRTOS and STM32F429, it works, and when I enable tickles mode, it still works, and the current reduction is as expected.

I want to use STOP mode now.  I can't figure out where to put the HAL_PWR_EnterSTOPMode() call...

It seems to me I should put that call in the vApplicationIdleHook(), but doing this violates the FreeRTOS rule that says vApplicationIdleHook() should never block.  But FreeRTOS also say this is where you put your processor into ''low power mode''. 

When I put HAL_PWR_EnterSTOPMode() into vApplicationIdleHook() my target ''stops'', and the periodic timer event I have running never runs anymore.  So I have one of two problems, the timer is not triggering a wakeup, or I can't enter STOP mode in the Idle hook, ... or?

martinmartin9
Associate II
Posted on February 12, 2015 at 20:02

I solved my problem, made a mistake...

But still would like some comments if I have the right approach....

martinmartin9
Associate II
Posted on February 16, 2015 at 04:27

I actually I did not solve my problem... In the IDLE hook I use,

HAL_PWR_EnterSTOPMode() And I am finding I am always getting interrupt, so it doesn't stay in STOP mode for very long. The interrupts that are pending are multiple, and I tried clearing them myself, but they become pending again.

/****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/
NonMaskableInt_IRQn = -14, 
/*!< 2 Non Maskable Interrupt */
MemoryManagement_IRQn = -12, 
/*!< 4 Cortex-M4 Memory Management Interrupt */
BusFault_IRQn = -11, 
/*!< 5 Cortex-M4 Bus Fault Interrupt */
UsageFault_IRQn = -10, 
/*!< 6 Cortex-M4 Usage Fault Interrupt */
SVCall_IRQn = -5, 
/*!< 11 Cortex-M4 SV Call Interrupt */
DebugMonitor_IRQn = -4, 
/*!< 12 Cortex-M4 Debug Monitor Interrupt */
PendSV_IRQn = -2, 
/*!< 14 Cortex-M4 Pend SV Interrupt */
SysTick_IRQn = -1, 
/*!< 15 Cortex-M4 System Tick Interrupt */

Specifically -1,-2,-4,-5 and -
martinmartin9
Associate II
Posted on February 16, 2015 at 04:32

To be clear, I am using Tickless mode.  I believe I have verified that the systick timer is not firing because the IDLE hook is only running when the tickless counter goes off, about every 2sec with my current clock.  If I disable tickles mode, I see the IDLE hook run at 1ms rate (expected).

martinmartin9
Associate II
Posted on February 17, 2015 at 17:32

I got some clarification.  FreeRTOS, in tickles mode, executes its own WFI code in vPortSuppressTicksAndSleep()... one should not call one in the IDLE hook.

A question I am trying to understand is that the IDLE hook can be used to enter a low power state, but how does one exit the low power state when a non-IDLE task starts?  It seems to me there should be a hook function for ''about to run another non-IDLE task''...

scottmorgan
Associate II
Posted on April 22, 2015 at 17:58

Have you figured out how to use STOP mode with FreeRTOS on the STM32?  I'm using an STM32F2 and having problems with hard faults randomly occurring after leaving stop mode and also with this periodic wake-up.  I have commented out the following code in Port.c:

if( xModifiableIdleTime > 0 )

{

__DSB();

__WFI();

__ISB();

}

And I implemented my own sleep code here:

void PreSleepProcessing(unsigned long ulExpectedIdleTime)

{

  /* Avoid compiler warnings about the unused parameter. */

  (void) ulExpectedIdleTime;

  

    if(ulExpectedIdleTime > 100)

    {      

        HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

        SYSCLKConfig_STOP();

    }

    else if(ulExpectedIdleTime > 0)

    {

        BSP_LED_Off(LED1);

        __DSB();

        __WFI();

        __ISB();

        BSP_LED_On(LED1);

    }

}

static void SYSCLKConfig_STOP(void)

{

  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  RCC_OscInitTypeDef RCC_OscInitStruct;

  /* Enable Power Control clock */

  __PWR_CLK_ENABLE();

  uint32_t pFLatency = 0;

  

  /* Get the Oscillators configuration according to the internal RCC registers */

  HAL_RCC_GetOscConfig(&RCC_OscInitStruct);

  

  /* After wake-up from STOP reconfigure the system clock: Enable HSE and PLL */

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

  RCC_OscInitStruct.HSEState = RCC_HSE_ON;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

  {

    //Error_Handler();

  }

  /* Get the Clocks configuration according to the internal RCC registers */

  HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);

  

  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 

     clocks dividers */

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;

  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)

  {

    //Error_Handler();

  }

}

To wake from stop mode my understanding is that you will  need to enable hardware interrupts to do this which would include setting an RTC alarm to cause the wakeup to occur some time in the future.  You can set the alarm using HAL_RTCEx_SetWakeUpTimer_IT() if you are using the STM32 HAL library.

Walid FTITI_O
Senior II
Posted on April 15, 2016 at 19:51

Hi Scot,

This issue is now fixed in the new release by adding inside MX_RTC_Init():

__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG();

Before the call to:

HAL_RTCEx_SetWakeUpTimer_IT();

-Hannibal-