温控daemon(六)Monitor算法

Monitor算法温控的常见算法之一,在main函数中调用了thermal_monitor函数.Monitor算法是一种静态算法,当超过每一个设置的温度值就会调频,当小于clr的温度就会停止调频算法。

1. thermal_monitor函数

thermal_monitor函数先是从dev_list中获取了各个device_info放入device_info_arr中,然后过滤setting放入tm_states的setting中,然后执行了sensor_up以及创建了一个thread执行函数sensor_monitor来监控是否触发monitor算法。

void thermal_monitor(struct thermal_setting_t *settings)
{
	struct setting_info *cfg_setting;
	union device_request req;

	/* Build Device Info List */
	if (devices_manager_get_list(NULL, &device_info_arr_len)) {//先获取dev_list的长度
		msg("Failed to get device list length\n");
		return;
	}

	device_info_arr = (struct device_info *)//根据device的长度 malloc
		malloc(sizeof(struct device_info)*device_info_arr_len);

	if (device_info_arr == NULL) {
		msg("Failed to alloc device_info_arr\n");
		return;
	}

	if (devices_manager_get_list(device_info_arr,//得到device_info
				     &device_info_arr_len)) {
		msg("Failed to get device list\n");
		free(device_info_arr);
		return;
	}

	cfg_setting = settings->list;

	while (cfg_setting && (tm_cnt < MAX_TM_INSTANCES_SUPPORTED)) {
		if ((cfg_setting->algo_type != MONITOR_ALGO_TYPE) ||//不是Monitor continue
		    (cfg_setting->err_disable != 0)) {//坏的setting continue
			cfg_setting = cfg_setting->next;
			continue;
		}

		dbgmsg("%s: Import %s", __func__, cfg_setting->desc);
		tm_states[tm_cnt].setting = cfg_setting;//放入tm_states数组的setting
		tm_states[tm_cnt].disable = cfg_setting->disable;
		tm_cnt++;

		if (!cfg_setting->disable)//没有disable 打印
			print_setting(cfg_setting);

		/* KEEP at end of while block */
		cfg_setting = cfg_setting->next;
	}

	if (!sensors_setup()) {//
		msg("Failed to setup at least one sensor for monitoring\n");
		return;
	}

	/* Vote to keep kernel mitigation enabled until thermal monitor has
	   processed initial thresholds. */
	kernel_dev = devices_manager_reg_clnt("kernel");
	if (kernel_dev == NULL) {
		msg("%s Failed to create kernel device handle\n", __func__);
		return;
	}
	req.value = 1;
	device_clnt_request(kernel_dev, &req);//继续keep KTM

	if (pthread_create(&tm_thread, NULL, (void *)&sensor_monitor,//sensor_monitor监控
			   (void *)NULL) != 0) {
		msg("Error initializing thermal monitor\n");
		device_clnt_cancel_request(kernel_dev);//失败就取消之前keep KTM的命令
	}
}

我们来看下devices_manager_get_list 函数,配合上面thermal_monitor函数,第一次传进来的info_arr为NULL,因此获取了device的长度,第二次再从dev_list中获取dev_info放入dev_info_arr.

int devices_manager_get_list(struct device_info *info_arr, uint32_t *info_arr_len)
{
	uint32_t dev_idx;
	struct devices_manager_dev *curr = dev_list;

	if ((info_arr == NULL) && (info_arr_len == NULL)) {
		msg("%s: Invalid args.\n", __func__);
		return -(EINVAL);
	}

	if (info_arr == NULL) {//第一次获取长度
		/* Interpret as request for number of dev's present. */
		*info_arr_len = dev_cnt;
		return 0;
	}

	/* Don't exceed end of info_array */
	*info_arr_len = MIN(*info_arr_len, dev_cnt);

	for (dev_idx = 0; (dev_idx < *info_arr_len) && (curr != NULL); dev_idx++) {//第二次遍历dev_list获取dev_info
		memcpy(&(info_arr[dev_idx]), &(curr->dev_info),
		       sizeof(struct device_info));
		curr = curr->next_dev;
	}

	return 0;
}

2. sensor_setup

下面我们再来看sensors_setup函数,这个函数我们需要结合monitor算法实际的配置来看。

static int sensors_setup(void)
{
	uint32_t i = 0;
	int sensor_count = 0;

	if (!tm_cnt)
		return 0;

	/* Set up tm instances */
	dbgmsg("%s: tm_cnt %d", __func__, tm_cnt);
	for (i = 0; i < tm_cnt; i++) {//遍历所有的tm_states
		struct tm_instance_info *tm_instance_info;
		struct setting_info *setting;
		struct tm_setting *tm_setting_info;

		tm_instance_info = &tm_states[i];
		setting = tm_instance_info->setting;
		tm_setting_info = &(setting->data.tm);

		dbgmsg("%s: TM Id %s Sensor %s num_thresholds %d", __func__,
		    setting->desc, tm_setting_info->sensor,
		    tm_setting_info->num_thresholds);
		if (tm_setting_info->num_thresholds > 0) {//结合下面num_thresholds为3
			/* Create sensor client */
			tm_instance_info->ts_clnt =
				sensors_manager_reg_clnt(tm_setting_info->sensor);//结合下面看我们的sensor是tsens_tz_sensor1
			if (tm_instance_info->ts_clnt == NULL) {//上面是创建一个sensor的client
				msg("%s: Can't create client for %s.\n",
				    __func__, tm_setting_info->sensor);
				tm_instance_info->disable = 1;
				continue;
			}

			/* Create necessary device clients */
			if (create_device_clnts(tm_instance_info) == 0)//这里处理每一个action
				sensor_count++;
			else
				tm_instance_info->disable = 1;
		}
	}
	return sensor_count;
}

下面是一个8909的Monitor算法的一部分:

	{
		.desc = "CAMERA_CAMCORDER_MONITOR",
		.algo_type = MONITOR_ALGO_TYPE,
		.data.tm = {
			.sensor = "tsens_tz_sensor1",
			.sampling_period_ms = 250,
			.num_thresholds = 3,//t的个数
			._n_thresholds = 3,
			._n_to_clear = 3,
			._n_actions = 3,
			._n_action_info = 3,
			.t[0] = {
				.lvl_trig = 80000,
				.lvl_clr = 75000,
				.num_actions = 2,//action的个数
				.actions[0] = {
					.device = "camera",
					.info = 1,
				},
				.actions[1] = {
					.device = "camcorder",
					.info = 1,
				},
			},
			.t[1] = {
				.lvl_trig = 85000,
				.lvl_clr = 80000,
				.num_actions = 2,
				.actions[0] = {
					.device = "camera",
					.info = 2,
				},
				.actions[1] = {
					.device = "camcorder",
					.info = 2,
				},
			},
			.t[2] = {
				.lvl_trig = 88000,
				.lvl_clr = 85000,
				.num_actions = 2,
				.actions[0] = {
					.device = "camera",
					.info = 10,
				},
				.actions[1] = {
					.device = "camcorder",
					.info = 10,
				},
			}
		},
	},

sensors_manager_reg_clnt函数就是为sensor创建一个client

sensor_clnt_handle sensors_manager_reg_clnt(const char *sensor_name)
{
	struct sensor_client_type *client = NULL;
	struct sensors_mgr_sensor_info *sensor_mgr = NULL;

	if (sensor_name == NULL) {
		msg("%s: Invalid args.\n", __func__);
		return client;
	}

	sensor_mgr = find_sensor(sensor_name);//从sensor_list中找到sensor

	if (sensor_mgr == NULL) {
		msg("%s: Invalid sensor %s.\n", __func__, sensor_name);
		return client;
	}

	client = malloc(sizeof(struct sensor_client_type));

	if (client == NULL) {
		msg("%s: Alloc. failed for %s.\n", __func__, sensor_name);
		return client;
	}
	memset(client, 0x0, sizeof(struct sensor_client_type));

	THERM_MUTEX_LOCK(&ts_clnt_mtx);
	/* Insert the client */
	client->sensor_mgr = sensor_mgr;
	client->next_clnt = sensor_mgr->client_list;
	sensor_mgr->client_list = client;
	THERM_MUTEX_UNLOCK(&ts_clnt_mtx);

	return client;
}

我们再来看下create_device_clnts函数

static int create_device_clnts(struct tm_instance_info *tm_instance_info)
{
	int ret_val = 0;
	uint32_t t_idx, a_idx;
	struct tm_devices_list
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值