I’ve been actively using FreeRTOS for the last few months in various projects, and we’re very happy with the results.
At the moment I’m working on an STM32L4 nucleo board, and I have a few questions regarding low power modes and FreeRTOS. Some questions may actually be STM32 related, but I’ll take my chances here anyway!
I’ve set configUSE_TICKLESS_IDLE to 1 in this project. My understanding is the scheduler will try to go to sleep whenever the expected idle time is more than configEXPECTED_IDLE_TIME_BEFORE_SLEEP (2). Now, the application works as follows:
- There is one task that calls vTaskDelay(250), which is an LED toggle.
- All other tasks start either with xStreamBufferReceive(…) or ulTaskNotifyTake(…) in different shapes and sizes as they are all interrupt based (USB comms, UART, etc).
Can I expect FreeRTOS to actually enter:
traceLOW_POWER_IDLE_BEGIN(); portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); traceLOW_POWER_IDLE_END();
Here’s another question on the same system. I’d like to put the system on sleep for an indefinite amount of time, and be woken up either by push button (GPIO) interrupt or the RTC alarm. When the system wakes up, it would call a system reset, it doesn’t really care for how long it was asleep.
There is a system task which wakes up with xTaskNotifyWait(…), within that task, the system gets deinitialised like this:
vTaskSuspendAll(); vPortRaiseBASEPRI(); HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFE); ///< Enters sleep mode here HAL_NVIC_SystemReset();
That puts the system to sleep until the button is pushed and it restarts. RTC values are kept. So far so good.
If I change the stop mode entry to _WFI and enable the GPIO pin as interrupt instead of event:
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); ///< Enters sleep mode here
The system goes to sleep but fails to wake up when I push the button!
Below, I remove vPortRaiseBASEPRI():
vTaskSuspendAll(); HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); ///< Enters sleep mode here HAL_NVIC_SystemReset();
And the system jumps from the enter power mode to reset, starting again.
The GPIO button interrupt is set to 7. if I add this line:
vTaskSuspendAll(); vPortSetBASEPRI(7); HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); ///< Enters sleep mode here HAL_NVIC_SystemReset();
Same as before, the system goes directly to reset. Same thing if I add
after suspending the tasks.
My guess is there is an interrupt running configured by FreeRTOS which wakes the system up immediately after going to sleep in stop mode.
How would I go deactivating only those interrupts used by FreeRTOS and not the ones I need, the GPIO interrupt and the RTC interrupt?
Alternatively, I could disable all interrupts and just wake up on events, but for the sake of understanding, I’d like to get both methods to work.
Many thanks in advance!