一、移植chargemon
1. https://wiki.sonyericsson.net/androiki/Vendorbaseintegration#Bring_up_branch
2. charge only代码目录 vendor/semc/hardware/power/chargemon
3. repo ics-fuji的代码 repo init -u git://review.sonyericsson.net/platform/manifest -b ics-fuji
4. repo feature-for-aoba-ics-test的代码 repo init -u git://review.sonyericsson.net/platform/manifest -b feature-for-aoba-ics-test
5. Check Android.mk@vendor/semc/hardware/power/chargemon,中有SEMC_CFG_CHARGEMON的判断,如果为true才会编译chargemon的内容,通过搜索查找SEMC_CFG_CHARGEMON@device/semc/fuji/BoardConfig.mk中定义为 SEMC_CFG_CHARGEMON := true;
a. 修改device/semc/aoba/BoardConfig.mk 添加
SEMC_CFG_CHARGEMON := true
6. 在哪启动chargemon, 在device/semc/common/files/init.common.rc有
on early-boot
exec /system/bin/chargemon
7. 如何在代码资源中添加chargemon, 在manifest.xml@.repo中有
<project name="platform/vendor/semc/hardware/power/chargemon" path="vendor/semc/hardware/power/chargemon" revision="ics-fuji"/>
a. 修改.repo/manifests/default.xml 或.repo/manifest.xml 两者为同一文件
8. 在代码vendor/semc/hardware/power/chargemon/src/hw.c中没有定义BACKLIGHT_DEVICE_PATH
a. 暂时在device/semc/aoba/aoba.mk 添加
b. 添加 TARGET_BACKLIGHT_DEVICE_PATH := /sys/class/leds/lcd-backlight/brightness
TARGET_BATTERY_DEVICE_PATH := /sys/class/power_supply/bq27520/capacity
c. TARGET_AAA在*.mk中TARGET属于关键字,如果在源代码中使用则是去掉TARGET_后的变量,即AAA
9. device/semc/common/semc-generic.mk中有
PRODUCT_PACKAGES += chargemon \
10. 修改/device/semc/aoba/init.semc.rc (和system/core/rootdir/etc/init.qcom.rc),增加如下内容
on early-boot
# Start the offline charging (This blocks booting further in some cases)
exec /system/bin/chargemon
11. 提交代码/device/semc/
$git add aoba/aoba.mk
$git add aoba/BoardConfig.mk
$git add aoba/init.semc.rc
$git commit
VBI: ????
Category:development
$git log //检查提交状态
$repo upload .
提交代码进入.repo/manifests 目录
$git checkout default
$git status
$git commit -a -m 'Added vendor/semc/power/chargemon'
$git commit --amend //追加提交内容
$git pull --rebase ssh://gang.xu@review.sonyericsson.net:29418/platform/manifest feature-for-aoba-ics-test //重新sync到最新版本,
$git push ssh://gang.xu@review.sonyericsson.net:29418/platform/manifest HEAD:refs/for/feature-for-aoba-ics-test
参考https://wiki.sonyericsson.net/androiki/Making_manifest_changes和https://wiki.sonyericsson.net/androiki/Update_Manifest
如果提交代码出错,可以用$git reset --hard 重置下
12. 如何输出log? 在vendor/semc/hardware/power/chargemon/src/log.h中定义#ifndef DEBUG_LOG即可,输出的log被保存到了手机的/data/cm.log文件中
二、chargemon 流程分析
1. Riogrande 平台上 charge only(电池电量不够,不能开机,只能进入开机充电画面)的程序在vendor/semc/hardware/power/chargemon 下面
2. 如何输出调试bug
a. 定义#define DEBUG_LOG 在文件/vendor/semc/hardware/power/chargemon/src/log.h.
b. 分析/vendor/semc/hardware/power/chargemon/src/log.c log会输出到手机的/data/cm.log
3. 分析vendor/semc/hardware/power/chargemon/src/ 目录下的main.c 文件中main函数
4. 函数isDisabled 判断TA中的UNIT_ID_DISABLE_CHARGE_ONLY[0x2311]设置是否允许charge only mode,用函数miscta_read_unit读取
5. 函数utils_isFirstBoot 判断是否是第一次启动,如果是第一次启动不允许进入charge only mode, 用函数property_get读取手机属性 persist.chargemon.active 的值,只要启动过一次 persist.chargemon.active=1;
6. 函数isChargeOnly中,utils_getStartupreason@utils.c读取手机中/proc/cmdline参数中的startup的值,如果读取成功,还要用utils_getWarmbootreason@utils.c读取手机中/proc/cmdline参数中的warmboot的值, 通过得到的参数判断是否已经charge only mode,一般而言不会在isChargeOnly返回值为1;
7. 函数hw_init@hw.c --> utils_findKeyEvents@utils.c,获取所有/dev/input/event?的文件handle,以备后用;实际上按键输入是dev/input/event4, utils_findBatteryFile@utils.c, 通过查找/sys/class/power_supply/下的那个目录中包含名称为capacity的文件,这样就能得到读取battery capictiy 的文件handle
8. utils_findChargerFile 获取当前充电的状态,是wall charger还是usb charger, 通过文件/sys/class/power_supply/ab8500_ac/present和/sys/class/power_supply/ab8500_usb/present 的值来判断,是1则表示正在用该type charger.
9. sigaction(SIGALRM, &sact, NULL);SIGALRM是在定时器终止时发送给进程的信号,会触发sact.sa_handler = alarm_handler;函数,用于把backlight 关掉, 目前在后面的代码有alarm(5),会在5秒后给本进程发送SIGALRM,从而trigger alarm_handler函数;实现的功能是显示屏幕5秒后,自动关屏;
10. graphics_init@graphics.c-->display_init@display.c 得到framebuffer的具体参数设置,比如每行像素大小和高,等等;另外mmap会映射一块内存到文件/dev/graphics/fb0; vt_set_graphicsmode 会设置显示的是图片或文字,操作文件/dev/tty0实现; display_update实现更新framebuffer中的数据。 然后继续读取图片/system/semc/chargemon/data/charging_animation_%02i.png,并加以保存图像文件handle,以备后用,注:这些png文件保存在 vendor/semc/hardware/power/chargemon/HVGA,通过Android.mk中的脚本拷贝到手机
copy_from := $(foreach i,01 02 03 04 05 06 07,charging_animation_$(i).png)
copy_file_pairs := $(foreach cf,$(copy_from),$(LOCAL_PATH)/HVGA/$(cf):system/semc/chargemon/data/ $(cf))
11. hw_saveState()和hw_setGovernor("powersave")@hw.c;设置CPU工作模式governor,powersave将CPU长期维持在最低频率
12. hw_setBacklight@hw.c, 操作的是BACKLIGHT_DEVICE_PATH文件,注意该路径是/device/semc/riogrande/riogrande.mk中定义的 TARGET_BACKLIGHT_DEVICE_PATH := /sys/class/leds/lcd-backlight/brightness, TARGET是关键字
13. graphics_update 会根据hw_getBatteryCapacity得到的电量选择对应的png图片显示
14. hw_setRGBled 根据capacity 设置充电led灯的颜色
15. hw_waitForUserAction,其中用到了select非阻塞功能(设置了超时WAIT_INTERVAL 5)
a. FD_ZERO(&listen);将指定的文件描述符集清空
b. FD_SET(inputfds[i], &listen);用于在文件描述符集合中增加一个新的文件描述符。
c. select(max_fd + 1, &listen, NULL, NULL, &delay);测试指定的fd可读(可写?有异常条件待处理?),如果可读listen对应bit为1,delay设置延时
d. FD_ISSET(inputfds[i], &listen);用于测试指定的文件描述符是否在该集合中,inputfds[] 是否可读
e. hw_longPress 判断是否KEY_POWER是否长按(LONG_PRESS_TIME 2秒)
16. 处理按键CHARGEMON_ACTION_WAKE_UP-->亮屏幕,CHARGEMON_ACTION_POWER_ON-->开机
17. 如果开机,hw_restoreState恢复原来的cpu governor, hw_vibrate会震动提示(操作文件为VIBRATOR_DEVICE_PATH "/sys/class/timed_output/vibrator/enable"),然后继续执行*.rc 中的其他命令,启动android
18. 如果出现异常,则reboot(RB_POWER_OFF);-->_reboot 系统调用,重启手机
a. #define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF@Reboot.h (bionic\libc\include\sys)