MTK/Android 充电逻辑

本文深入探讨了Android设备中电池管理系统的实现原理和技术细节。从Healthd守护进程如何收集电池信息开始,介绍了它与BatteryService之间的交互过程。进一步分析了BatteryService的启动流程及其如何响应电池状态的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

加量不加价,更新来一波

整体框图

不记得从哪保存的好图了
在这里插入图片描述

硬件/内核相关

相关概念

懒的排版了,直接上图
这里写图片描述

相关文件关系

再来一发
这里写图片描述

杂项,电池温度检测原理图


这里写图片描述

充电流程

图样图森破
这里写图片描述

核心函数特写

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

Android 相关

Healthd 就是一個 daemon service,取代以前的 battery JNI ,
1.定期讀取 sys/class/power_supply 的檔案, 包含所有關於電池的必要資訊(電壓, 電流, 溫度,狀態 etc)
2.將上述讀取的資訊寫入至 battery property, 讓 android battery Service update

Healthd 启动流程

// system\core\rootdir\init.rc
service healthd /sbin/healthd
    class core
    critical
    seclabel u:r:healthd:s0
    group root system wakelock
    

// 对应的代码路径为:
// Healthd.cpp (system\core\healthd)
int main(int argc, char **argv)
		//////////////////////////////////////////////////////////////////////////////
		// 1. 根据不同的启动模式,设置 healthd_mode_ops 为不同的操作函数集
		//      当开机充电时变量赋值为 &android_ops,关机充电时候变量赋值为 &charger_ops
		//healthd_mode_ops = &android_ops;
		//
		// 2.用 epoll 监听了:
		//      1. Binder 通信事件
		//      2. 定时器事件 
		//      3. Netlink 实现的 uevent 事件
		// 然后遍历 /sys/class/power_supply/ 下的结点,设置全局变量 healthd_config
		//ret = healthd_init();
		//    // 创建了一个 epoll 轮询象
		//    epollfd = epoll_create(MAX_EPOLL_EVENTS);
		//    // 这里就开机充电的情况下分析,调用 android_ops->init()
		//    // 主要是进行了 Binder 相关初始化,并注册了一个服务 "batteryproperties"
		//    // 到 servicemanager 中进行管理
		//    healthd_mode_ops->init(&healthd_config);
		//
		//    // 主要是创建了一个定时器,24小时执行一次?
		//    wakealarm_init();
		//
		//    // 用 epoll 监听 netlink 上报的 uevent 事件        
		//    uevent_init();
		//
		//    // 创建 BatteryMonitor 的对象,并将其初始化。BatteryMonitor 
		//    // 主要接受 healthd 传来的数据,做电池状态的计算并更新       
		//    gBatteryMonitor = new BatteryMonitor();
		//
		//    // 主要是根据路径下节点设置全局变量 healthd_config
		//    //   POWER_SUPPLY_SYSFS_PATH 定义为 "/sys/class/power_supply",
		//    //   在 init 函数中打开系统该文件夹,然后一一读取该文件夹下的文
		//    //   件内容,在 while 循环中判断该文件夹下各个文件节点的内容,
		//    //   并将其初始化给相关的参数
		//    gBatteryMonitor->init(&healthd_config);
		//
		//
		// 3. 死循环,
		//    监听 epoll 事件,并调用相应的回调函数进行处理:
		//      1> uevent_event() 处理内核 Netlink 上报的数据 
		//              // 当 sys 属性变化时,写入 log, 通知监听者
		//      2> wakealarm_event(): 处理定时器唤醒
		//      3> binder_event(): 处理 Binder 通信
		//    如果没有事件,则根据 sys 属性变化,写入 log, 通知监听者 BatteryPropertiesRegistrar::notifyListeners() 
		//healthd_mainloop();

BatteryService

接口:frameworks\base\core\java\com\android\internal\app\IBatteryStats.aidl

【初始化流程】

zygote
	SystemServer
		// 入口函数
		main(String[] args) 
			new SystemServer().run();
				startBootstrapServices();
				startCoreServices();
					mSystemServiceManager.startService(BatteryService.class);
							////////////////////////////////////////////////////////////////////////////
							// frameworks\base\services\core\java\com\android\server\SystemServiceManager.java
							// 创建一个继承 SystemService 的子类 
							public <T extends SystemService> T startService(Class<T> serviceClass)
											// 获得 Class 名称
											final String name = serviceClass.getName();
											// 获得构造函数: public BatteryService(Context context) 
											Constructor<T> constructor = serviceClass.getConstructor(Context.class);
											// 调用构造函数,创建类对象
											service = constructor.newInstance(mContext);
                                                        ///////////////////////////////////////////////////////////////
														// frameworks\base\services\core\java\com\android\server\BatteryService.java
                                                        BatteryService::BatteryService()
                                                        	// LED 灯光显示
                                                        	mLed = new Led(context, getLocalService(LightsManager.class));
															// 相关警告电量配置

											// 添加到链表中进行管理                                            
											mServices.add(service);
											// 启动服务 
											service.onStart();
														// frameworks\base\services\core\java\com\android\server\BatteryService.java
														public void onStart()
																// 1. 首先将电池监听注册到底层去, 底层电量变化,会【调用 update()】
																IBinder b = ServiceManager.getService("batteryproperties");
																final IBatteryPropertiesRegistrar batteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);
																//电池监听,注册到底层。当底层电量改变会调用此监听。然后执行 update 
																batteryPropertiesRegistrar.registerListener(new BatteryListener());

																///////////////////////////////////////////////////////////
																// 2. 如果是 IPO 开关机的话,需要监听广播
																if (SystemProperties.get("ro.mtk_ipo_support").equals("1")) 。。。

																// 3. 将本地接口 publish 出去,                                                                
																// 创建一个内部类 BinderService 对象 
																mBinderService = new BinderService();

底层电量更新流程

// 当底层电池状态更新时,healthd 会回调 BatteryPropertiesRegistrar::notifyListeners()    
// 而此类是通过 Binder 通信注册了回调的,当有事件时会调用回调 update():
//      IBinder b = ServiceManager.getService("batteryproperties");     // BatteryPropertiesRegistrar.cpp  注册的
//      final IBatteryPropertiesRegistrar batteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);     
//      batteryPropertiesRegistrar.registerListener(new BatteryListener());                                                                          
private final class BatteryListener extends IBatteryPropertiesListener.Stub 
	BatteryService.this.update(props);
		processValuesLocked(false);
			// //解析充电类型  
			if (mBatteryProps.chargerAcOnline) 。。。
			// 充电指示灯更新
			mLed.updateLightsLocked();
			// 没电了
			shutdownIfNoPowerLocked();
			// 温度过高  
			shutdownIfOverTempLocked();
			// 发送电池状态变化的广播
			sendIntentLocked();

#什么!还要了解?请看源码
地址:链接: http://pan.baidu.com/s/1kV3DKNX 密码: uiyb

### Android MTK 平台关机充电流程解析 #### 1. 关机充电背景 在Android设备中,特别是在MTK平台上,当设备处于关机状态并连接到电源适配器时,系统会进入一种特殊的模式——关机充电模式。这种模式允许电池在不启动操作系统的情况下完成快速充电过程[^3]。 #### 2. PowerManagerService 的角色 `PowerManagerService.java` 是 Android 系统框架中的核心服务之一,负责管理设备的电源状态和唤醒锁等功能。对于关机充电场景而言,该文件定义了一些关键逻辑用于处理设备从正常运行切换至关机以及后续的充电行为[^1]。 以下是 `PowerManagerService` 中可能涉及的关键方法片段: ```java private void handleShutdown() { // 处理关机请求的具体逻辑 if (mShuttingDown) { nativeHandleShutdown(); // 调用本地接口执行实际操作 } } ``` 上述代码展示了如何通过调用原生函数来触发硬件级别的关机动作。此阶段完成后,设备将完全断电,并等待外部条件满足后再重新激活某些模块以支持关机充电功能。 #### 3. 内核重启机制 一旦设备正式进入关机序列,Linux内核层面也会参与其中。具体来说,`do_kernel_restart()` 函数被用来通知所有注册过的重启处理器准备行动。这些处理器通常由驱动程序提供,它们各自承担不同的职责,比如保存当前上下文或者配置特定寄存器以便于之后恢复工作环境[^2]。 下面是一个简化版的例子展示这一过程的一部分实现细节: ```c void do_kernel_restart(char *cmd) { atomic_notifier_call_chain(&restart_handler_list, reboot_mode, cmd); } ``` 这里利用了原子通知链表结构 (`atomic_notifier_call_chain`) 来遍历所有的回调函数实例列表(`&restart_handler_list`) ,从而确保每一个必要的组件都能得到适当的通知去响应即将发生的改变 —— 即系统的彻底关闭或者是转换成备用模式如shutdown charging mode . #### 4. 低电量自动关机阈值设定 针对不同型号的产品设计需求,制造商往往希望自定义设置较低水平下的剩余容量百分比作为强制切断供电的标准。例如,在版本号为9.0及以上的新一代安卓智能手机里,默认情况下如果检测到低于某个预定比例(比如说百分之二),则立即实施紧急停运措施以防过度耗尽锂电池单元内部储存的能量储备造成永久损害等问题发生[^4]。 为此目的所作的主要改动集中在以下几个方面: - **核心类别位置**: 文件路径位于 `frameworks\base\services\core\java\com\android\server\BatteryService.java`. - **主要功能描述**: 修改现有算法使得能够识别新的临界点数值并且依据它做出相应的决策反应. #### 结论 综上所述,我们可以看到整个 android mtk shutdown charging process 不仅涉及到高层级的应用层面上的服务控制,同时也深入到了中间件乃至最底层的操作系统内核部分。只有全面理解各个层次之间的相互作用关系才能真正掌握其全貌并有效解决可能出现的各种复杂状况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值