一、工作背景
公司主要做类手机的产品,使用的是android/linux系统,硬件平台用的rockchip3588,想实现这么一个功能,当接入充电适配器的情况时,用户执行关机操作,就进入充电动画界面。
二、实现思路
由于rk3588的充电动逻辑代码处于uboot阶段,而关机操作是用应用层发起,所以应用层下发的信息,uboot阶段能读取到。由于系统关机,pmu关断ddr电源,内存的数据则会丢失,并且也不会再启动Uboot。所以这里得执行重启动作,且应用层下发的信息也得存在flash中。这里想到的是用uboot中自带的工具fw_setenv,将环境变量写入flash的一块分区中,再由uboot读取这片环境变量来判断是否要主动接入充电动画界面。
三、实现流程
1.编译env源码,源码路径:rk3588/u-boot/tools/env,并将执行程序改名成fw_setenv放入系统/bin目录中
2.配置文件fw_env.config
2.1找到设备的磁盘符
2.2选择一个合适的存储地址
2.3将配置文件放入系统的/etc目录下
3.修改Uboot源码,这里只截取关键代码:
源码路径:u-boot/drivers/power/charge_animation.c
static int charge_animation_show(struct udevice *dev)//uboot启动后,会执行此函数来显示充电动画
{
.....
/* Not valid charge mode, exit */
#ifdef CONFIG_RKIMG_BOOTLOADER
boot_mode = rockchip_get_boot_mode(); //通过读取环境变量,判断是否进入充电界面
if ((boot_mode != BOOT_MODE_CHARGING) &&
(boot_mode != BOOT_MODE_UNDEFINE)) {
printf("Exit charge: due to boot mode boot_mode = %d\n",boot_mode);
return 0;
}
#endif
......
}
源码路径:u-boot/arch/arm/mach-rockchip/boot_mode.c
int rockchip_get_boot_mode(void)
{
struct bootloader_message *bmsg = NULL;
struct blk_desc *dev_desc;
disk_partition_t part_info;
uint32_t reg_boot_mode;
char *env_reboot_mode;
static int boot_mode = -1; /* static */
int clear_boot_reg = 0;
int ret, cnt;
#ifdef CONFIG_ANDROID_BOOT_IMAGE
u32 bcb_offset = android_bcb_msg_sector_offset();
#else
u32 bcb_offset = BCB_MESSAGE_BLK_OFFSET;
#endif
/*
* Here, we mainly check for:
* In rockusb_download(), that recovery key is pressed without
* USB attach will do env_set("reboot_mode", "recovery");
*/
env_reboot_mode = env_get("reboot_mode");
if (env_reboot_mode) {
if (!strcmp(env_reboot_mode, "recovery-key")) {
boot_mode = BOOT_MODE_RECOVERY;
printf("boot mode: recovery (key)\n");
} else if (!strcmp(env_reboot_mode, "recovery-usb")) {
boot_mode = BOOT_MODE_RECOVERY;
printf("boot mode: recovery (usb)\n");
} else if (!strcmp(env_reboot_mode, "recovery")) {
boot_mode = BOOT_MODE_RECOVERY;
printf("boot mode: recovery(env)\n");
} else if (!strcmp(env_reboot_mode, "fastboot")) {
boot_mode = BOOT_MODE_BOOTLOADER;
printf("boot mode: fastboot\n");
}else if (!strcmp(env_reboot_mode, "charging")){ //进入充电标志
boot_mode = BOOT_MODE_CHARGING;
env_set("reboot_mode"," ");
env_save();
printf("boot mode: charging!!!\n");
}
}
}
4.应用层将关机指令修改为.fw_setenv reboot_mode charging &&reboot 即可