//--------------------------------------------------------------------------------------------
// 作者:longtian635241
// 论坛ID:imx6
// 版权:longtian635241
// 平台:飞思卡尔imx6
// 发布日期:2014-11-26
// 最后修改:2014-11-26
//----------------------------------------------------------------------------------------------
1、imx6如何进入charger模式呢?为尊重前辈先上参考资料!
http://blog.csdn.net/xubin341719/article/details/8498580 :讲解详细,基本都讲到了
http://blog.csdn.net/k_linux_man/article/details/7292746
:文中错误明显有提示作用,补充上面的
http://blog.sina.com.cn/s/blog_d627f7dc010199xt.html :当bootargs设置为androidboot.mode=charger不能启动charger可以参考修改源码
http://blog.csdn.net/shuaiff/article/details/5581127 同上
http://blog.csdn.net/lushengchu_luis/article/details/20382775
http://blog.csdn.net/wh_19910525/article/details/23176065 charger.c分析
2、具体过程
2.1 测试方法:
在uboot模式下设置bootargs:
<pre name="code" class="cpp">Hit any key to stop autoboot: 0 MX6Q SABRESD U-Boot > set bootargs console=ttymxc0,115200 init=/init video=mxcfb0:dev=lcd,SEIKO-WVGA,if=RGB24 video=mxcfb1:off video=mxcfb2:off vmalloc=400M androidboot.console=ttymxc0 androidboot.hardware=freescale androidboot.mode=charger MX6Q SABRESD U-Boot > sav Saving Environment to MMC... Writing to MMC(3)... done MX6Q SABRESD U-Boot >
2.2 重启,这是如果你幸运应该会进入charger mode
<span style="font-family:Arial;"> </span>
<span style="font-family:Arial;">2.3:imx6跑到</span>
<span style="font-family:Arial;">2.3.1</span>
<span style="font-family:Arial;">[ 3.255968] snvs_rtc snvs_rtc.0: setting system clock to 1970-01-02 01:57:30 UTC (93450) [ 3.264596] Freeing init memory: 228K</span>
<span style="font-family:Arial;">就没有反应了,通过测试发现已经加载到Z:\wk\myandroid\system\core\init\init.c的</span>
<span style="font-family:Arial;">。。。。。。。。。。。。。。。。。。。。。。。。</span>
<span style="font-family:Arial;">queue_builtin_action(console_init_action, "console_init"); //图片显示</span>
<span style="color:#ff0000;"><span style="font-family:Arial;">此处遇到一个纠结问题:如何在</span><span style="font-family: Arial;">init.c中打印log,有研究的大神烦指点下!</span></span>
<span style="font-family:Arial;"><span style="color:#ff0000;">ERROR("init_parse_config_file init.rc #####\n");这个函数貌似没及时打印到串口</span></span>
<span style="font-family:Arial;">2.3.2</span>
<span style="font-family:Arial;">分析init.c确定<span style="font-family: Arial; font-size: 18px; line-height: 26px;">androidboot.mode=charger参数有效,查看charger mode发现normal和charger主要区别在:</span></span>
<span style="font-family:Arial;"></span><pre name="code" class="cpp"> if (!is_charger) { //if (is_charger) { ERROR("!is_charger !is_charger #####\n"); <span style="color:#ff0000;"> action_for_each_trigger("early-fs", action_add_queue_tail); action_for_each_trigger("fs", action_add_queue_tail); action_for_each_trigger("post-fs", action_add_queue_tail); action_for_each_trigger("post-fs-data", action_add_queue_tail);</span> } queue_builtin_action(property_service_init_action, "property_service_init"); queue_builtin_action(signal_init_action, "signal_init"); queue_builtin_action(check_startup_action, "check_startup"); if (is_charger) { //if (!is_charger) { ERROR("is_charger is_charger $$$$$$$$$$$$$\n"); action_for_each_trigger("charger", action_add_queue_tail); } else { ERROR("action_for_each_trigger early-boot$$$$$$$$$$$$$\n"); <span style="color:#ff0000;"> action_for_each_trigger("early-boot", action_add_queue_tail); action_for_each_trigger("boot", action_add_queue_tail);</span> }
然后这些的执行都在init.rc中触发执行,而charger没有执行这些就无法执行,确定应该是init.rc的某些服务没配置!
<span style="font-family:Arial;">2.3.4</span>
<span style="font-family:Arial;">查看init.rc发现,一般init.rc中都有</span>
<span style="font-family:Arial;"></span><pre name="code" class="html"><span style="color:#ff0000;">on charger <span style="white-space:pre"> </span>class_start charger</span>
进而添加自己的服务
<span style="font-family:Arial;">service charger /charger <span style="white-space:pre"> </span>user root <span style="white-space:pre"> </span>group root graphics <span style="white-space:pre"> </span>console</span>
<span style="font-family:Arial;"><span style="white-space:pre"> </span>oneshot <span style="color:#ff0000;">init.rc语法很重要:其中不能加class main,class core,因为这两个启动的时候就会让这一类都启动!</span></span>
<span style="font-family:Arial;">然而就是无法启动,停在:[ 3.264596] Freeing init memory: 228K</span>
<span style="font-family:Arial;">此时有我想到两种方法:</span>
<span style="font-family:Arial;">一修改源码</span>
<span style="font-family:Arial;">二修改init.rc</span>
<span style="font-family:Arial;">自己太懒不想改源码,那样破坏其原始性,于是改init.rc,由于不熟悉init.rc的语法,瞎折腾了一天!因为我确信init.rc有问题,最后我参考了recovery模式下的init.rc:</span>
<span style="font-family:Arial;"></span><pre name="code" class="cpp">import /init.recovery.${ro.hardware}.rc on early-init start ueventd on init export PATH /sbin export ANDROID_ROOT /system export ANDROID_DATA /data export EXTERNAL_STORAGE /sdcard symlink /system/etc /etc mkdir /sdcard mkdir /system mkdir /data mkdir /cache mount /tmp /tmp tmpfs chown root shell /tmp chmod 0775 /tmp write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct D001 write /sys/class/android_usb/android0/functions adb write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer} write /sys/class/android_usb/android0/iProduct ${ro.product.model} write /sys/class/android_usb/android0/iSerial ${ro.serialno} on boot ifup lo hostname localhost domainname localdomain <span style="color:#ff0000;"> class_start default //recovery模式下的重点</span> service ueventd /sbin/ueventd critical service recovery /sbin/recovery service adbd /sbin/adbd recovery disabled # Always start adbd on userdebug and eng builds on property:ro.debuggable=1 write /sys/class/android_usb/android0/enable 1 start adbd # Restart adbd so it can run as root on property:service.adb.root=1 write /sys/class/android_usb/android0/enable 0 restart adbd write /sys/class/android_usb/android0/enable 1
最后将
<span style="color:#ff0000;">class_start default 加入</span>
<span style="font-family:Arial;"></span><pre name="code" class="html">on charger <span style="white-space:pre"> </span>class_start default <span style="white-space:pre"> </span>class_start charger
这样就可以启动charger mode了!
<span style="font-family:Arial;"> </span>
<span style="font-family:Arial;">2.4</span>
<span style="font-family:Arial;">自带的图片太丑,想换几张图片,因为原来libminui只支持png图片,找了几张替换,发现显示有问题:</span>
<span style="font-family:Arial;"></span>
\\192.168.1.130\hcm\wk\myandroid\system\core\charger\charger.c
<span style="font-family:Arial;">\\192.168.1.130\hcm\wk\myandroid\system\core\charger\charger.c分析代码:</span>
<span style="font-family:Arial;"> </span><pre name="code" class="cpp">int main(int argc, char **argv) { int ret; struct charger *charger = &charger_state; int64_t now = curr_time_ms() - 1; int fd; int i; list_init(&charger->supplies); klog_init(); klog_set_level(CHARGER_KLOG_LEVEL); dump_last_kmsg(); LOGI("--------------- STARTING CHARGER MODE ---------------\n"); gr_init(); gr_font_size(&char_width, &char_height); ev_init(input_callback, charger); fd = uevent_open_socket(64*1024, true); if (fd >= 0) { fcntl(fd, F_SETFL, O_NONBLOCK); ev_add_fd(fd, uevent_callback, charger); } charger->uevent_fd = fd; coldboot(charger, "/sys/class/power_supply", "add"); <span style="color:#ff0000;"> ret = res_create_surface("charger/battery_fail", &charger->surf_unknown);</span> if (ret < 0) { LOGE("Cannot load image\n"); charger->surf_unknown = NULL; } for (i = 0; i < charger->batt_anim->num_frames; i++) { struct frame *frame = &charger->batt_anim->frames[i]; <span style="color:#ff0000;">ret = res_create_surface(frame->name, &frame->surface); //</span><span style="color: rgb(255, 0, 0); font-family: Arial;">res_create_surface将对应图片变为surface</span><span style="color:#ff0000;"> </span> if (ret < 0) { LOGE("Cannot load image %s\n", frame->name); /* TODO: free the already allocated surfaces... */ charger->batt_anim->num_frames = 0; charger->batt_anim->num_cycles = 1; break; } } ev_sync_key_state(set_key_callback, charger); #ifndef CHARGER_DISABLE_INIT_BLANK gr_fb_blank(true); #endif charger->next_screen_transition = now - 1; charger->next_key_check = -1; charger->next_pwr_check = -1; reset_animation(charger->batt_anim); kick_animation(charger->batt_anim); LOGI("start event_loop\n"); event_loop(charger); return 0; }
具体显示流程:event_loop ---->update_screen_state------>redraw_screen----->draw_unknown(draw_battery)
------->draw_surface_centered--------->gr_blit
libminui库在:Y:\git-InnoTab\bootable\recovery\minui
分析此文件时,可以参考recovery的ui显示分析!
http://www.2cto.com/kf/201301/183366.html
http://blog.csdn.net/thinkinwm/article/details/12621129
im6的显示修改:
Y:\git-InnoTab\bootable\recovery\minui\resources.c的
int res_create_surface(const char* name, gr_surface* pSurface) { 。。。。。。。。。。。。。。。。 snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.png", name); resPath[sizeof(resPath)-1] = '\0'; FILE* fp = fopen(resPath, "rb"); if (fp == NULL) { result = -1; goto exit; } 。。。。。。。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。。。。 if (setjmp(png_jmpbuf(png_ptr))) { result = -6; goto exit; } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, sizeof(header)); png_read_info(png_ptr, info_ptr); size_t width = info_ptr->width; size_t height = info_ptr->height; size_t stride = 4 * width; size_t pixelSize = stride * height; 。。。。。。。。。。。。。。。。。。。。。 unsigned char* pData = (unsigned char*) (surface + 1); surface->version = sizeof(GGLSurface); surface->width = width; surface->height = height; surface->stride = width; /* Yes, pixels, not bytes */ surface->data = pData; <span style="color:#ff0000;">// surface->format = (channels == 3) ? GGL_PIXEL_FORMAT_RGBX_8888 : // ((color_type == PNG_COLOR_TYPE_PALETTE ? GGL_PIXEL_FORMAT_RGBA_8888 : GGL_PIXEL_FORMAT_L_8));改为如下 surface->format = (channels == 3)?GGL_PIXEL_FORMAT_RGBX_8888 : GGL_PIXEL_FORMAT_RGBA_8888;</span> 。。。。。。。。。。。。。。。。。。。 }
3、修改Z:\wk\myandroid\device\fsl\imx6\imx6.mk
PRODUCT_PACKAGES += \
charger \
audio.primary.imx6
\
audio_policy.conf
\
tinyplay
编译一下,make bootimage之后,烧机。