Управление анимацией зарядки u-boot (rk817) подробное объяснение

вопрос:

        Недавно столкнулся с проблемой.Продукт системы android11 ​​rk3566-планшет.Система нормально находится в состоянии энергопотребления,и система будет нормально зависать(это значит что заряда батареи не хватает для вождения нагрузка, чтобы продолжать нормально работать), что мы и говорим. Система принудительно выключается (физическое выключение), но после выключения системы она автоматически перезапускается, а затем перезагружается на полпути, снова зависает, и это было в этом цикле, и заряд батареи был достаточно разряжен для автоматического запуска, он не загружается.

ПРИМЕЧАНИЕ. Это тот случай, когда система питается от аккумулятора, а адаптер не подключен.

анализировать:

        Причина, по которой система зависает, определенно заключается в том, что заряда батареи недостаточно для нормальной работы нагрузки системы, что мы называем автоматическим отключением (физическим отключением) при низком заряде батареи и причиной автоматического перезапуска. заключается в том, что когда система выключена, батарея Текущее состояние не нагружено, и батарея, которую я использую, имеет проблемы, и это может быть причиной того, что батарея, которую я использую, слишком расстроена. -нагрузка, напряжение его батареи увеличится примерно на 0,2-0,3 В, и система будет судить об этом значении напряжения.В это время система чувствует, что батарея работает! ! ! Он может поддерживать систему для повторного запуска, а затем автоматически запускается снова.Обнаружено, что батарея не двигается, когда она включается наполовину, а затем зависает. . . . Молодец, это не мошенничество! ! Конечно, автоматический запуск здесь будет упомянут позже, и в коде есть соответствующие суждения. Что моя текущая система должна реализовать, так это отключить зарядку, а не иметь возможность автоматически включать ее при подключении к адаптеру, и решить вышеуказанные проблемы.

Зарядка при выключении и соответствующая обработка загрузки находятся на этапе u-boot, и задействованы следующие файлы:

u-boot/drivers/power/charge_animation.c //Важно, отвечает за управление всем процессом зарядки, он будет получать питание, тип зарядки, ключевые события, инициировать спящий режим с низким энергопотреблением и т. д.

u-boot/include/power/charge_animation.h

u-загрузка/драйверы/мощность/fuel_gauge/fg_rk817.c

u-загрузка/драйверы/мощность/fuel_gauge/fuel_gauge_uclass.c

u-загрузка/драйверы/питание/pmic/rk8xx.c

Важный код, анализ структуры:

        Эта структура связана со значением, используемым для управления начислениями, и конкретные функции четко аннотированы.

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

 Разбор файла конфигурации 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>;
	};	
	

Примечание: их необходимо настроить в соответствии с вашей средой, в частности, вы можете проверить это с помощью мультиметра, а затем настроить его на соответствующее значение.

Все рабочие функции в charge_animation.c реализованы в fg_rk817.c следующим образом:

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

Функция реализации всего процесса зарядки управления uboot — это, в основном, функция charge_animation_show(), которая является относительно важной функцией.Давайте проанализируем ее процесс ниже.

        

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 的处理。 

Функция charge_extrem_low_power() в основном предназначена для определения текущего значения заряда аккумулятора и необходимости подключения адаптера для зарядки аккумулятора. Если заряд батареи меньше минимального значения мощности, которое мы установили, и адаптер не подключен, pmic будет выключен. Для того, чтобы возникала упомянутая выше ситуация повторных перезапусков.

        

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

Таким образом, в основном проблемы, которые у нас есть выше, относительно ясны, а остальные требуют от нас только настройки соответствующих параметров.

        И у моей текущей платы нет значка выключения зарядки, потому что мой дисплей конвертируется в LVDS через mipi dsi, а чип конвертируется через GM8775C, поэтому мне нужно успешно инициализировать чип в uboot.

 

Guess you like

Origin blog.csdn.net/qq_48709036/article/details/124406521