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)