1 The Significance of Low Power
Electronic products, especially those powered by batteries, require low power consumption. What exactly is considered low power? The values without context are meaningless; low power is a standard that is situational and can only be understood in context.
2 Ideas Determine Success or Failure
The chip datasheet states low power consumption, but those surprisingly small current standards are merely decorative and represent a non-functional state; the operational power consumption is what truly matters. Sometimes, to demonstrate low power consumption, a so-called low power mode must be designed into the application, where the system goes to sleep when no tasks are confirmed. Thus, the logic of “wanting the horse to run while also not feeding it grass” becomes a common choice for reducing system power consumption under normal operating conditions.
From a hardware perspective, it is essential to identify all possible current-consuming loops, determine which can be optimized through software control and which are unavoidable, and provide software developers with the relationship between all IO port states and their impact on power consumption, illustrated with simple tables showing how high or low levels affect consumption, and what happens with floating states. Initially configuring the driver software and verifying that the minimum current during operation meets the standards can confirm that the hardware is functioning correctly. The remaining space is for software developers to explore, and the software-based power reduction strategies are the main focus of this article. For more information, please follow the WeChat public account [Embedded Systems].
3 Driver Software Design
3.1 Port Configuration
First, confirm the default state of the pins after reset, whether there is leakage current, whether certain clock sources will be activated, and whether there are internal pull-ups or pull-downs, and then configure accordingly with hardware or peripherals. For example, disable internal pull-ups for AD channels, set ordinary GPIOs to low or high to avoid leakage, and avoid interrupt input modes for floating pins.
For fixed connection control, push-pull output can control peripherals, or choose open-drain when external pull-ups are present; special pins like UART can generally be configured in mode, with hardware automatically controlling the corresponding levels; for intermittent operations like ADC, once the input conversion is complete, it can be set back to output or turned off.
Some peripherals can be plugged in or unplugged, such as UART, which is high during normal idle. If the peripheral is powered down or removed but remains high, there is a risk of leakage, in which case the pin should be set to output low. Focus on a specific state during operation; when work ends or an exception occurs, switch states promptly to avoid leakage or mismatched levels.
If the peripheral supports interrupts, try to configure it to enable interrupts instead of polling communication at intervals.
3.2 Power Management
The chip often divides different power domains internally, and hardware peripherals are powered from different units. Parts that are temporarily unused can have their power domains and clock domains turned off immediately. When hardware costs allow or power consumption requirements are strict, peripherals should be powered independently so that in non-usage states, software can control power down. It is important to note that after shutting off the power domain, certain ports may need to be reconfigured to avoid leakage. For example, as mentioned in the previous section, after shutting off the power supply to the peripheral, the UART port of the peripheral becomes low, and the main control UART port cannot maintain a high level anymore.
3.3 System Clock
In normal operating modes, the higher the frequency, the higher the power consumption; completing the same work in a shorter time can also lead to quicker entry into sleep mode. If the microcontroller mainly performs control tasks without complex calculations, reducing the frequency to meet the requirements can switch to a lower frequency. If there are extensive mathematical calculations, one can trade space for time, or run at a high frequency to complete algorithms quickly, then dynamically switch to a lower frequency after completion.
At the same clock rate, lower supply voltage also results in lower power consumption; timed sampling and screen refreshing can also be processed at lower frequencies as long as the requirements are met.
3.4 Standby Leakage Current
Consult the datasheet or official SDK documentation to determine the lowest power sleep mode that meets the requirements and can be awakened. Write a test case that turns off all possible power-consuming peripherals, enters a sleep state, and verifies the power consumption under extreme conditions.
It may also be necessary to eliminate inherent power consumption on the circuit board that cannot be optimized, such as voltage conversion and other fixed current consumption components. Simply looking at the operating current of the main chip, check if it meets the theoretical values in the datasheet for the corresponding mode. If not, continue to shut down some functions that automatically turn on after reset, such as clock enables; or have hardware engineers assist in removing suspicious components to speed up troubleshooting. This first step is crucial and directly determines the best effect of the entire machine’s power consumption later on. During the configuration process, it is essential to gain a nuanced understanding of which peripherals and configurations impact power consumption, how they impact it, and to what extent.
3.5 Sleep and Wake-up
After sleeping, some may work at reduced frequency, some may be in a pseudo-dead state (software not running, memory recoverable; some cannot be recovered, waking up resembles a restart), or directly shut down (RTC shutdown alarm wake-up). Different hardware solutions and software requirements lead to different performances in sleep modes. During microcontroller development, confirm all sleep modes and which clock sources work or sleep in each corresponding sleep mode, combining specific application needs to clarify system requirements for wake-up sources and modes, thereby determining the system’s basic sleep mode.
Note that some chips maintain wake-up states on only a few ports in sleep mode, and only special pins can wake up; this needs to be considered in hardware design beforehand.
3.6 Power Consumption Assessment
Reducing power consumption is a problem that can only be solved through cooperation between software and hardware. For example, during AD sampling with a voltage divider, if directly connected to ground, it will continuously consume current; increasing the divider resistance sufficiently will result in low static current, but due to the AD’s internal resistance shunting, the final result will have a significant deviation. If an IO port controls its grounding, only grounding when sampling is required, and floating or pulling high after sampling, it can minimize static losses. Although the cost increases significantly, it effectively saves power. Whether to adopt this approach mainly depends on the power consumption standards; if slight continuous static losses are acceptable, there is no need to increase hardware costs.
Achieving the lowest power consumption in the system sometimes requires compromises between peripheral performance, hardware costs, and power consumption. Whether the CPU can reduce frequency, whether the hardware peripherals support interrupt wake-up, etc., all affect the final standby power consumption. Reducing power consumption is the result of cooperation between hardware and software, with software configuring drivers and hardware confirming current is within expectations. The theoretical values are defined based on manufacturer data or experience, as well as compromises based on the product definition of standby duration.
4 Business Software Design
While low power can be partly addressed through hardware, relying solely on hardware is insufficient; close cooperation with software is necessary to achieve the best results. The above focuses on hardware driver levels, which are generally more concerning, but in reality, the flexibility at the software business layer can yield more significant effects than the low power results achieved by hardware alone. In simpler terms, the optimization efforts of the underlying hardware to save power are far surpassed by a well-designed software implementation.
From the perspective of software business logic and product requirements, the design can lead to unexpected effects in power consumption. A simple summary of software power consumption optimization is “sleep whenever possible”.
4.1 Task Periodization
An embedded product includes many sub-functions and tasks; an application is realized through calls to several services. Here, services can be hardware services, such as AD voltage sampling and UART serial communication, or software services, such as TCP/IP network communication, etc. Simple functions like CRC checks, implemented purely in software, yield immediate results and have no impact on power consumption; for complex functions, it is better to implement them in a task-oriented manner, not specifically referring to operating system tasks or threads, but understood as a complete process for running a sub-function. A task with a clear start and end can be repeated cyclically based on needs, and by clearly distinguishing between running and non-running states, optimization can be achieved, such as reducing the duration of running or high-current segments, which can significantly affect power consumption.
4.2 Sleep Self-Management and Coordination
The entire embedded software system can be divided into many small tasks with periodic work, which may be interleaved or completely parallel. Essentially, each small task only needs to focus on its own start and end times. The system’s power management involves managing the power of each task, and only through effective coordination can minimal power consumption be achieved. Task-based power management can be divided into two parts: from a micro perspective, managing the power of individual tasks, and from a macro perspective, coordinating sleep among multiple tasks.
From a micro perspective, a task can independently complete its function; all steps within the task are determined and “self-governing”. From an external perspective, it acts as a “black box”. The requirements for low power consumption can be summarized into the following scenarios:
All three types of tasks coexist in the system. The first type is quite dominant; as long as it is executing, sleep is not permitted at all. The second type completes the task while also considering sleep. The third type can be ignored. When designing system tasks, the latter two types should be prioritized, avoiding or attempting to split the first type.
From a macro perspective, multiple tasks may be executing simultaneously at any time, each with different sleep requirements. If a coordination mechanism is to be established, what should be done? Each task, based on its minimum requirements, should check in with the sleep coordination agency to vote, indicating its current tolerable minimum power consumption and corresponding sleep level. The sleep coordination agency, acting as an arbitrator, periodically checks all task votes, finds the smallest sleep level, and enters the corresponding sleep state, similar to the shortest link in a bucket being the “consensus”. If anyone votes “no sleep,” the arbitration must give up sleep. Therefore, each task should be responsible and timely update its tolerance for sleep based on its various steps, ensuring that the voting can yield meaningful results.
This mechanism can be easily implemented, for example:
// WeChat public account: Embedded Systems uint16_t sleep_enable = 0xFFFF; //0xFFFF indicates that sleep is possible
uint16_t sleep_enable=0xFFFF indicates that the system can enter sleep; each task independently operates on the corresponding bit, clearing it to 0 when sleep is prohibited and setting it to 1 when sleep is allowed. The sleep coordination mechanism can periodically check whether sleep_enable is 0xFFFF, either through polling in the main loop or through the RTOS’s idle task queries to manage sleep entry and exit.
Reasonable task partitioning allows for sleep, and this negotiation mechanism can resolve the “sleep whenever possible” issue.
4.3 Task Waiting and Merging
During device operation, there will inevitably be timed wake-up tasks, with multiple timed tasks waking up randomly at any moment, leading to frequent exits from sleep. In this case, within the maximum allowable delay, multiple tasks can be executed all at once upon a single wake-up. For example, when going to the supermarket to buy groceries, it is better to buy everything needed for the day at once rather than going before each meal. In applications for 4G IoT products, for instance, if a device needs to send a TCP/IP heartbeat packet to the server every 3 minutes while a sensor collects data every 10 seconds, the data can be cached and sent together when the 3-minute timer overflows, reducing the number of wake-ups for the wireless network module.
4.4 Timely Loss Prevention
Due to different environments or peripheral combinations, it may be impossible to meet requirements during certain periods, or based on current information, it is highly likely that requirements cannot be met, or hardware parts may fail. When software detects such anomalies, it needs to promptly stop losses and reduce unnecessary consumption. For example, GNSS satellite positioning requires open areas to function; if the device activates GNSS but finds the signal weak, it can preliminarily determine that it is likely indoors, and even if it continues operating, it cannot locate. In this case, GNSS should be turned off immediately to save power; of course, the product needs to consider other operations that do not require positioning. Similarly, if communication confirms that a peripheral is absent or damaged, there is no need to continue powering it for periodic interaction; an exception alert can be issued instead.
4.5 Demand Level
When defining requirements, fully consider the start and end requirements of a task or peripheral to avoid long periods of ineffective work. For instance, one can use an accelerometer to determine whether the device is in motion before starting monitoring, or use infrared or sound control to determine if someone is approaching before activating work. These are all combinations defined at the product requirement level, ensuring that work is only activated when requirements are met and entering sleep mode promptly when unmet, though this may increase hardware costs. Some devices might also consider adding solar panels to save energy.
For software design patterns, you can refer to Embedded Software Design Patterns (Part 1) and Embedded Software Design Patterns (Part 2).
5 To Do a Good Job, One Must First Sharpen Their Tools
Before practicing low-power system design, it is essential to have an effective means to detect or observe the current working mode of the system, to intuitively know when the system is working, when it is sleeping, the duration of work, and the duration of sleep. A high-precision ammeter is indispensable, and if it can log current-time curves, that would be even better. Based on the current curve, targeted optimization of the software process or timing parameters can be made, or follow the WeChat public account [Embedded Systems].