技术标签: Linux驱动总结 手机充电总结 Android总结 MTK平台驱动学习
转自:http://blog.csdn.NET/baidu_34021173/article/details/51105223
主要涉及代码:
Kernel:
kernel-3.10\drivers\power\mediatek\
kernel-3.10\drivers\misc\mediatek\mach\mt6580\<project_name>\power\
MTK Battery框架结构图
通过上层通过读取创建一系列的设备节点获取电池相关的状态信息
Android电源管理系统
/sys/class/power_supply/ac/online //AC 电源连接状态 交流电 即电源插座
/sys/class/power_supply/usb/online //USB电源连接状态
/sys/class/power_supply/battery/status //充电状态
/sys/class/power_supply/battery/health //电池状态
/sys/class/power_supply/battery/present //使用状态
/sys/class/power_supply/battery/capacity //电池 level
/sys/class/power_supply/battery/batt_vol //电池电压
/sys/class/power_supply/battery/batt_temp //电池温度
/sys/class/power_supply/battery/technology //电池技术
代码框架:
battery_common.c
在Battery驱动模块中,battery_probe函数中会创建一些设备节点,并且运行一个线程bat_thread_kthread获取电池相关的数据信息
battery_kthread_hrtimer_init();//检测电池插入/拔出
kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread");
在bat_thread_kthread线程中
在这个线程中,每隔10s会去调用函数BAT_Thread去获取电池数据
BAT_Thread
battery_meter_get_battery_percentage:
oam_run:
MTK采用的Fuel方案获取剩余电池电量
首先通过adc读取电池 Vbat脚的电压值,然后通过这个闭路电压值查找 R—Table (cust_battery_meter_table.h )获得当前电压和温度下的电池内阻值,然后通过递归回溯的方法得到开路电压 OCV,然后通过这个OCV电压值查找 放电深度表获取当前的放电深度,从而算出剩余的电池电量。
调试驱动时应注意的一些关键点
1、电池曲线
2、充电电流的一些设置(AC_CHARGER_CURRENT,NON_STD_AC_CHARGER_CURRENT,USB_CHARGER_CURRENT等),是否是高压电池HIGH_BATTERY_VOLTAGE_SUPPORT
最高温度: MAX_CHARGE_TEMPERATURE
最高电压: V_CHARGER_MAX
截止满充电流大小:CHARGING_FULL_CURRENT
充关机最大电池差异:CUST_POWERON_DELTA_CAPACITY_TOLRANCE(若小于这个值,则下一次开机用RTC里面存储的剩余电池电量值)
关机电压:SYSTEM_OFF_VOLTAGE
UI电量同步时间:SYNC_TO_REAL_TRACKING_TIME
电池充电驱动流程分析(battery_common.c):
/* Integrate with NVRAM */
ret = alloc_chrdev_region(&adc_cali_devno, 0, 1, ADC_CALI_DEVNAME);
//字符设备的注册,
register_chrdev_region(dev_t first,unsigned int count,char *name)
First :要分配的设备编号范围的初始值(次设备号常设为0);
Count:连续编号范围.
Name:编号相关联的设备名称. (/proc/devices);
动态分配:
Int alloc_chrdev_region(dev_t *dev,unsigned int firstminor,unsigned int count,char *name);
Firstminor : 通常为0;
*dev:存放返回的设备号;
Count:连续编号范围.
Name:编号相关联的设备名称. (/proc/devices);
adc_cali_cdev = cdev_alloc();
动态申请一个字符设备的内存
adc_cali_cdev->owner = THIS_MODULE;
adc_cali_cdev->ops = &adc_cali_fops;
ret = cdev_add(adc_cali_cdev, adc_cali_devno, 1)//adc_cali_devno:设备号,前20位是主设备好,后12位此设备号 adc_cali_cdev:设备的结构体
adc_cali_major = MAJOR(adc_cali_devno); //获取主设备号
adc_cali_class = class_create(THIS_MODULE, ADC_CALI_DEVNAME);, 1);
class_dev = (struct class_device *)device_create(adc_cali_class,
NULL,
adc_cali_devno, NULL, ADC_CALI_DEVNAME);
get_charging_control();
battery_charging_control = chr_control_interface;
status = charging_func[cmd](data);
static kal_uint32 (* const charging_func[CHARGING_CMD_NUMBER])(void *data)=
{
charging_hw_init
,charging_dump_register
,charging_enable
,charging_set_cv_voltage
,charging_get_current
,charging_set_current
......
}
/* Integrate with Android Battery Service */
ret = power_supply_register(&(dev->dev), &ac_main.psy);
BMT_status.bat_charging_state = CHR_PRE;
BMT_status.bat_in_recharging_state = KAL_FALSE;
BMT_status.bat_full = KAL_FALSE;
BMT_status.nPercent_ZCV = 0; 初始化状态
battery_kthread_hrtimer_init(); 定时器初始化
kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread"); 创建并让线程一直运行起来
/*LOG System Set */
init_proc_log();
bat_thread_kthread:
{
wait_event(bat_thread_wq, (bat_thread_timeout == KAL_TRUE));
}
void BAT_thread(void)
{
static kal_bool battery_meter_initilized = KAL_FALSE;
if (battery_meter_initilized == KAL_FALSE) {
battery_meter_initial();/* move from battery_probe() to decrease booting time */
BMT_status.nPercent_ZCV = battery_meter_get_battery_nPercent_zcv();
battery_meter_initilized = KAL_TRUE;
}
mt_battery_charger_detect_check();
mt_battery_GetBatteryData();
if (BMT_status.charger_exist == KAL_TRUE) {
check_battery_exist();
}
mt_battery_thermal_check();
mt_battery_notify_check();
if (BMT_status.charger_exist == KAL_TRUE) {
mt_battery_CheckBatteryStatus(); //检查充电状态,选择CC_PRE开始,或其他非正常状态,
mt_battery_charging_algorithm(); //真正的充电开始,如果一直在CC_PRE状态,则会反复判断是否达到
进入CC状态的条件,以此类推,状态这样切换
}
mt_battery_update_status();
mt_kpoc_power_off_check();
}
1. 在线思维导图https://www.processon.com/
构造方法:构造方法没有 返回值类型方法名必须和类名相同(一个类中要想用多个构造方法只能用重载) 构造方法不允许手工调用,在对象构造过程中自动调用1次;(好比人类中的剪脐带,只在出生的时候剪一次)作用:给实例中的对象赋值;在现实生活中,很多事物一出现,就天生具有某些属性和行为。比如人一出生,就有年龄、身高、体重、就会哭;汽车一出产,就有颜色、有外观、可以运行等。这些,...
tapestry如何携带两个参数啊,晕比如是一个参数的,如果还想在添加一个参数该怎样处理啊?
java.util.concurrent.Executor, java.util.concurrent.ExecutorService, java.util.concurrent. Executors 这三者均是 Java Executor 框架的一部分,用来提供线程池的功能。因为创建和管理线程非常心累,并且操作系统通常对线程数有限制,所以建议使用线程池来并发执行任务,而不是每次请求进来时创建
一,场景:用户登录时需要输入验证码登录,如何实现用户通过验证码登录二,实现逻辑1,进入登录页面时,调用生成验证码接口,入参:当前时间戳(前端传入)2,后台调用生成验证码接口,生成验证码,并以入参时间戳为 key,验证码为value,保存在redis,并设置有效时间为1分钟,超时需要重新输入3,用户输入验证码,调用后台登录接口,入参:用户名,密码,验证码,key4,登录时校验,比...
//// main.m// 定义一个类//// Created by admin on 15/7/22.// Copyright (c) 2015年 admin. All rights reserved.//#import /* 1. 定义一个类有三部分: 类名 要求:> 类名的首字母 必须 大写
有时候需要用代码控制外部APP的一些操作,比如点击注册或者其他,这就需要用findwinow去抓取界面的句柄等,或者用mouse_event直接点击屏幕的某些位置。首先,引用命名空间及调用dllusing System.Runtime.InteropServices;[DllImport("user32.dll")]static extern IntPtr FindWindow(string lpClassName, string lpWindowName);[DllImport("user32.
关于serveletContext.getRealPath()方法from http://www.java3z.com/cwbwebhome/article/article2/210218.html1.关于request.getRealPath问题:String filename=request.getRealPath(filename)------------------
一般用户登录svn并记住用户密码后,下次再登录的时候将不需要输入用户密码,导致电脑使用着登录的时候,不知道到底登录的是个用户,只能将数据清除1.项目文件夹清除:直接查看项目当中的隐藏文件夹,找到.svn这个文件删除即可2.编译器中(这里以idea为例):重启Idea,然后点击SVN就可以看到需要重新输入帐号密码了想查看svn的账号密码:svn登录用户的文件,存放位置:C:\Users...
问题背景项目使用了shiro 过滤器拦截请求,做一些限流,鉴权,白名单限制的事情,可是最近在上线一个新功能时,新增了一个拦截路径,上线后,发现部分设置了拦截的路径失效,导致项目回滚问题定位之前在本地开发环境出现过类似问题,怀疑是正则表达式覆盖或者是拦截器排序规则导致,可是查了一堆网上资料,均没有类似情况,加之是本地环境问题,也就草草了之了。今天在线上环境碰到就不得不去查明原因,彻底解决。这...
今天在STARTUP一数据库时,发生如下错误:SQL> conn /as sysdbaConnected to an idle instance.SQL> startuporacle instance started.Total System Global Area 276824064 bytesFixed Size 778736 bytesVariable Size
SSH和SSM的区别加粗样式SSH是Spring+Struts2+Hibernate是目前较流行的一种Web应用程序开源集成框架。SSM是Spring+SpringMVC+MyBatis常作为数据源较简单的web项目的框架。Spring的核心功能加粗样式控制反转(IOC) & 依赖注入(DI)控制反转(IOC)SpringMVC的概念加粗样式SpringMVC是Spring生态圈中的WEB-MVC框架Hibernate加粗样式是一个开放源代码的对象关系映射框架,程序员可以更加轻松的操