温控daemon(四)加载配置文件

这篇博客我们主要分析thermal-engine中如何加载配置文件,包括代码中和配置文件。这里主要分析下thermal和ss算法的配置。

加载配置,在main函数中主要涉及如下代码。

	init_settings(&thermal_settings);

	pid_init_data(&thermal_settings);//pid算法我们平台disable后续分析
	thermal_monitor_init_data(&thermal_settings);
	speaker_cal_init_data(&thermal_settings);//后续分析
	ss_init_data(&thermal_settings);
	tb_init_data(&thermal_settings);//后续分析

	virtual_sensors_init_data(&thermal_settings);//后续分析

	virtual_sensors_init(&thermal_settings, config_file);//这里主要是通过settings_info中的type为virtual的,创建virtual sensor

#       ifdef ENABLE_OLD_PARSER
	load_config(&thermal_settings, config_file);//不涉及
#       else
	load_config(&thermal_settings, config_file, LOAD_ALL_FLAG);//加载配置文件
#       endif

init_settings函数主要是做下初始化。

void init_settings(struct thermal_setting_t *settings)
{
	if (!settings)
		return;

	memset(settings, 0, sizeof(struct thermal_setting_t));
	settings->sample_period_ms = ERR_SAMPLING_VAL;
}

thermal_monitor_init_data函数代码如下,主要是根据平台的类型加载代码中的thermal算法的配置。

void thermal_monitor_init_data(struct thermal_setting_t *setting)
{
	unsigned int i;
	struct setting_info *cfg = NULL;
	unsigned int arr_size = 0;

	switch (therm_get_msm_id()) {//通过读取soc_id得到msm_id
		......
		case THERM_MSM_8909:
			switch (therm_get_pmic_model()) {
				case THERM_PMIC_PM8916:
					cfg = tm_cfgs_8909_pm8916;
					arr_size =
					ARRAY_SIZE(tm_cfgs_8909_pm8916);
					break;
				case THERM_PMIC_PM8909://读取pmic_model得到pmic
				default:
					if (therm_get_hw_platform_subtype() ==
						THERM_PLATFORM_SUB_QRD_HUAQIN) {
						cfg = tm_cfgs_8909_qrd_hq;
						arr_size =
						ARRAY_SIZE(tm_cfgs_8909_qrd_hq);
					} else {
						cfg = tm_cfgs_8909;
						arr_size =
						ARRAY_SIZE(tm_cfgs_8909);
					}
					break;
			}
			break;
		......
		default:
			msg("%s: Uknown Bear family device", __func__);
			break;
	}

	for (i = 0; i < arr_size; i++) {
		add_setting(setting, &cfg[i]);
	}
}

我们先来看下therm_get_msm_id函数,先是从/sys/devices/soc0/soc_id或者/sys/devices/system/soc/soc0/id节点中读取soc_id,然后再从msm_soc_table中找到msm_id

enum therm_msm_id therm_get_msm_id(void)
{
	static enum therm_msm_id msm_id;
	static uint8_t msm_id_init;

	if (!msm_id_init) {
		int idx;
		char buf[MAX_SOC_INFO_NAME_LEN];

		if (soc_id < 0) {
			get_soc_info(buf, SYSFS_PLATFORMID, SYSFS_PLATFORMID_DEPRECATED);
			soc_id = atoi(buf);
		}

		for (idx = 0; idx < ARRAY_SIZE(msm_soc_table); idx++) {
			if (soc_id == msm_soc_table[idx].soc_id) {
				msm_id = msm_soc_table[idx].msm_id;
				break;
			}
		}
		if (!msm_id)
			msg("Unknown target identified with soc id %d\n", soc_id);

		msm_id_init = 1;
	}
	return msm_id;
}

soc_id为如下

msm_soc_table表如下,soc_id是245对应的msm_id是8909

static struct therm_msm_soc_type msm_soc_table[] = {
	{THERM_MSM_8960,   87},
	......
	{THERM_MSM_8909,   245},

therm_get_pmic_model读取/sys/devices/soc0/pmic_model或者/sys/devices/system/soc/soc0/pmic_model节点的值为65549,然后通过pmic_type_table得到是THERM_PMIC_PM8909

enum therm_pmic_model therm_get_pmic_model(void)
{
	static enum therm_pmic_model pmic = THERM_PMIC_UNKNOWN;
	static uint8_t pmic_id_init;

	if (!pmic_id_init) {
		int idx;
		int pmic_id = 0;
		char buf[MAX_SOC_INFO_NAME_LEN] = {0};

		get_soc_info(buf, SYSFS_PMIC_MODEL,
				SYSFS_PMIC_MODEL_DEPRECATED);
		pmic_id = atoi(buf);

		for (idx = 0; idx < ARRAY_SIZE(pmic_type_table); idx++) {
			if (pmic_id == pmic_type_table[idx].pmic_id) {
				pmic = pmic_type_table[idx].pmic;
				break;
			}
		}
		if (!pmic)
			msg("Unknown pmic identified with pmic id %d\n",
			    pmic_id);

		pmic_id_init = 1;
	}

	return pmic;
}

最后再通过therm_get_hw_platform_subtype函数得到平台类型,读取/sys/devices/soc0/platform_subtype_id或者/sys/devices/system/soc/soc0/platform_subtype_id节点,这里是是1,因此最后cfg = tm_cfgs_8909

enum therm_hw_platform_subtype therm_get_hw_platform_subtype(void)
{
	static enum therm_hw_platform_subtype subtype =
					THERM_PLATFORM_SUB_UNKNOWN;
	static uint8_t subtype_id_init;

	if (!subtype_id_init) {
		int subtype_id = 0;
		char buf[MAX_SOC_INFO_NAME_LEN];

		get_soc_info(buf, SYSFS_HW_SUBTYPE, SYSFS_HW_SUBTYPE_DEPRECATED);
		subtype_id = atoi(buf);
		if (subtype_id > THERM_PLATFORM_SUB_UNKNOWN)
			subtype = subtype_id;

		subtype_id_init = 1;
	}
	return subtype;
}

我们来看下tm_cfgs_8909,这里列了部分典型的后面我们再温度到达条件再结合配置一起看。

static struct setting_info tm_cfgs_8909[] =
{
	{
		.desc = "CPU3_HOTPLUG_MONITOR",
		.algo_type = MONITOR_ALGO_TYPE,
		.data.tm = {
			.sensor = "tsens_tz_sensor4",
			.sampling_period_ms = 1000,
			.num_thresholds = 1,
			._n_thresholds = 1,
			._n_to_clear = 1,
			._n_actions = 1,
			._n_action_info = 1,
			.t[0] = {
				.lvl_trig = 85000,
				.lvl_clr = 80000,
				.num_actions = 1,
				.actions[0] = {
					.device = "hotplug_3",
					.info = 1,
				},
			}
		},
	},
	......
	{
		.desc = "CX_MITIGATION_MONITOR_TSENS4",
		.algo_type = MONITOR_ALGO_TYPE,
		.data.tm = {
			.sensor = "tsens_tz_sensor4",
			.sampling_period_ms = 250,
			.num_thresholds = 2,
			._n_thresholds = 2,
			._n_to_clear = 2,
			._n_actions = 2,
			._n_action_info = 2,
			.t[0] = {
				.lvl_trig = 92000,
				.lvl_clr = 85000,
				.num_actions = 7,
				.actions[0] = {
					.device = "modem_cx",
					.info = 2,
				},
				.actions[1] = {
					.device = "gpu",
					.info = 200000000,
				},
				.actions[2] = {
					.device = "venus",
					.info = 1,
				},
				.actions[3] = {
					.device = "mdp",
					.info = 1,
				},
				.actions[4] = {
					.device = "wlan",
					.info = 1,
				},
				.actions[5] = {
					.device = "camera",
					.info = 0,
				},
				.actions[6] = {
					.device = "camcorder",
					.info = 0,
				},
			},
			.t[1] = {
				.lvl_trig = 100000,
				.lvl_clr = 92000,
				.num_actions = 7,
				.actions[0] = {
					.device = "modem_cx",
					.info = 3,
				},
				.actions[1] = {
					.device = "gpu",
					.info = 200000000,
				},
				.actions[2] = {
					.device = "venus",
					.info = 3,
				},
				.actions[3] = {
					.device = "mdp",
					.info = 3,
				},
				.actions[4] = {
					.device = "wlan",
					.info = 4,
				},
				.actions[5] = {
					.device = "camera",
					.info = 10,
				},
				.actions[6] = {
					.device = "camcorder",
					.info = 10,
				},
			}
		},
	},
};

下面我们来看ss算法,ss_init_data函数如下

		case THERM_MSM_8909:
			switch (therm_get_hw_platform()) {
				case THERM_PLATFORM_QRD:
					if (therm_get_hw_platform_subtype() ==
						THERM_PLATFORM_SUB_QRD_HUAQIN) {
						cfg = ss_cfgs_8909_qrd_hq;
						arr_size =
						ARRAY_SIZE(ss_cfgs_8909_qrd_hq);
					} else {
						cfg = ss_cfgs_8909_qrd_lc;
						arr_size =
						ARRAY_SIZE(ss_cfgs_8909_qrd_lc);
					}
					break;
				default:
					cfg = ss_cfgs_8909;
					arr_size = ARRAY_SIZE(ss_cfgs_8909);
					break;
			}
			break;

therm_get_hw_platform是获取/sys/devices/soc0/hw_platform或者/sys/devices/system/soc/soc0/hw_platform节点这里MTP,最后是cfg=  s_cfgs_8909。

enum therm_hw_platform therm_get_hw_platform(void)
{
	static enum therm_hw_platform platform;
	static uint8_t hw_platform_init;

	if (!hw_platform_init) {
		int idx;
		char buf[MAX_SOC_INFO_NAME_LEN];

		get_soc_info(buf, SYSFS_HW_PLATFORM,
				   SYSFS_HW_PLATFORM_DEPRECATED);

		for (idx = 0; idx < ARRAY_SIZE(platform_table); idx++) {
			if (strncmp(platform_table[idx].platform_name, buf,
			    MAX_SOC_INFO_NAME_LEN) == 0) {
				platform = platform_table[idx].platform;
				break;
			}
		}
		hw_platform_init = 1;
	}
	return platform;
}

我们来看下ss算法,后续结合温度一起分析。

static struct setting_info ss_cfgs_8909[] =
{
	{
		.desc = "SS-CPU0-2",
		.algo_type = SS_ALGO_TYPE,
		.data.ss =
		{
			.sensor = "tsens_tz_sensor3",
			.device = "cpu",
			.sampling_period_ms = 65,
			.set_point = 85000,
			.set_point_clr = 55000,
		},
	},
	{
		.desc = "SS-CPU1-3",
		.algo_type = SS_ALGO_TYPE,
		.data.ss =
		{
			.sensor = "tsens_tz_sensor4",
			.device = "cpu",
			.sampling_period_ms = 65,
			.set_point = 85000,
			.set_point_clr = 55000,
		},
	},
	{
		.desc = "SS-POPMEM",
		.algo_type = SS_ALGO_TYPE,
		.data.ss =
		{
			.sensor = "pop_mem",
			.device = "cpu",
			.sampling_period_ms = 250,
			.set_point = 75000,
			.set_point_clr = 55000,
			.time_constant = 2,
		},
	},
	{
		.desc = "SS-GPU",
		.algo_type = SS_ALGO_TYPE,
		.data.ss =
		{
			.sensor = "tsens_tz_sensor2",
			.device = "gpu",
			.sampling_period_ms = 250,
			.set_point = 80000,
			.set_point_clr = 65000,
		},
	},
};

load_config函数是加载配置,主要加载各个sensor、device、和文件中的算法配置。

int load_config(struct thermal_setting_t *settings, const char *pFName, int flag)
{
	int ret_val = 0;
	const char *cf = (pFName) ? pFName : CONFIG_FILE_DEFAULT;//如果没有指定configfile就用/system/etc/thermal-engine.conf

	info("Loading configuration file %s\n", cf);
	configFile = fopen(cf,"r");
	if (configFile == NULL) {
		msg("Unable to open config file '%s'\n",cf);
		ret_val = -(EIO);
		goto error_handler;
	}

	if (load_sensors() || load_devices() || load_fields()) {//这是是收集平台所有的sensor、device信息
		ret_val = -(EFAULT);
		goto error_handler;
	}

	parse_file(settings, flag);//解析算法配置文件

	validate_config(settings);// 验证配置文件是否有效

error_handler:
	if (sensor_info_arr)
		free(sensor_info_arr);
	if (device_info_arr)
		free(device_info_arr);
	if (configFile)
		fclose(configFile);
	if (fields)
		free(fields);

	fields = NULL;
	sensor_info_arr = NULL;
	device_info_arr = NULL;
	configFile = NULL;

	return ret_val;
}

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值