I pushed last bits of pico]OS 1.1 branch to github today and created 1.1.0 prerelease version. It is a major improvent on energy efficiency, since timer ticks can now be suppressed when system is idle.
In previous versions it was also possible to put CPU into sleep between timer interrupts, but there was no API to handle it – one had to use idle task hook to implement it. Now this can be handled in more elegant manner by adding p_pos_powerSleep function into architecture port. To get it called when system is idle, you’ll have to enable power management API in poscfg.h:
#define POSCFG_FEATURE_POWER 1
This is the simplest mode of power saving and it assumes that any interrupt will wake up the cpu. However, some microcontrollers support staying asleep when interrupt handler has been completed and require usually toggling a bit in cpu resgister to wake up. This can be handled by enabling wakeup feature in power management api by:
#define POSCFG_POWER_WAKEUP 1
and adding p_pos_powerWakeup function into archtecture port.
Further energy savings can be obtained by disabling timer interrupt during idle periods or ‘streching’ the timer tick to accumulate all idle time that is expected. To enable this mode add this to poscfg.h:
#define POSCFG_FEATURE_TICKLESS 1
It adds two new functions into pico]OS kernel: c_pos_nextWake can be called to find out the expected system idle time (in ticks) and c_pos_timerStep can be used to tell kernel how many ticks system actually slept (as it can be waken up earlier than expected by interrupt). Two new functions are required in architecture port also: p_pos_powerTickSuspend should disable the periodic timer interrupt and schedule a wakeup interrupt after given number of ticks. p_pos_powerTickResume should find out time actually slept, inform kernel about it and restart periodic tick.
I have been testing this with EMW3165 module, which has STM32F411CE cpu. A working tickless timer implementation for it is available at picoos/ports/cortex-m/stm32/tick_rtc.c. To enable it in application, following settings are needed:
#define POSCFG_FEATURE_POWER 1 #define POSCFG_FEATURE_TICKLESS 1 #define PORTCFG_TICK_SYSTICK 0 // disable standard systick implementation #define PORTCFG_TICK_RTC 1 // use tickless implementation with RTC
Wakeup timing is handled with STM32 RTC wake up timer.
Using tickless idle mode can cause slight clock drift in system, which might (or might not) be a problem for a realtime application. If timing accuracy with tickless mode is not good enough for one’s application, it is perhaps better to avoid tickless mode and keep using old-school timer interrupt (you can still got some power savings as the CPU sleeps between interrupts).
I’ll probably add tickless idle implementation for MSP430 in near future, as it is really easy to do now. On Cortex-M chips, Energy Micro EFM32 and Texas Instruments MSP432 might deserve an implementation also.
Architecture port power management API might still change, I’ll try to include common bits into pico]OS kernel from different architecture ports when I complete them. But that won’t affect any application code.