In the course of the work, encountering such a product, it is based on the CORTEX-M7 core of the stm32f769 chip, while using the FreeRTOS real-time operating system.
Because the product is battery-powered, it has low power requirements.
Next, I'll briefly describe the low-power characteristics of the STM32 and FreeRTOS, and how to achieve low power consumption when used in conjunction with each other.
1. three low-power modes of the stm32f769 chip
The stm32f769 supports three low-power modes, namely SLEEP, stop, and standby, which increase power-saving capabilities in turn.
In SLEEP mode, only the CORTEX-M7 kernel stops working, and the peripherals are still running.
After entering sleep mode, all interrupts can wake the MCU and exit sleep mode.
In stop mode, the kernel stops working, and all clocks (such as HCLK, PCLK1, PCLK2, etc.) also stop working, that is, all peripherals stop working, and here is a bit of special attention, when SYSTICK is also stopped. Of course, the RTC in our product continues to operate because its clock source is an external 32.768K oscillator.
After entering STOP mode, only external interrupts (Exti) can wake the MCU (the RTC interrupt can also wake the MCU because the RTC interrupt hangs on the external interrupt line).
In STANDBY mode, the kernel, all clocks, and the backup 1.2V power supply all stop working.
When awakened from STANDBY mode, the system is equivalent to performing a reset operation and the program will start over.
In summary, it is clear that in the three low-power modes offered by STM32, we can only use the SLEEP and STOP of the two, STANDBY not applicable.
For more detailed low-power content introduction to STM32769, see section 4.3 –low-power Modes of Reference Manual.
2. FreeRTOS low power implementation [2]
When you start the Task Scheduler, FreeRTOS creates an idle task with the lowest task priority, and the idle task gains CPU usage only if all other tasks are blocked.
Therefore, it is very easy to think of the idle task to achieve the entry and exit stm32f769 low-power mode, that is, after cutting into the idle task, let the STM32 also into the low-power mode, and before switching out of the idle task, to wake up STM32.
In addition, the newer version of FreeRTOS adds Tickless mode, which is described in more detail in the reference [2].
3. the entire product of low-power implementation
So in the IDLE task, how to determine whether the current STM32 should be into sleep or STOP mode?
Taking into account the difference between sleep and STOP, that is, any interrupt under sleep can wake up the STM32, and under STOP can only be awakened by an external interrupt, so our product uses the following mechanism:
In the foreseeable future, if the programmer knows that a non-external interrupt will occur during this period, the STM32 will not be allowed to enter STOP mode. Because, once entered the Stop,stm32 can only respond to external interrupts, but not to non-external interrupts (such as serial, i²c and other peripheral interrupts) to respond.
An example would be easier to understand. Suppose such a scenario--by interrupting to read the I²C data. After the programmer has configured the I²C read data interrupt, the system is in the state of waiting for the i²c interrupt. Then, if an i²c interrupt is generated, it means that the data has been read and the programmer can then process the data.
Then, after the configuration of the I²c read data interrupt, if the IDLE task is executed at this time, then, in this case, the STM32 can not enter the STOP mode, but only into SLEEP mode. Once an i²c interrupt is generated, the STM32 is awakened from SLEEP. If the previous STM32 entered the STOP mode, then the I²C interrupt will be omitted.
So, in this product, we provide two interfaces, Disable_enter_stop_mode and Enable_enter_stop_mode, respectively, to inform that the current cannot enter the stop mode and currently can enter stop mode.
To tidy up, we can get the following flowchart:
If you can now enter stop mode, there is one more thing to do before actually entering stop-configuring the RTC wake-up timer to wake the STM32 at some point. How long you can sleep in STOP mode, calculated by the Prvgetexpectedidletime interface in FreeRTOS.
After the RTC wake-up timer is configured, you can call Hal_pwr_enterstopmode to get STM32 into STOP mode. If no interrupts are in the PENDING state at this time, STM32 will immediately enter stop mode, and if there is an interrupt in the PENDING state, STM32 will not enter stop mode and the code will continue to execute down.
When STM32 is in STOP mode, if any external interrupts (Exti interrupts) are generated, the STM32 is immediately awakened, regardless of whether the RTC wake-up timer has timed out. If there is no external interruption during the period, the STM32 will remain in STOP mode until the RTC wake-up timer expires, thus STM32 wakes up.
In addition, because the SYSTICK that provides the heartbeat clock for FreeRTOS also stops working under stop, it is necessary to tell FreeRTOS when the stop passes after being awakened.
In short, the basic idea of reducing the overall power consumption is to allow FreeRTOS to be idle for as long as possible, allowing STM32 to be in STOP mode as much time as possible, ultimately achieving as much power savings as possible.
After a short period of time, and then put the relevant code to paste out, for reference.
Reference documents:
[1] stm32f76xxx Reference Manual
[2] FreeRTOS low Power support–tickless Idle Mode
STM32 and FreeRTOS for low power consumption