热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Android实现电池管理系统

这篇文章主要为大家详细介绍了Android实现电池管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一、Android 电池服务

Android电池服务,用来监听内核上报的电池事件,并将最新的电池数据上报给系统,系统收到新数据后会去更新电池显示状态、剩余电量等信息。如果收到过温报警和低电报警,系统会自动触发关机流程,保护电池和机器不受到危害。

Android电池服务的启动和运行流程:

Android

电池服务的源码结构

 Framework\base\services\java\com\android\server
        ├── SystemServer.java
                 创建BatteryServices、PowerManagerService、ActivityManagerService
        ├── BatterySevices.java
                 监听底层上报的battery事件,广播电池发生改变的消息
         Framework\base\services\java\com\android\server\am
        ├── ActivityManagerService.java
                 创建BatteryStatsService
        ├── BatteryStatsService.java
                 统计和记录电池参数的信息
         Framework\base\services\java\com\android\server\power
        ├── PowerManagerService.java
                 监听电池发生变化的广播消息,并调节系统的电源状态,例如亮屏
         Framework\base\core\java\com\internal\os\
        ├── BatteryStatsImpl.java
                 统计和记录电池参数的信息,并通知其他模块
         System\core\healthd
        ├── healthd.cpp
                 创建uevent socket,监听内核上报的内核事件
        ├── BatteryMonitor.cpp
                 初始化本地电池数据结构,将power_supply路径下属性节点路径填充进去,
        ├── BatteryMonitor.h
        ├── BatteryPropertiesRegistrar.cpp
                 创建电池属性监听器,并将其注册到Android的系统服务中
        ├── BatteryPropertiesRegistrar.h

二、Healthd

该模型向下监听来自底层的电池事件,向上传递电池数据信息给Framework层的BatteryService用来计算电池电量相关信息,
BatteryService通过传递来的数据来计算电池电量等信息,因此healthd在电池管理系统中起着承上启下的作用。

healthd的具体调用流程深入分析android5.1 healthd这篇文章讲得很清楚。

三、驱动

Android电源管理底层用的是Linux
 power_supply框架,内核提供给电池驱动的接口是结构体power_supply结构体。

struct power_supply { 
 const char *name; 
 enum power_supply_type type; 
 enum power_supply_property *properties; 
 size_t num_properties; 
 
 char **supplied_to; 
 size_t num_supplicants; 
 
 int (*get_property)(struct power_supply *psy, 
  enum power_supply_property psp, 
  union power_supply_propval *val); 
 int (*set_property)(struct power_supply *psy, 
  enum power_supply_property psp, 
  const union power_supply_propval *val); 
 int (*property_is_writeable)(struct power_supply *psy, 
   enum power_supply_property psp); 
 void (*external_power_changed)(struct power_supply *psy); 
 void (*set_charged)(struct power_supply *psy); 
 
 /* For APM emulation, think legacy userspace. */ 
 int use_for_apm; 
 
 /* Driver private data */ 
 void *drv_data;//add by bhj 
 
 /* private */ 
 struct device *dev; 
 struct work_struct changed_work; 
 spinlock_t changed_lock; 
 bool changed; 
 struct wake_lock work_wake_lock; 
 struct delayed_work deferred_register_work; 
 
#ifdef CONFIG_LEDS_TRIGGERS 
 struct led_trigger *charging_full_trig; 
 char *charging_full_trig_name; 
 struct led_trigger *charging_trig; 
 char *charging_trig_name; 
 struct led_trigger *full_trig; 
 char *full_trig_name; 
 struct led_trigger *online_trig; 
 char *online_trig_name; 
 struct led_trigger *charging_blink_full_solid_trig; 
 char *charging_blink_full_solid_trig_name; 
#endif 
};

内核主要通过get_property这个函数指针来获得驱动中的有关电池的信息,而这个函数在内核中只给出了声明,我们在写驱动的时候要自己实现这个函数,即将自己写的函数赋值给这个函数指针,当内核需要驱动中电源信息的时候就回调这个get_property函数。另外,我们写驱动程序的时候又要给用户提供接口,内核中提供给用户的接口就是sysfs,通过读取sysfs文件系统中文件内容,就可以得到电源的信息。内核主要通过两个文件power_supply_class.c和power_supply_core.c,我们调用其中的函数就可以把电源(电池,USB或AC)的信息展现给用户,有关电源的属性写在/sys/class/powersupply文件夹下(此文件夹为程序运行后所生成的)。

电池系统从底层向Framework层上报数据的流程:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 本文主要讨论了在xps15上安装双系统win10和MacOS后,win10无法正常更新的问题。分析了可能的引导问题,并提供了解决方法。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 树莓派Linux基础(一):查看文件系统的命令行操作
    本文介绍了在树莓派上通过SSH服务使用命令行查看文件系统的操作,包括cd命令用于变更目录、pwd命令用于显示当前目录位置、ls命令用于显示文件和目录列表。详细讲解了这些命令的使用方法和注意事项。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
author-avatar
老谢2502887117
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有