simonhaines wrote on Thursday, April 04, 2019:
I am looking for advice on the best way to suspend/resume FreeRTOS for a low power application.
The application has has two operating modes: active and suspended. When active, it uses FreeRTOS with tickless idle to manage many threads and peripherals. This works really well.
When suspended, the application is waiting for an interrupt from one of two sources: a button press or an ADC compare trigger (low battery voltage detect). All other peripherals and interrupt sources are shut down.
The application is running on a NXP Kinetis part (ARM Cortex-M4F). To enter low power, it requires moving through clock configurations to arrive at a low power clock domain with reduced core/bus/flash clocks. Because of this, it is easier to suspend FreeRTOS and disable the SysTick until one of the interrupts is triggered, then move back through the clock configurations to arrive at the active clock domain, then re-enable the SysTick and resume FreeRTOS.
Is this the right thing to do? I could instead re-clock the SysTick with the low power clock and adjust the tick rate just to keep FreeRTOS running, but it is not needed at all.
To suspend FreeRTOS, I am entering a critical section, calling vTaskSuspendAll, disabling the SysTick by clearing the bit in the SysTick CTRL register, clearing any pending SVC/SysTick by writing the appropriate bits in the SCB ICSR register, and then exiting the critical section.
To resume FreeRTOS, I am entering a critical section, resetting the SysTick value to 0, enabling the SysTick by writing the bit in the SysTick CTRL register, calling xTaskResumeAll and exiting the critical section.
I understand by doing this I’m losing software timers, but these aren’t needed in low power anyway. Is this a valid approach? It seems to work so far, but I’m worried about lurking pitfalls. Advice appreciated.