Android Battery Management System
1. Overview
With the rapid development of mobile smart devices, the battery endurance has greatly induced the purchase choices of consumers, the rationality of the Power Management in the android system directly affects the battery endurance, it is mainly used to monitor the battery status (battery power, battery status and battery temperature ). The following describes the android battery system architecture in detail.
2. Android battery system architecture
In the Android system, the management driver layer of the battery inherits the power supply class in linux, while in the user layer, it is in BatteryService. in java, the following battery-related attributes are reported to upper-layer apps through broadcast. These attributes are declared in java and updated in jni.
These attributes are all updated in the local code com_android_server_BatteryService.cpp-jni by calling the sys File System to access the corresponding status of the battery in the driver layer.
3. BatteryService
Code path:
Frameworks/base/services/java/com/android/server/BatteryService. java
BatteryService is a battery and charging service. It monitors uevents, reads the status in sysfs, and broadcasts Intent. ACTION_BATTERY_CHANGED.
3.1 listening UEvent:
BatteryService implements two UEvenObserver mUEventObserver (as shown in the above Code ). Uevent is a mechanism used by the Linux kernel to actively report events to the user space. For JAVA programs, it only implements the virtual function onUEvent of UEventObserver and then registers it.
3.2 read sysfs Battery status
Update reads the sysfs file to obtain battery information synchronously, updates the BatteryService member variables based on the read status, and broadcasts an Intent to notify other components that focus on the Power status. When the kernel has power_supply event reporting, the mUEventObserver calls the update () function, and then the update calls native_update to read the relevant status from sysfs (com_android_server_BatteryService.cpp ).
3.3 broadcast Intent. ACTION_BATTERY_CHANGED
Broadcast Intent. ACTION_BATTERY_CHANGED: Package battery properties such as battery status, battery power, battery process, and send them to other users. That is to say, you only need to listen to Intent in the app. ACTION_BATTERY_CHANGED broadcast, you can get various battery status attributes!
4. Local Code-jni
Code path:
Frameworks/base/services/jni/com_android_server_BatteryService.cpp
This is the local code of the battery user space. It calls the sys File System to access the driver and encapsulates local methods in the upper layer of BatteryService to isolate platform-based differences.
The header of this file is defined as follows:
This is the sys File System Path generated by the underlying battery driver.
This file encapsulates a local method:
For upper-layer BatteryService. In addition, you can use GetFieldID in this file to obtain the BatteryService. java class's batterattribute ID, as shown below:
I will not complain about the interaction between java and c/c ++. There is a lot of information on the Internet.
In this file, you can operate the corresponding sys File System to obtain various attribute values of the battery. See the following code:
POWER_SUPPLY_PATH has been defined in the file header, corresponding path:/sys/class/power_supply, then traverse the entire folder to find various properties of each energy supply device, the selected part is used to find the attributes of the communication device.
The attributes of various energy devices are as follows:
/Sys/class/power_supply/ac/online AC power supply connection status
/Sys/class/power_supply/usb/online USB Power Supply Connection status
/Sys/class/power_supply/battery/status charging status
/Sys/class/power_supply/battery/health battery status
/Sys/class/power_supply/battery/present usage status
/Sys/class/power_supply/battery/capacity battery level
/Sys/class/power_supply/battery/batt_vol battery voltage
/Sys/class/power_supply/battery/batt_temp battery temperature
/Sys/class/power_supply/battery/technology battery technology
When the status of the power supply device changes, the driver updates these files and sends information to the java layer through the local method android_server_BatteryService_update in jni.
5. Driver 5.1. Driver Overview
The driver of the android system Battery inherits the Power Supply driver architecture in the traditional linux system. The Battery driver generates the corresponding sys File System through the Power Supply driver, this provides interfaces for various battery attributes to the user space. The file system path used by the Linux Standard Power Supply driver is/sys/class/power_supply. Each subdirectory represents an energy Supply device.
5.2 Driver header file
The header file of the Power Supply driver is kernel/include/linux/power_supply.h. The functions for registering and logging out the driver are as follows:
Intpower_supply_register (struct device * parent, struct power_supply * psy );
Voidpower_supply_unregister (struct power_supply * psy );
Structpower_supply {
Constchar * name;/* device name */
Enumpower_supply_type;/* type */
Enumpower_supply_property * properties;/* Property pointer */
Size_tnum_properties;/* Number of attributes */
Char ** supplied_to;
Size_tnum_supplicants;
Int (* get_property) (struct power_supply * psy,/* Get attribute */
Enumpower_supply_property psp,
Unionpower_supply_propval * val );
Void (* external_power_changed) (struct power_supply * psy );
/* Some content is omitted */
};
5.3. power supply core
Corresponding DRIVER: power_supply
Let's take a look at the power_supply_sysfs.c file. Here we mainly create uevent for the following power supply device properties!
These uevent nodes may not be created. Whether or not the node is created depends on the num_properties passed in by the specific power device driver and properties. You can easily see this in the create uevent function power_supply_uevent:
5.4. battery driver
The current battery detection and management methods used in the project (T808 and T828) are poc adc. The corresponding driver files are:
Mediatek/kernel/drivers/power/battery_common.c
The probe function in this file contains the following content:
We can see that the ac, usb, and battery power supply devices are registered to the power supply core, and the corresponding global struct variables ac_main, usb_main, and battery_main are defined as follows:
The uevent nodes to be created for each power supply device are determined by the xx_props passed in here. The corresponding definitions are as follows:
It can be found that only one online attribute is created for ac and usb, and the upper-layer app can know which device is charging the current system by judging the online status of ac and usb; battery creates many battery-related attributes, such as status, health, present, capacity, and batt_vol, the upper-layer app can monitor the current operating status of the battery by using these battery properties uevent.
An example shows how to send an update message to the system after the status of these attributes changes.
This function is called when show property is displayed in power supply sysfs, and the unique attribute of AC_ONLINE as ac power is updated in ac_update:
Ac_update will eventually perform a round robin in bat_thread_kthread. Here there is a global BMT_status, which is used as the attributes of the entire power supply device! In addition, let's take a look at the global function pointer CHARGING_CONTROL battery_charging_control. The prototype is defined as follows:
The following is a prototype of the chr_control_interface function:
Corresponding file path:
Mediatek/platform/mt6572/kernel/drivers/power/charging_hw_pmic.c
The charging_func function pointer array is defined as follows:
We can see the following call relationship:
It will eventually be called:
The enumerated types correspond to one-to-one functions. For example, if CHARGING_CMD_GET_CHARGER_TYPE is called above, charger type is obtained. The function prototype is as follows:
Here, the pmic hardware status is used to obtain the corresponding information.
5.5 charging Error Correction
The ideal battery has no internal resistance, and the battery voltage is consumed by external loads.
However, this is not the case. Because of the internal resistance of the battery, the battery power obtained by directly measuring the battery voltage (ADC) may have certain errors, whether the battery is in the power supply or discharge status, this error exists, especially when the battery is full, the battery is empty, and the battery is powered off, this will bring about poor user experience.
The error caused by the internal resistance of the battery can be corrected in mathematics.
It can be seen that, as long as the internal resistance of the battery is known, this error can be easily corrected. However, the internal resistance of the battery is not the same, but changes with the change of battery power. Different battery models have different features, so you need to get a more accurate battery power, it is necessary for the battery plant to provide a complete set of relationship between the battery voltage and the internal resistance of the battery!
Error Correction Code during charge/discharge:
Mediatek/kernel/drivers/power/battery_meter.c
The following code is available in oam_run:
The mtk_imp_tracking function is an △v correction for the pressure drop caused by the internal resistance of the battery during the charging and discharging process.
In addition, due to the battery characteristics, the power may jump during power-on and power-off. In the system, the UI power during power-off is saved to RTC, during the next boot process, compare the detected electrical value with the UI electrical value saved to RTC, because the user may change the battery, the difference between the two is controlled within the range of 20%, that is:The actual detected electrical value is within the 20% range of the UI electrical value saved in RTC, And the UI electrical value saved in RTC is used as the electrical value of the current battery; if the detected electrical value exceeds 20% of the UI electrical value in RTC, the user is deemed to have replaced the battery, and the detected electrical value is used as the electrical value of the current battery..
The corresponding judgment code is as follows:
In the header file:
Mediate/custiom/mt6572/kernel/battery/cust_battery_meter.h
Has the following definitions
6. Write it at the end
The battery power detection algorithm is described in detail in the mtmer_training_battery_charginghistory file of mtk6.