system:Android 8.1

platform:RK3326/PX30

uboot

kernel


Android 8.1 关机充电动画(一)模式选择

Android 8.1 关机充电动画(二)Uboot模式

Android 8.1 关机充电动画(三)Android模式


前言

这部分要涉及到uboot下关机充电动画的定制,属于比较low level的部分,所以代码修改的部分不大,在uboot中主要是对多张图片进行轮播,所以这里的主要工作是定位到相应的代码以及如何定制自己的动画。

相关文档

RK在uboot的开发方面已经给出了文档

其中已经包括了这部分动画如何打包到rom中,不可避免的是需要重新编译uboot,但是图片会被打包到resource.img中。

相关代码

重新回到代码中u-boot/drivers/power/charge_animation.c

struct charge_image {
const char *name;
int soc;
int period; /* ms */
};
/*
* IF you want to use your own charge images, please:
*
* 1. Update the following 'image[]' to point to your own images;
* 2. You must set the failed image as last one and soc = -1 !!!
*/
static const struct charge_image image[] = {
{ .name = "battery_0.bmp", .soc = 5, .period = 600 },
{ .name = "battery_1.bmp", .soc = 20, .period = 600 },
{ .name = "battery_2.bmp", .soc = 40, .period = 600 },
{ .name = "battery_3.bmp", .soc = 60, .period = 600 },
{ .name = "battery_4.bmp", .soc = 80, .period = 600 },
{ .name = "battery_5.bmp", .soc = 100, .period = 600 },
{ .name = "battery_fail.bmp", .soc = -1, .period = 1000 },
};
  • name :文件名
  • soc:图片对应的电量百分比
  • period:图片显示的时间(单位:ms)

那么,这里问题来了,图片如何打包到固件里呢?

  1. 先找到RK提供的打包用的脚本,u-boot/pack_resource.sh
  2. 找到需要打包的图片,然后需要修改的直接替换掉,图片采用8bit或24bit bmp格式,图片路径:u-boot/tools/images/,如下图所示:
  3. 最终就是如何打包图片了:
cd u-boot && ./pack_resource.sh ../kernel/resource.img

执行完以上命令后,终端会输出以下信息,说明打包成功;

Pack ./tools/images/ & resource.img to resource.img ...
Unpacking old image(resource.img):
rk-kernel.dtb battery_1.bmp battery_2.bmp battery_3.bmp battery_4.bmp battery_5.bmp battery_fail.bmp logo.bmp logo_kernel.bmp battery_0.bmp
Pack to resource.img successed!
Packed resources:
rk-kernel.dtb battery_1.bmp battery_2.bmp battery_3.bmp battery_4.bmp battery_5.bmp battery_fail.bmp logo.bmp logo_kernel.bmp battery_0.bmp
resource.img is packed ready

并且会在当前的路径下重新生成resource.img,将这个文件重新烧写到设备的对应分区,就可以把充电动画打包到设备的rom中了。

总结

简单介绍了RK平台上进行关机充电uboot模式下充电动画的定制和打包方法,篇幅较短,也可以参考RK官方的文档,下一篇介绍一下,关机充电Android模式下如何进行充电动画的修改。附录是充电动画显示的主要代码。


附录

下面的代码是函数static int charge_animation_show(struct udevice *dev)中的while(1),这里会一直循环显示充电图片;

	/* Charging ! */
while (1) {
/*
* At the most time, fuel gauge is usually a i2c device, we
* should avoid read/write all the time. We had better set
* poll seconds to update fuel gauge info.
*/
if (!first_poll_fg && get_timer(delta) < FUEL_GAUGE_POLL_MS)
goto show_images; delta = get_timer(0); debug("step1 (%d)... \n", screen_on); /*
* Most fuel gauge is I2C interface, it shouldn't be interrupted
* during tansfer. The power key event depends on interrupt, so
* so we should disable local irq when update fuel gauge.
*/
local_irq_disable(); /* Step1: Is charging now ? */
charging = fuel_gauge_get_chrg_online(fg);
if (charging <= 0) {
printf("Not charging, online=%d. Shutdown...\n",
charging); /* wait uart flush before shutdown */
mdelay(5); /* PMIC shutdown */
pmic_shutdown(pmic); printf("Cpu should never reach here, shutdown failed !\n");
continue;
} debug("step2 (%d)... show_idx=%d\n", screen_on, show_idx); /* Step2: get soc and voltage */
soc = fuel_gauge_get_soc(fg);
if (soc < 0 || soc > 100) {
printf("get soc failed: %d\n", soc);
continue;
} voltage = fuel_gauge_get_voltage(fg);
if (voltage < 0) {
printf("get voltage failed: %d\n", voltage);
continue;
} current = fuel_gauge_get_current(fg);
if (current == -ENOSYS) {
printf("get current failed: %d\n", current);
continue;
}
first_poll_fg = 0; local_irq_enable(); show_images:
/*
* Just for debug, otherwise there will be nothing output which
* is not good to know what happen.
*/
if (!debug_start)
debug_start = get_timer(0);
if (get_timer(debug_start) > 20000) {
debug_start = get_timer(0);
printf("[%8ld]: soc=%d%%, vol=%dmv, c=%dma, online=%d, screen_on=%d\n",
get_timer(0)/1000, soc, voltage,
current, charging, screen_on);
} /*
* If ever lowpower screen off, force screen_on=false, which
* means key event can't modify screen_on, only voltage higher
* then threshold can update screen_on=true;
*/
if (ever_lowpower_screen_off)
screen_on = false; /*
* Auto turn on screen when voltage higher than Vol screen on.
* 'ever_lowpower_screen_off' means enter while loop with
* screen off.
*/
if ((ever_lowpower_screen_off) &&
(voltage > pdata->screen_on_voltage)) {
ever_lowpower_screen_off = false;
screen_on = true;
show_idx = IMAGE_SHOW_RESET;
} /*
* IMAGE_SHOW_RESET means show_idx show be update by start_idx.
* When short key pressed event trigged, we will set show_idx
* as IMAGE_SHOW_RESET which updates images index from start_idx
* that calculate by current soc.
*/
if (show_idx == IMAGE_SHOW_RESET) {
for (i = 0; i < image_num - 2; i++) {
/* Find out which image we start to show */
if ((soc >= image[i].soc) &&
(soc < image[i + 1].soc)) {
start_idx = i;
break;
} if (soc >= 100) {
start_idx = image_num - 2;
break;
}
} debug("%s: show_idx=%d, screen_on=%d\n",
__func__, show_idx, screen_on); /* Mark start index and start time */
show_idx = start_idx;
show_start = get_timer(0);
} debug("step3 (%d)... show_idx=%d\n", screen_on, show_idx); /* Step3: show images */
if (screen_on) {
/* Don't call 'charge_show_bmp' unless image changed */
if (old_show_idx != show_idx) {
old_show_idx = show_idx;
debug("SHOW: %s\n", image[show_idx].name);
charge_show_bmp(image[show_idx].name);
}
/* Re calculate timeout to off screen */
if (priv->auto_screen_off_timeout == 0)
priv->auto_screen_off_timeout = get_timer(0);
} else {
priv->auto_screen_off_timeout = 0; system_suspend_enter(pdata);
} mdelay(5); /* Every image shows period */
if (get_timer(show_start) > image[show_idx].period) {
show_start = get_timer(0);
/* Update to next image */
show_idx++;
if (show_idx > (image_num - 2))
show_idx = IMAGE_SHOW_RESET;
} debug("step4 (%d)... \n", screen_on); /*
* Step4: check key event.
*
* Short key event: turn on/off screen;
* Long key event: show logo and boot system or still charging.
*/
key_state = check_key_press(dev);
if (key_state == KEY_PRESS_DOWN) {
old_show_idx = IMAGE_SHOW_RESET; /* NULL means show nothing, ie. turn off screen */
if (screen_on)
charge_show_bmp(NULL); /*
* Clear current image index, and show image
* from start_idx
*/
show_idx = IMAGE_SHOW_RESET; /*
* We turn off screen by charge_show_bmp(NULL), so we
* should tell while loop to stop show images any more.
*
* If screen_on=false, means this short key pressed
* event turn on the screen and we need show images.
*
* If screen_on=true, means this short key pressed
* event turn off the screen and we never show images.
*/
if (screen_on)
screen_on = false;
else
screen_on = true;
} else if (key_state == KEY_PRESS_LONG_DOWN) {
/* Only long pressed while screen off needs screen_on true */
if (!screen_on)
screen_on = true; /* Is able to boot now ? */
if (soc < pdata->exit_charge_level) {
printf("soc=%d%%, threshold soc=%d%%\n",
soc, pdata->exit_charge_level);
printf("Low power, unable to boot, charging...\n");
show_idx = image_num - 1;
continue;
} if (voltage < pdata->exit_charge_voltage) {
printf("voltage=%dmv, threshold voltage=%dmv\n",
voltage, pdata->exit_charge_voltage);
printf("Low power, unable to boot, charging...\n");
show_idx = image_num - 1;
continue;
} /* Success exit charging */
printf("Exit charge animation...\n");
charge_show_logo();
break;
} else {
/* Do nothing */
} debug("step5 (%d)... \n", screen_on); /* Step5: Exit by ctrl+c */
if (ctrlc()) {
if (voltage >= pdata->screen_on_voltage)
charge_show_logo();
printf("Exit charge, due to ctrl+c\n");
break;
}
}

Android 8.1 关机充电动画(二)Uboot模式的更多相关文章

  1. Android 8.1 关机充电动画(三)Android模式

    system:Android 8.1 platform:RK3326/PX30 uboot kernel system/core/healthd Android 8.1 关机充电动画(一)模式选择 A ...

  2. Android 8.1 关机充电动画(一)模式选择

    system:Android 8.1 platform:RK3326/PX30 uboot kernel Android 8.1 关机充电动画(一)模式选择 Android 8.1 关机充电动画(二) ...

  3. Android MTK6580 客制化关机充电动画

    1.客制化关机充电图片 vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/xxx 找到对应分辨率替换 2.调整显示图片位置.大小 ...

  4. 【转】android 电池(二):android关机充电流程、充电画面显示

    关键词:android 电池关机充电 androidboot.mode charger关机充电 充电画面显示 平台信息:内核:linux2.6/linux3.0系统:android/android4. ...

  5. android 电池(二):android关机充电流程、充电画面显示【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/8498580 上一篇我们讲了锂电池的充放电的流程和电池的一些特性,这一节我们重点说一下a ...

  6. Android9.0 MTK 平板横屏方案修改(强制app横屏 + 开机logo/动画+关机充电横屏 + RecoveryUI 横屏)

    文章较长建议先收藏再看 拆解步骤 1.app 强制横屏显示,无视 android:screenOrientation="portrait" 属性 2.屏幕触摸坐标修改为横屏 3.开 ...

  7. Android Framework层Power键关机流程(二,关机流程)

    二,关机流程 从前一篇博文我们知道,当用户长按Power键时会弹出(关机.重启,飞行模式等选项)对话框,我们点击关机,则会弹出关机确认对话框.那么从选项对话框到关机确认对话框又是一个什么流程呢.下面我 ...

  8. Android 电池关机充电

    android 电池(一):锂电池基本原理篇 android 电池(二):android关机充电流程.充电画面显示 android 电池(三):android电池系统 android电池(四):电池 ...

  9. android关机充电

    1.关机充电其实是进入adb shell很快的方式! 2.手机关机时候插入USB,手机将进入关机充电模式,那么这个模式究竟是怎么进行的,这里分析如下! (1)uboot:这里代码大概浏览了一下:u-b ...

随机推荐

  1. 博云DevOps 3.0重大升级 | 可用性大幅提升、自研需求管理&自定义工作流上线,满足客户多样化需求

    DevOps能够为企业带来更高的部署频率.更短的交付周期与更快的客户响应速度.标准化.规范化的管理流程,可视化和数字化的研发进度管理和可追溯的版本也为企业带来的了更多的价值.引入DevOps成为企业实 ...

  2. Thymeleaf+SpringBoot+Mybatis实现的齐贤易游网旅游信息管理系统

    项目简介 项目来源于:https://github.com/liuyongfei-1998/root 本系统是基于Thymeleaf+SpringBoot+Mybatis.是非常标准的SSM三大框架( ...

  3. spring源码阅读笔记09:循环依赖

    前面的文章一直在研究Spring创建Bean的整个过程,创建一个bean是一个非常复杂的过程,而其中最难以理解的就是对循环依赖的处理,本文就来研究一下spring是如何处理循环依赖的. 1. 什么是循 ...

  4. 数据包的抓取[tcpdump]的应用

    [root@server ~]# yum install tcpdump [root@server ~]# yum install wireshark 1.默认情况下,直接启动tcpdump将监视第一 ...

  5. MySQL join的7种理论及SQL写法

    转载于    https://www.cnblogs.com/dinglinyong/p/6656315.html 建表 在这里呢我们先来建立两张有外键关联的张表. CREATE DATABASE d ...

  6. Codeforces Round #635 (Div. 2) 题解

    渭城朝雨浥轻尘,客舍青青柳色新. 劝君更尽一杯酒,西出阳关无故人.--王维 A. Ichihime and Triangle 网址:https://codeforces.com/contest/133 ...

  7. c语言-----劫持系统03

    1. 回顾 在前2节我们已经实现了劫持原理.函数指针等一些概念,下面进行系统劫持 2. 工具 vs2017 Detours 3. windows如何创建一个进程? (1)创建进程函数 CreatePr ...

  8. 【Linux常见命令】paste命令

    paste - merge lines of files paste 命令用于合并文件的列. paste 指令会把每个文件以列对列的方式,一列列地加以合并. 语法: paste [OPTION]... ...

  9. 13、canvas操纵像素数据ImageData

    2019独角兽企业重金招聘Python工程师标准>>> 一.ImageData 对象 含义: 存储canvas对象真实的像素数据(每个像素块的RGBA色值) 属性: 1.width: ...

  10. (附音视频、PPT地址)《打开Python这扇窗》分享总结

    0.导读 2016年最新开发语言排行榜中,Python已经跃居第三,仅次于C.JAVA.掌握Python已经成为时下运维圈的共识,更让人期待的是,本次公开课分享的嘉宾自身就长期专注Python.Doc ...