Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Trying to implement Tickless Idle sleeping on STM32L476 using STM32CubeMx

Posted by mattster5 on May 6, 2016

Trying to get the Tickless Idle working on my project. Using a Nucleo64 l476 board, used STMCubeMx to set the project up and had it install FreeRTOS.

Turned to Tickless Idle in the config.

First problem/question: How to get the code to start. Finally decided to suspend my two tasks, then put code in the interrupt to resume the tasks. That did not work and when I stepped through the freertos.c code I discovered that it did not work because it was determining that it could only sleep for 1 tick. Why 1 tick, because of the default idle task created by Cube:

~~~ for(;;) { osDelay(1); }


So I decided to also suspend the idle task - don't know if that's a good idea, but it works.

I have a break point in PreSleepProcessing, and I'm finding that it is always called with ulExpectedIdleTime set to 209. I don't understand why, all the tasks are suspended, shouldn't it be infinate?

Also: I want to eventually put in code to change the CPU clock so I can enter stop mode. But I'm unsure how FreeRTOS is waking itself up and how changing the CPU clock would affect that.

So, how do I figure out why it is sleeping for 209 ticks? should I change the default idle task? is it ok to suspend the default idle task? could I use a vTaskSuspendAll? will changing the CPU clock mess things up?

Thanks so much - first time posting to this board! -Matt

Trying to implement Tickless Idle sleeping on STM32L476 using STM32CubeMx

Posted by rtel on May 7, 2016

I would suggest the following steps:

1) Create just one task that does nothing but sleep for a fixed period, then toggle an LED (just to give visual feedback).

~~~ void vATask( void *pvParameters ) { const TickTypet x100ms = pdMSTO_TICKS( 100UL );

for( ;; )
    vTaskDelay( x100ms );

    /* You will have to provide the ToggleLED() function. */

} ~~~

Compile and run this with configUSETICKLESSIDLE set to 0 as a sanity check that everything is as expected, and the LED does indeed toggle at the expected rate.

2) Set configUSETICKLESSIDLE to 1, and configUSE_TIMERS to 0 (so the timer task is not interfering with anything) and build and run the code again. You should not see any difference in behaviour, but now the system should be turning the tick interrupt off in between LED toggles.

3) Record the expected idle time value as before - do this by just saving it into a variable, or array of variables, rather than printing it out of any other slow mechanism - as anything slow (writing to a UART or whatever) would adversely effect the operation at that point.

4) Halve the time passed to vTaskDelay() and record the expected idle time value again.

Does the expected Idle time halve when the block time is halved?

If not, look at the value of xMaximumPossibleSuppressedTicks in FreeRTOS/Source/portable/[compiler]/ARM_CM4F/port.c, because the expected idle time is capped to that value, and if you have a fast clock speed you may find the value is quite short as the SysTick timer is only 24-bits.

This is why, if you can't slow the clock that feeds the SysTick timer (which some microcontrollers can, but most can't) and you want ultra low power, then you need to implement a chip specific version. Links to some chip specific versions are found at the top of this page: http://www.freertos.org/low-power-tickless-rtos.html but I expect you have seen those already. Note the STM32L version might not be optimal. The CEC1032 and EFM32 examples are the newest and known to be extremely robust for slow clock speeds.

With regards to indefinite sleeps - I'm not sure if the generic tickless idle will ever sleep indefinitely, but some of the chip specific examples will. If all the tasks are blocked indefinitely or suspended and it is ok to only keep relative time, rather than absolute time, then eTaskConfirmSleepModeStatus() will return eNoTasksWaitingTimeout and you can sleep indefinitely - in which case only an interrupt other than the clock/timer interrupt will bring you out of sleep mode.

Trying to implement Tickless Idle sleeping on STM32L476 using STM32CubeMx

Posted by mattster5 on May 9, 2016

Thanks very much for the suggestions. What do you suggest I do about the default task? Remove it?

Also, xMaximumPossibleSuppressedTicks is... 209. (80 MHz clock, 1ms tick).


Trying to implement Tickless Idle sleeping on STM32L476 using STM32CubeMx

Posted by rtel on May 9, 2016

I'm not sure what the default task is doing, but if it is nothing more than shown in your previous post I would guess it was meant to be a template that you could then add your own code into. If you have created your own tasks already then there would seem to be no reason to keep the default task that was generated for you.

Trying to implement Tickless Idle sleeping on STM32L476 using STM32CubeMx

Posted by mattster5 on May 10, 2016

Ah, I see. I assumed it was the idle task - it's not. It's a template 'default'.

I changed the system clock to 4Mhz, and now the system sleeps for a little over 2 minutes at a time.

I have decided to change the clock FreeRTOS uses from the SysTick to LPTIM2. This way I can configure LPTIM2 to have the LSE clock (~32K). The clock will continue to run while asleep, and run at low power. I'll change the ticks per second to a lower number, which will give me more flexability to have long sleep times. It also means I can change the system clock to what ever speed I want and it won't affect FreeRTOS.

I think this is a very good solution and will be writting a paper on it for the rest of the company.

Also, is it possible to use vTaskSuspendAll instead of suspending each task indivdually? (just asking, I don't plan on doing it in the product).


Trying to implement Tickless Idle sleeping on STM32L476 using STM32CubeMx

Posted by rtel on May 10, 2016

No - vTaskSuspendAll() is perhaps not the best named function as it actually suspends the scheduler, not the tasks. It is not the same as suspending each task and when the "suppress ticks and sleep" function is called the scheduler is actually already suspended (to prevent race conditions).

Trying to implement Tickless Idle sleeping on STM32L476 using STM32CubeMx

Posted by mattster5 on May 10, 2016

One more thing - if I'm implementing a clock other than SysTick, do I need to set the alternate clock interrupt time inside configPRESLEEPPROCESSING? Or is there a routine other than vPortSetupTimerInterrupt that I need to create?

Thanks for your replies! -Matt

Trying to implement Tickless Idle sleeping on STM32L476 using STM32CubeMx

Posted by rtel on May 11, 2016

If you are using your own clock then it would be best to provide your own version of vPortSuppressTicksAndSleep().

Here are few examples you can use as templates. Note the one to use depends on whether your clock is an up counter or a down counter. You also have to take into account when the counter is cleared - some counters will be cleared by updating a compare match value, others won't:

Up counter example: https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Demo/CORTEXEFM32GiantGeckoSimplicityStudio/LowPowerDemo/lowpowertickmanagement_RTC.c

Down counter example: https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Demo/CORTEXM4FCEC1302KeilGCC/mainlowpower/lowpowertick_config.c

[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]

Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS v10.2.1 is available for immediate download. MIT licensed, includes 64-bit RISC-V, NXP Cortex-M33 demo & Nuvoton Cortex-M23 demo.

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


FreeRTOS and other embedded software careers at AWS.

FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Cadence Tensilica Cortes

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers





STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner