Animación de carga administración de carga u-boot (rk817) explicación detallada

pregunta:

        Recientemente, encontré un problema. El producto del sistema android11 ​​​​rk3566 es una tableta. El sistema normalmente está en un estado de consumo de energía y el sistema colgará normalmente (esto significa que la energía de la batería no es suficiente para conducir). la carga para seguir funcionando normalmente), que es lo que decimos El sistema se ve obligado a apagar (apagado físico), pero después de que el sistema se apaga, se reiniciará automáticamente, y luego se reiniciará a la mitad, se colgará de nuevo, y ha estado en este ciclo, y la energía de la batería se ha agotado lo suficiente como para iniciarse automáticamente, no se iniciará.

NOTA: Este es el caso cuando el sistema funciona con la batería y el adaptador no está enchufado.

analizar:

        La razón por la que el sistema se cuelga es definitivamente porque la energía de la batería no es suficiente para hacer que la carga del sistema funcione normalmente, que es lo que llamamos apagado automático (apagado físico) cuando la batería está baja y el motivo del reinicio automático. es que cuando el sistema se apaga, la batería El estado actual es un estado sin carga, y la batería que uso tiene un problema, y ​​puede ser la razón por la que la batería que uso está demasiado frustrada. -carga, el voltaje de la batería aumentará en 0,2-0,3 V y el sistema juzgará este valor de voltaje. ¡En este momento, el sistema siente que la batería parece estar funcionando! ! ! Puede permitir que el sistema se inicie de nuevo, y luego se inicia automáticamente de nuevo.Se encuentra que la batería no se mueve cuando se enciende a la mitad, y luego se cuelga. . . . Buen chico, ¿no es esto una estafa? ! Por supuesto, el inicio automático aquí se mencionará más adelante, y hay juicios relacionados en el código. Lo que mi sistema actual debe realizar es apagar la carga y no poder hacer que se encienda automáticamente cuando está conectado al adaptador, y resolver los problemas anteriores.

La carga de apagado y el procesamiento de arranque relacionado están todos en la etapa de u-boot, y los archivos involucrados son:

u-boot/drivers/power/charge_animation.c //Importante, responsable de administrar todo el proceso de carga, obtendrá energía, tipo de carga, eventos clave, iniciará el modo de suspensión de bajo consumo, etc.

u-boot/include/power/charge_animation.h

u-boot/drivers/power/fuel_gauge/fg_rk817.c

u-boot/drivers/power/fuel_gauge/fuel_gauge_uclass.c

u-boot/drivers/power/pmic/rk8xx.c

Código importante, análisis de estructura:

        Esta estructura está relacionada con el valor utilizado para la gestión de cargos, y las funciones específicas están claramente anotadas.

struct charge_animation_pdata {
	int android_charge;	/* android charge, 1: enable, 0: disable */
	int uboot_charge;	/* u-boot charge, 1: enable, 0: disable */

	int auto_exit_charge;	/* energy enough auto exit uboot charging*/
	int exit_charge_voltage;/* lowest voltage allowed to exit charging */
	int exit_charge_level;  /* lowest soc level allowed to exit charging */
	int low_power_voltage;	/* below this voltage, force system into charge mode anyway */
	int screen_on_voltage;	/* lowest voltage allowed to turn on screen */

	int system_suspend;	/* enter ATF system suspend, 1: enable, 0: disable */
	int auto_wakeup_interval;/* timeout seconds to auto wakeup system */
	int auto_wakeup_screen_invert;/* auto wakeup system, 1: enable, 0: disable */
	int auto_off_screen_interval;/* timeout seconds to auto turn off screen */
};

 análisis del archivo de configuración dts:

charge-animation {
	compatible = "rockchip,uboot-charge";
	status = "okay";
	rockchip,uboot-charge-on = <0>; // 是否开启U-Boot充电
	rockchip,android-charge-on = <1>; // 是否开启Android充电
	rockchip,uboot-exit-charge-level = <5>; // U-Boot充电时,允许开机的最低电量
	rockchip,uboot-exit-charge-voltage = <3650>;// U-Boot充电时,允许开机的最低电压
	rockchip,screen-on-voltage = <3400>; // U-Boot充电时,允许点亮屏幕的最低电
	rockchip,uboot-low-power-voltage = <3350>; // U-Boot无条件强制进入充电模式的最低
	rockchip,system-suspend = <1>; // 是否灭屏时进入trust低功耗待机(要压电压ATF支持)
	rockchip,auto-off-screen-interval = <20>; // 自动灭屏超时,单位秒,默认15s
	rockchip,auto-wakeup-interval = <10>; // 休眠自动唤醒时间,单位秒。如果值为0或没// 有这个属性,则禁止休眠自动唤醒,一般用于 压力测试使用
	rockchip,auto-wakeup-screen-invert = <1>;
	};	
	

Nota: estos deben configurarse de acuerdo con su propio entorno. Específicamente, puede probarlo con un multímetro y luego configurarlo al valor correspondiente.

Todas las funciones de operación en charge_animation.c se implementan en fg_rk817.c de la siguiente manera:

 static struct dm_fuel_gauge_ops fg_ops = { //charge_animatio.c 中的一些回调函数都是都是调用的fg_rk817中的函数实现。
	.bat_is_exist = rk817_bat_bat_is_exist,
	.get_soc = rk817_bat_update_get_soc,
	.get_voltage = rk817_bat_update_get_voltage,
	.get_current = rk817_bat_update_get_current,
	.get_chrg_online = rk817_bat_update_get_chrg_online,
};

La función de implementación de todo el proceso de carga de la gestión de uboot es principalmente la función charge_animation_show(), que es una función relativamente importante. Analicemos su proceso a continuación.

        

charge_animation_show();
 	|--fuel_gauge_bat_is_exist();->rk817_bat_bat_is_exist
	   |--rk817_bat_get_battery_voltage(battery); //读取pmic中的寄存器值获取battery的电量。
	|--charge_extrem_low_power(dev); //该函数主要是检测电池低电量(无法满足系统工作的电量)的,且无供电电源时,关闭PMIC 下电。下面会讲一下该函数。
	   |--fuel_gauge_get_voltage(fg);
	      |--rk817_bat_update_get_voltage();	
	      |--rk817_bat_get_battery_voltage();
	     |--fg_charger_get_chrg_online(dev); // --->>>/* PMIC shutdown */ pmic_shutdown(pmic);static int rk8xx_shutdown(struct udevice *dev)
		|--rk817_bat_update_get_chrg_online();
		   |--rk817_bat_dwc_otg_check_dpdm(battery);	//检测充电类型	
	   |--autowakeup_timer_init(dev,5);	///* Enable auto wakeup */
	   |--fuel_gauge_update_get_soc(fg);-->static int rk817_bat_update_get_soc(struct udevice *dev)//该函数设置充电电流,以及外接的充电类,rk817_bat_smooth_charge(struct rk817_battery_device *battery)(每隔5S检测一次,保证是否在平稳的充电)
	   |--eds_update(dev, soc);
	   |--system_suspend_enter(dev);/* System suspend */
	   |--fuel_gauge_get_voltage(fg);  //更新电压	|--rk817_bat_update_get_voltage();
	|--rockchip_get_boot_mode();//检测充电模式是否有效。
	|--fg_charger_get_chrg_online(dev);--->rk817_bat_update_get_chrg_online();rk817_bat_dwc_otg_check_dpdm(battery);//获取充电头类型
	/* Not charger online and low power, shutdown */
			soc = fuel_gauge_update_get_soc(fg);
		voltage = fuel_gauge_get_voltage(fg);
		if (soc < pdata->exit_charge_level) {
			printf("soc(%d%%) < exit_charge_level(%d%%)\n",
			       soc, pdata->exit_charge_level);
			exit_charge = true;
		}
		if (voltage < pdata->exit_charge_voltage) {
			printf("voltage(%d) < exit_charge_voltage(%d)\n",
			       voltage, pdata->exit_charge_voltage);
			exit_charge = true;
		}
		if (exit_charge) {
			printf("Not charging and low power, Shutdown...\n");
			show_idx = IMAGE_LOWPOWER_IDX(image_num);
			charge_show_bmp(image[show_idx].name);
			mdelay(1000);
			pmic_shutdown(pmic);
		}
	}
	//以下是判断:
	|--pdata->android_charge // Enter android charge, set property for kernel */
	|--if (!pdata->uboot_charge)///* Not enable U-Boot charge, exit */
	|--fuel_gauge_get_voltage(fg);
	|--if (voltage <= pdata->screen_on_voltage + 50)//charge_show_bmp(NULL); 
	|-----!!!!!!/* Charging ! */  while (1) 开始充电 //获取电量状态等驱动中利用的是定时器轮询的方式来获取,避免通过i2c来一直读取寄存器的值。在此期间是禁止中断的,而是通过power key产生事件中断。
	|--local_irq_disable();	
	接下来就是充电5个步骤。
	|--第一步:检测是否现在充电。
	|--charging = fg_charger_get_chrg_online(dev);//如果充电器在此过程中拔出,则会调用rockchip_eink_show_charge_logo(),并关闭PMIC。
	|--第二步:获取系统的电量与电池的电压,以及电流。判断目前的电压是否可以退出uboot阶段的充电(pdata->auto_exit_charge)。判断此时电量是否足以打开屏幕。
	|--fuel_gauge_update_get_soc(fg);	
	|--fuel_gauge_get_voltage(fg);
	|--fuel_gauge_get_current(fg);
	|--下面的一部分就是处理关机充电时,亮屏以及充电图标状态显示的处理。当系统充电到100时则退出充电状态,以引导android 系统。
	。。。。。。
	|--第三步:主要是显示充电图标的处理。这部分我们不重点关注。
	|--第四步:检查按键事件。检测power key :short key event:亮灭屏。长按键:显示logo 图标,引导系统开机继续保持充电状态。       
	|--key_state = check_key_press(dev);//key_state == KEY_PRESS_DOWN /key_state == KEY_PRESS_LONG_DOWN
	|--第五步:主要是检测 ctrl+c 的处理。 

La función charge_extrem_low_power() es principalmente para detectar el valor actual de energía de la batería y si se debe enchufar el adaptador para cargar la batería. Si la energía de la batería es menor que el valor de energía mínimo que configuramos y no hay ningún adaptador enchufado, el pmic se apagará. Con el fin de garantizar que se presente la situación de reinicios repetidos mencionada anteriormente.

        

static int charge_extrem_low_power(struct udevice *dev)
{
	struct charge_animation_pdata *pdata = dev_get_platdata(dev);
	struct charge_animation_priv *priv = dev_get_priv(dev);
	struct udevice *pmic = priv->pmic;
	struct udevice *fg = priv->fg;
	int voltage, soc, charging = 1;
	static int timer_initialized;
	int ret;

	voltage = fuel_gauge_get_voltage(fg);//获取当前电池电量值
	if (voltage < 0)
		return -EINVAL;
	while (voltage < pdata->low_power_voltage + 50) {
		/* Check charger online */
		charging = fg_charger_get_chrg_online(dev);//判断是否插入输入源,及适配器。返回输入源类型
		if (charging <= 0) {
			printf("%s: Not charging, online=%d. Shutdown...\n",
			       __func__, charging);
			/* wait uart flush before shutdown */
			mdelay(5);
			/* PMIC shutdown */
			pmic_shutdown(pmic);//关闭pmic.

			printf("Cpu should never reach here, shutdown failed !\n");
			continue;
		}

		/* Enable auto wakeup */
		if (!timer_initialized) {
			timer_initialized = 1;
			autowakeup_timer_init(dev, 5);
		}

		/*
		 * Just for fuel gauge to update something important,
		 * including charge current, coulometer or other.
		 */
		soc = fuel_gauge_update_get_soc(fg); //获取系统的电量值。
		if (soc < 0 || soc > 100) {
			printf("get soc failed: %d\n", soc);
			continue;
		}

		/* Update led */
		ret = leds_update(dev, soc);
		if (ret)
			printf("update led failed: %d\n", ret);

		printf("Extrem low power, force charging... threshold=%dmv, now=%dmv\n",
		       pdata->low_power_voltage, voltage);

		/* System suspend */
		system_suspend_enter(dev);

		/* Update voltage */
		voltage = fuel_gauge_get_voltage(fg);
		if (voltage < 0) {
			printf("get voltage failed: %d\n", voltage);
			continue;
		}

		if (ctrlc()) {
			printf("Extrem low charge: exit by ctrl+c\n");
			break;
		}
	}

	autowakeup_timer_uninit();

	return 0;
}

Entonces, básicamente, los problemas que tenemos arriba son relativamente claros, y el resto solo necesita que configuremos los parámetros relevantes.

        Y mi placa actual no tiene un ícono de carga de apagado, porque mi pantalla se convierte a LVDS a través de mipi dsi, y el chip se convierte a través de GM8775C, por lo que necesito inicializar el chip con éxito en uboot.

 

Supongo que te gusta

Origin blog.csdn.net/qq_48709036/article/details/124406521
Recomendado
Clasificación