android 电池.docx
《android 电池.docx》由会员分享,可在线阅读,更多相关《android 电池.docx(32页珍藏版)》请在冰豆网上搜索。
android电池
android电池
(一):
锂电池基本原理篇
关键词:
android 电池关机充电 androidboot.modecharger
平台信息:
内核:
linux2.6/linux3.0
系统:
android/android4.0
平台:
S5PV310(samsungexynos4210)
电池在电子产品中所占的地位就不用说了。
不过电池在物理接口上比较简单,就两条线:
正极、负极,这个小学生科普知识都知道;不过真正用到电子产品中时,有关电池方面的东西还是有点多的。
从三个方面介绍:
电池的基本原理;
Android关机充电流程,充电logo是怎么显示的;
Android开机充电流程,电池电量、低电信息是怎么处理的;
电池充电最重要的就是这三步:
第一步:
判断电压<3V,要先进行预充电,0.05C电流;
第二步:
判断 3V<电压<4.2V,恒流充电0.2C~1C电流;
第三步:
判断电压>4.2V,恒压充电,电压为4.20V,电流随电压的增加而减少,直到充满。
一、锂电池
1、简述锂电池以及工作原理
锂离子电池自1990年问世以来,因其卓越的性能得到了迅猛的发展,并广泛地应用于社会。
锂离子电池以其它电池所不可比拟的优势迅速占领了许多领域,象大家熟知的移动电话、笔记本电脑、小型摄像机等等。
目前锂电池公认的基本原理是所谓的“摇椅理论”。
锂电池的冲放电不是通过传统的方式实现电子的转移,而是通过锂离子在层壮物质的晶体中的出入,发生能量变化。
在正常冲放电情况下,锂离子的出入一般只引起层间距的变化,而不会引起晶体结构的破坏,因此从冲放电反映来讲,锂离子电池是一种理想的可逆电池。
在冲放电时锂离子在电池正负极往返出入,正像摇椅一样在正负极间摇来摇去,故有人将锂离子电池形象称为摇椅电池。
我们经常说的锂离子电池的优越性是针对于传统的镍镉电池(Ni/Cd)和镍氢电池(Ni/MH)来讲的。
具有工作电压高比能量大循环寿命长自放电率低无记忆效应等优点。
2、锂电池日常使用过程中的常识
(1)、误区:
“电池激活,前三次充电12小时以上”
对于锂电池的“激活”问题,众多的说法是:
充电时间一定要超过12小时,反复做三次,以便激活电池。
这种“前三次充电要充12小时以上”的说法,明显是从镍电池(如镍镉和镍氢)延续下来的说法。
所以这种说法,可以说一开始就是误传。
经过抽样调查,可以看出有相当一部分人混淆了两种电池的充电方法。
锂电池和镍电池的充放电特性有非常大的区别,所查阅过的所有严肃的正式技术资料都强调过充和过放电会对锂电池、特别是液体锂离子电池造成巨大的伤害。
因而充电最好按照标准时间和标准方法充电,特别是不要进行超过12个小时的超长充电。
通常,手机说明书上介绍的充电方法,就是适合该手机的标准充电方法。
(2)、不益长时间充电、电池完全用完再充电
锂电池的手机或充电器在电池充满后都会自动停充,并不存在镍电充电器所谓的持续10几小时的“涓流”充电。
如果锂电池在充满后,放在充电器上也是也不再充电。
超常时间充电和完全用空电量会造成过度充电和过度放电,将对锂离子电池的正负极造成永久的损坏,从分子层面看,过度放电将导致负极碳过度释出锂离子而使得其片层结构出现塌陷,过度充电将把太多的锂离子硬塞进负极碳结构里去,而使得其中一些锂离子再也无法释放出来。
(3)、电池寿命
关于锂离子电池充放电循环的实验表,关于循环寿命的数据列出如下(DOD是放电深度的英文缩写):
循环寿命(10%DOD):
>1000次
循环寿命(100%DOD):
>200次
从上面数据可见,可充电次数和放电深度有关,10%DOD时的循环寿命要比100%DOD的要长很多。
当然如果折合到实际充电的相对总容量10%*1000=100,100%*200=200,后者的完全充放电还是要比较好一些。
但是锂电池的寿命主要体现在充放电周期上,这个周期是一个绝对概念,上次使用了30%电力,充满电,下次又使用了70%的电力,又充满电,这个刚好是一个充电周期。
所以还是遵循锂电池发明者的口号“即用即充,即充即用”的方法使用锂电池。
(4)、定期深度充放电进行 电池校准
锂离子电池一般都带有管理芯片和充电控制芯片。
其中管理芯片中有一系列的寄存器,存有容量、温度、ID、充电状态、放电次数等数值。
这些数值在使用中会逐渐变化。
使用说明中的“使用一个月左右应该全充放一次”的做法主要的作用应该就是修正这些寄存器里不当的值。
二、锂电池的充电方式是限压横流方式
主要分三步完成:
第一步:
判断电压<3V ,要先进行预充电,0.05C电流;
第二步:
判断 3V<电压<4.2V,恒流充电0.2C~1C电流;
第三步:
判断电压>4.2V,恒压充电,电压为4.20V,电流随电压的增加而减少,直到充满。
其实今天我就是这一点有些不懂,在网上查了一下,然后上面那些做为常识了解。
充电开始时,应先检测待充电电池的电压,如果电压低于3V,要先进行预充电,充电电流为设定电流的1/10,一般选0.05C左右。
电压升到3V后,进入标准充电过程。
标准充电过程为:
以设定电流进行恒流充电,电池电压升到4.20V时,改为恒压充电,保持充电电压为4.20V。
此时,充电电流逐渐下降,当电流下降至设定充电电流的1/10时,充电结束。
一般锂电池充电电流设定在0.2C至1C之间,电流越大,充电越快,同时电池发热也越大。
而且,过大的电流充电,容量不够满,因为电池内部的电化学反应需要时间。
就跟倒啤酒一样,倒太快的话会产生泡沫,反而不满。
术语解释:
充放电电流一般用C作参照,C是对应电池容量的数值。
电池容量一般用Ah、mAh表示,如M8的电池容量1200mAh,对应的C就是1200mA。
0.2C就等于240mA。
下面是锂电池典型充电曲线图:
三、锂电池的放电,对电池来说,正常使用就是放电过程
锂电池放电只需要注意很少的几点:
1、放电电流不能过大,过大的电流导致电池内部发热,有可能会造成永久性的损害;
2、绝对不能过放电!
锂电池最怕过放电,一旦放电电压低于2.7V,将可能导致电池报废。
下面是一般锂电池的典型放电曲线图:
从典型放电曲线图上可以看出,电池放电电流越大,放电容量越小,电压下降更快。
所以,一般情况下电池大负荷工作后,减少负荷会出现电压回升现象,就是所说的“回电”现象。
给个图看看,这个放电曲线图在放电过程中停了一下,出现了“回电”。
android电池
(二):
android关机充电流程、充电画面显示
关键词:
android 电池关机充电 androidboot.modecharger 关机充电充电画面显示
平台信息:
内核:
linux2.6/linux3.0
系统:
android/android4.0
平台:
S5PV310(samsungexynos4210)
电池的基本原理;
android关机充电流程、充电画面显示;
Android开机充电流程,电池电量、低电信息是怎么处理的;
上一篇我们讲了锂电池的充放电的流程和电池的一些特性,这一节我们重点说一下android关机充电是怎么、充电画面显示是怎么实现的,这个在工作中也比较有用,我们开始做这一块的时候也走了不少的弯路。
我记得我们做adnroid2.3的时候,关机状态和充电logo显示是在uboot中做的。
应该是有两种做法,回头我再看下uboot中做画面显示那一块是怎么做的,这一节我们重点说系统中的充电logo显示。
一、android正常开机流程、关机充电流程
在写这篇文章之前我们先看两个流程:
正常开机流程,关机充电系统启动流程
1、正常开机流程,按开机键。
可大致分成三部分
(1)、OS_level:
UBOOT、kenrel、init这三步完成系统启动;
(2)、Android_level:
这部分完成android部的初始化;
(3)、HomeScreen:
这部分就是我们看到的launcher部分。
2、关机充电系统启动流程
与前面相比,这个流程只走到init这一部分,就没有往后走了,这部分我们会在后面的代码中分析。
二、关机充电逻辑硬件逻辑
1、插入DC,chargerIC从硬件上唤醒系统,相当于长按开机键开机。
下面这部分是chargerIC连接系统的控制部分。
三、软件逻辑。
DC插入,其实相当于关机状态下“按开机键”开机。
第一步要走UBOOT、kernel、androidinit这一流程。
1、UBOOT
UBOOT启动代码我们不在这里详细分析,这里我们只要注意二个问题:
a:
如何判断是DC插入;
b:
设定setenv("bootargs","androidboot.mode=charger"),androidboot.mode这个参数相当重要,这个参数决定系统是正常启动、还是关机充电状态。
Uboot/board/samsung/smdk4212/smkd4212.c
[cpp] viewplaincopy
1.int board_late_init (void)
2.{
3. int keystate = 0;
4. printf("check start mode\n");
5. if ((*(int *)0x10020800==0x19721212) || (*(int *)0x10020804==0x19721212)
6.|| (*(int *)0x10020808==0x19721212)) //
(1)、检查是否有DC插入;
7.{
8. setenv ("bootargs", "");//
(2)、没有DC插入;
9. } else {//DC插入
10. int tmp=*(int *)0x11000c08;
11. *(int *)0x10020800=*(int *)0x10020804=0x19721212;
12. *(int *)0x11000c08=(tmp&(~0xc000))|0xc000;
13. udelay(10000);
14. if ((*(int *)0x11000c04 & 0x80)!
=0x80 && INF_REG4_REG !
= 0xf) {
15. setenv ("bootargs", "androidboot.mode=charger");//(3)、设定bootargs为charger状态
16. printf("charger mode\n");
17. } else {
18. setenv ("bootargs", "");
19. }
20. *(int *)0x11000c08=tmp;
21. }
22.#ifdef CONFIG_CPU_EXYNOS4X12
23. int charge_status=CheckBatteryLow();//(4)、检查电池电量;
24. keystate=board_key_check();//(5)、检查按键状态;
25. // fuse bootloader
26. if(second_boot_info !
= 0) {
27. boot_symbol=1;
28. INF_REG2_REG =0x8;
29. run_command(CONFIG_BOOTCMD_FUSE_BOOTLOADER, NULL);
30. }
31. if((INF_REG4_REG == 0xd)) {
32. // reboot default
33. char buf[10];
34. sprintf(buf, "%d", CONFIG_BOOTDELAY);
35. setenv ("bootdelay", buf);
36. setenv ("reserved", NULL);
37. saveenv();
38. } else if((INF_REG4_REG == 0xe) || keystate == (0x1 | 0x2)) {//(6)、按键进入fastboot模式;
39. // reboot bootloader
40. boot_symbol=1;
41. INF_REG2_REG =0x8;
42. printf("BOOTLOADER - FASTBOOT\n");
43. setenv ("reserved", "fastboot");
44. setenv ("bootdelay", "0");
45. } else if((INF_REG4_REG == 0xf) || keystate == (0x1 | 0x2 | 0x4)) {//(7)、按键进入recovery模式;
46. // reboot recovery
47. printf("BOOTLOADER - RECOVERY\n");
48. boot_symbol=1;
49. INF_REG2_REG =0x8;
50. setenv ("reserved", CONFIG_BOOTCMD_RECOVERY);
51. setenv ("bootdelay", "0");
52. } else
53. if(keystate == (0x1 | 0x4) || second_boot_info !
= 0 || partition_check()) {//(8)、按键进入卡升级模式;
54. // 2nd boot
55. printf("BOOTLOADER - 2ND BOOT DEVICE\n");
56. boot_symbol=1;
57. INF_REG2_REG =0x8;
58. setenv ("bootcmd", CONFIG_BOOTCOMMAND);
59. setenv ("reserved", CONFIG_BOOTCMD_FUSE_RELEASE);
60. setenv ("bootdelay", "0");
61. } else {//(9)、正常启动;
62. // normal case
63. char buf[10];
64. sprintf(buf, "%d", CONFIG_BOOTDELAY);
65. setenv ("bootdelay", buf);
66. }
67. INF_REG4_REG = 0;
68. return 0;
69.}
(1)、检查是否有DC插入;
[cpp] viewplaincopy
1.if ((*(int *)0x10020800==0x19721212) || (*(int *)0x10020804==0x19721212)
2. (*(int *)0x10020808==0x19721212))
这部分检查寄存器的值。
(2)、没有DC插入;
(3)、设定bootargs为charger状态
[cpp] viewplaincopy
1.if ((*(int *)0x11000c04 & 0x80)!
=0x80 && INF_REG4_REG !
= 0xf) {
2. setenv ("bootargs", "androidboot.mode=charger");
这是这部分的重点,如果能过寄存器判断是DC插入,把androidboot.mode设定为charger状态。
以下这部分根据需要加入,通过判断不同的情况进入不同的功能,如fastboot\revovery…………,这部分不做详细解释。
(4)、检查电池电量;
这个在正常开机状态下,如果检测电量太低,则不开机,这部分代码就不做分析。
(5)、检查按键状态;
我们这个平台有几种模式:
fastboot\recovery\卡升级等……
(6)、按键进入fastboot模式;
(7)、按键进入recovery模式;
(8)、按键进入卡升级模式
(9)、正常启动;
2、kernel
这部分和正常启动是一样的。
3、init
前面所有的描述其实只有一点和正常启动不太一样,那就是在UBOOT中把androidboot.mode设定为charger状态,内核正常流程启动,然后到init时要对charger这种状态处理。
system\core\init\init.c
[cpp] viewplaincopy
1.int main(int argc, char **argv)
2.{
3. ………………
4. action_for_each_trigger("early-init", action_add_queue_tail);
5.
6. queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
7. queue_builtin_action(property_init_action, "property_init");
8. queue_builtin_action(keychord_init_action, "keychord_init");
9. queue_builtin_action(console_init_action, "console_init"); //
(1)、显示initlogo.rle,也就是android第二张图片;
10. queue_builtin_action(set_init_properties_action, "set_init_properties");
11.
12. /* execute all the boot actions to get us started */
13. action_for_each_trigger("init", action_add_queue_tail);
14.
15. /* skip mounting filesystems in charger mode */
16. if (strcmp(bootmode, "charger") !
= 0) {//
(2)、这里就是UBOOT中设定的bootmode,如果是charger模式,跳过下面初始化;
17. action_for_each_trigger("early-fs", action_add_queue_tail);
18. action_for_each_trigger("fs", action_add_queue_tail);
19. action_for_each_trigger("post-fs", action_add_queue_tail);
20. action_for_each_trigger("post-fs-data", action_add_queue_tail);
21. }
22.
23. queue_builtin_action(property_service_init_action, "property_service_init");
24. queue_builtin_action(signal_init_action, "signal_init");
25. queue_builtin_action(check_startup_action, "check_startup");
26.
27. if (!
strcmp(bootmode, "charger")) {//(3)、如果为charger,则调用charger.c。
28. action_for_each_trigger("charger", action_add_queue_tail);
29. } else {
30. action_for_each_trigger("early-boot", action_add_queue_tail);
31. action_for_each_trigger("boot", action_add_queue_tail);
32. }
33.……………………
34.}
(1)、显示initlogo.rle,也就是android第二张图片;
queue_builtin_action(console_init_action,"console_init");调用console_init_action
[cpp] viewplaincopy
1.static int console_init_action(int nargs, char **args)
2.{
3. int fd;
4. char tmp[PROP_VALUE_MAX];
5. if (console[0]) {
6. snprintf(tmp, sizeof(tmp), "/dev/%s", console);
7. console_name = strdup(tmp);
8. }
9. fd = open(console_name, O_RDWR);
10. if (fd >= 0)
11. have_console = 1;
12. close(fd);
13.