Android 8.1 关机充电动画(二)Uboot模式
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 },
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
name
:文件名soc
:图片对应的电量百分比period
:图片显示的时间(单位:ms)
那么,这里问题来了,图片如何打包到固件里呢?
- 先找到RK提供的打包用的脚本,u-boot/pack_resource.sh
- 找到需要打包的图片,然后需要修改的直接替换掉,图片采用8bit或24bit bmp格式,图片路径:u-boot/tools/images/,如下图所示:
- 最终就是如何打包图片了:
cd u-boot && ./pack_resource.sh ../kernel/resource.img
- 1
执行完以上命令后,终端会输出以下信息,说明打包成功;
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
并且会在当前的路径下重新生成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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
文章来源: great.blog.csdn.net,作者:小麦大叔,版权归原作者所有,如需转载,请联系作者。
原文链接:great.blog.csdn.net/article/details/89192487
- 点赞
- 收藏
- 关注作者
评论(0)