Explication détaillée de la gestion de la charge de l'animation de charge u-boot (rk817)

question:

        Récemment, j'ai rencontré un problème. Le produit du système android11 ​​rk3566 est une tablette. Le système est normalement dans un état de consommation d'énergie, et le système raccrochera normalement (cela signifie que la puissance de la batterie n'est pas suffisante pour conduire la charge pour continuer à fonctionner normalement), c'est ce que nous disons Le système est forcé de s'arrêter (arrêt physique), mais après l'arrêt du système, il redémarrera automatiquement, puis redémarrera à mi-chemin, il raccrochera à nouveau, et il a été dans ce cycle, et la puissance de la batterie a été suffisamment épuisée pour démarrer automatiquement, il ne démarrera pas.

REMARQUE : C'est le cas lorsque le système est alimenté par la batterie et que l'adaptateur n'est pas branché.

analyser:

        La raison pour laquelle le système raccroche est certainement parce que la puissance de la batterie n'est pas suffisante pour que la charge du système fonctionne normalement, c'est ce que nous appelons l'arrêt automatique (arrêt physique) lorsque la batterie est faible, et la raison du redémarrage automatique est que lorsque le système est éteint, la batterie L'état actuel est un état sans charge, et la batterie que j'utilise a un problème, et c'est peut-être la raison pour laquelle la batterie que j'utilise est trop frustrée. -load, sa tension de batterie augmentera de 0,2-0,3 V environ et le système évaluera cette valeur de tension. A ce moment, le système sent que la batterie semble fonctionner ! ! ! Il peut aider le système à redémarrer, puis il redémarre automatiquement.On constate que la batterie ne bouge pas lorsqu'elle est allumée à mi-chemin, puis elle raccroche. . . . Bon gars, n'est-ce pas une arnaque ! ! Bien sûr, le démarrage automatique ici sera mentionné plus tard, et il y a des jugements liés dans le code. Ce que mon système actuel doit comprendre, c'est d'éteindre la charge et de ne pas pouvoir la faire s'allumer automatiquement lorsqu'elle est branchée sur l'adaptateur, et de résoudre les problèmes ci-dessus.

La charge d'arrêt et le traitement de démarrage associé sont tous au stade u-boot, et les fichiers concernés sont :

u-boot/drivers/power/charge_animation.c //Important, responsable de la gestion de l'ensemble du processus de charge, il obtiendra la puissance, le type de charge, les événements clés, initiera le sommeil à faible consommation, 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

Code important, analyse de structure :

        Cette structure est liée à la valeur utilisée pour la gestion de la charge, et les fonctions spécifiques sont clairement annotées.

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 */
};

 analyse du fichier de configuration 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>;
	};	
	

Remarque : Ceux-ci doivent être configurés en fonction de votre propre environnement. Plus précisément, vous pouvez le tester avec un multimètre, puis le configurer à la valeur correspondante.

Toutes les fonctions d'opération dans charge_animation.c sont implémentées dans fg_rk817.c comme suit :

 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 fonction d'implémentation de l'ensemble du processus de charge de la gestion uboot est principalement la fonction charge_animation_show(), qui est une fonction relativement importante. Analysons son processus ci-dessous.

        

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 fonction charge_extrem_low_power() sert principalement à détecter la valeur actuelle de la puissance de la batterie et s'il faut brancher l'adaptateur pour charger la batterie. Si la puissance de la batterie est inférieure à la valeur de puissance minimale que nous avons définie et qu'aucun adaptateur n'est branché, le pmic sera éteint. Afin de s'assurer que la situation de redémarrages répétés mentionnée ci-dessus apparaît.

        

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;
}

Donc, fondamentalement, les problèmes que nous avons ci-dessus sont relativement clairs, et le reste n'a besoin que de nous pour configurer les paramètres pertinents.

        Et ma carte actuelle n'a pas d'icône de chargement d'arrêt, car mon écran est converti en LVDS via mipi dsi, et la puce est convertie via GM8775C, je dois donc initialiser la puce avec succès dans uboot.

 

Je suppose que tu aimes

Origine blog.csdn.net/qq_48709036/article/details/124406521
conseillé
Classement