温控daemon(三)sensor初始化

既上一篇博客继续分析main函数,上一篇博客我们分析了devices_init device的初始化,这篇博客先是分析保持KTM工作,后面主要分析sensor的初始化,。

1. 保持KTM工作

我们先来看如下,先是创建了一个kernel的client,然后因为有kernel 的device,所以会调用device_clnt_request函数

	kernel_dev = devices_manager_reg_clnt("kernel");//创建一个kernel device的client
	if (kernel_dev == NULL) {
		msg("%s Failed to create kernel device handle\n", __func__);
	} else {
		req.value = 1;//有kernel device
		device_clnt_request(kernel_dev, &req);
	}

上一篇博客我们分析过device_clnt_reques函数,这里传进来的device的type不一样我们再来分析下。kernel的device的type是DEVICE_GENERIC_TYPE,所以调用了devices_manager_set_lvl函数

int device_clnt_request(device_clnt_handle clnt, union device_request *req)
{
	struct devices_manager_dev *dev_mgr = NULL;
	struct device_clnt   *client = clnt;
	int ret_val = 0;

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

	ret_val = validate_clnt(client);//验证client,就是遍历device的list看每个device的client有没有这个client
	if (ret_val != 0)
		return ret_val;

	dev_mgr = client->dev_mgr;

	switch (dev_mgr->dev_info.dev_type) {
	case DEVICE_GENERIC_TYPE://kernel的device的type为这个
		ret_val = devices_manager_set_lvl(dev_mgr, client, req->value);
		break;
	case DEVICE_OP_VALUE_TYPE:
		ret_val = devices_manager_set_op_value(dev_mgr, client,
						       req->value);
		break;
	case DEVICE_DIRECT_ACTION_TYPE:
		ret_val = devices_manager_set_direct_action(dev_mgr, client,
							    req);
		break;
	default:
		dbgmsg("%s: Unhandled dev_type %d", __func__,
		       dev_mgr->dev_info.dev_type);
		break;
	}
	return ret_val;
}

devices_manager_set_lvl函数设置了client的request.value的值,然后调用了update_dev_state来更新device的state。

static int devices_manager_set_lvl(struct devices_manager_dev *dev_mgr,
				   struct device_clnt *client, int lvl)
{
	lvl = MIN(lvl, (int)(dev_mgr->dev_info.num_of_levels - 1));
	lvl = MAX(lvl, (int)(dev_mgr->dev_info.min_lvl));

	pthread_mutex_lock(&clnt_mtx);
	client->request.value = lvl;
	client->request_active = 1;
	pthread_mutex_unlock(&clnt_mtx);
	dbgmsg("%s: DEV %s, lvl %d\n", __func__,
	       dev_mgr->dev_info.name, lvl);
	update_dev_state(dev_mgr);

	return dev_mgr->active_req.value;;
}

update_dev_state函数上一篇博客已经分析过了,这里我们再来看下这里主要是遍历所有的client找到其最大值然后调用device的action函数。

static int update_dev_state(struct devices_manager_dev *dev_mgr)
{
	union device_request req;
	struct device_clnt *client = dev_mgr->client_list;

	if ((dev_mgr->dev_info.dev_type != DEVICE_GENERIC_TYPE) &&
	    (dev_mgr->dev_info.dev_type != DEVICE_OP_VALUE_TYPE))
		return -(EFAULT);

	pthread_mutex_lock(&clnt_mtx);

	if (dev_mgr->dev_info.dev_type == DEVICE_GENERIC_TYPE) {//kernel的type为这个分支
		/* Start from min level to find the highest existing client request */
		req.value = dev_mgr->dev_info.min_lvl;//device的min_lvl作为初始值

		/* Walk client list to find highest mitigation level */
		while (client != NULL) {
			if (client->request_active)
				req.value = MAX(req.value, client->request.value);//遍历所有的client的req.value取其最大值
			client = client->next_clnt;
		}
	} else if (dev_mgr->dev_info.dev_type == DEVICE_OP_VALUE_TYPE) {
		/* Start from max allowable value find lowest request */
		req.value = dev_mgr->dev_info.max_dev_op_value;

		/* Walk client list to find highest mitigation level */
		while (client != NULL) {
			if (client->request_active)
				req.value = MIN(req.value, client->request.value);
			client = client->next_clnt;
		}
	}

	if (dev_mgr->active_req.value != req.value) {
		dev_mgr->active_req.value = req.value;

		if (dev_mgr->action)
			dev_mgr->action(dev_mgr);//调用device的action函数

		/* Notify clients */
		client = dev_mgr->client_list;
		while (client != NULL) {//如果client有回调,就调用回调
			if (client->cb_func != NULL)
				client->cb_func(client, &req,
						client->cb_usr_data);
			client = client->next_clnt;
		}
	}
	pthread_mutex_unlock(&clnt_mtx);
	return 0;
}

而kernel的action最后调用了kernel_mitigation_request函数

static int kernel_mitigation_action(struct devices_manager_dev *dev_mgr)
{
	return kernel_mitigation_request(dev_mgr->active_req.value);
}

kernel_mitigation_request函数现在的request传入的是1,因此不做操作就是继续保持kernel的KTM工作,而当我们的thermal-engine完全工作后(初始化完成),最后会重新走到这,那时request为0,就会write /sys/module/msm_thermal/parameters/enabled节点为N,接管KTM的工作, 当KTM停止工作时,之前在thermal驱动设置的频率会重置。

int kernel_mitigation_request(int request)
{
	int ret = -1;

	pthread_mutex_lock(&kernel_disable_mtx);

	if (request == 0) {
		/* Disable kernel thermal module and take over */
		write_to_file("/sys/module/msm_thermal/parameters/enabled",
			      "N" , strlen("N") + 1);
		dbgmsg("KERNEL mitigation disabled\n");
	} else
		dbgmsg("KERNEL request to keep mitigation enabled\n");

	pthread_mutex_unlock(&kernel_disable_mtx);
	return ret;
}

2. sensor初始化

这节我们开始分析sensor的初始化,main函数调用了sensors_init函数,这个minimum_mode一般为0,我们的代码在Sensors.c中,这个可以从Android.mk查看。

int sensors_init(int minimum_mode)
{
	int ret_val = 0;
	min_mode = minimum_mode;

	if (!min_mode)
		modem_ts_qmi_init();//这里和modem通信的qmi我们后续分析

	init_sensor_alias();
	parse_thermal_zones();

	/* BCL */
	if (add_tgt_sensors_set(bcl_sensors,
			   ARRAY_SIZE(bcl_sensors)) != 0) {
		msg("%s: Error adding BCL TS\n", __func__);
		ret_val = -(EFAULT);
	}

	return ret_val;
}

2.1 读取每个sensor的信息

我们来看下init_sensor_alias函数,先从节点/sys/module/msm_thermal/sensor_info读取节点信息,然后保存sensor信息到sensors数组中,这个sensors的类型是msm_sensor_info。

static void init_sensor_alias(void)
{
	char buf[MAX_SENSOR_INFO_LEN];
	char *psensor_info = NULL, *psave1 = NULL;

	if (read_line_from_file(SENSOR_INFO_SYSFS, buf,//读取/sys/module/msm_thermal/sensor_info节点信息
			MAX_SENSOR_INFO_LEN) <= 0)
		return;

	psensor_info = strtok_r(buf, " ", &psave1);
	while (psensor_info != NULL && sensor_cnt < MAX_NUM_SENSORS) {
		char *psensor = NULL;
		char *psave2 = NULL;

		psensor = strtok_r(psensor_info, ":", &psave2);
		if ((psensor == NULL) || strlcpy(sensors[sensor_cnt].type,//type
			psensor, MAX_SENSOR_NAME_LEN) >= MAX_SENSOR_NAME_LEN)
			goto next_sensor;

		psensor = strtok_r(NULL, ":", &psave2);
		if ((psensor == NULL) || strlcpy(sensors[sensor_cnt].name,//name
			psensor, MAX_SENSOR_NAME_LEN) >= MAX_SENSOR_NAME_LEN)
			goto next_sensor;

		if (psensor[strlen(psensor) + 1] != ':') {
			psensor = strtok_r(NULL, ":", &psave2);
			if ((psensor == NULL) ||
				strlcpy(sensors[sensor_cnt].alias, psensor,//alias
				MAX_SENSOR_NAME_LEN) >= MAX_SENSOR_NAME_LEN)
					goto next_sensor;
		}

		psensor = strtok_r(NULL, ":", &psave2);
		if (psensor == NULL)
			goto next_sensor;
		sensors[sensor_cnt].scaling_factor =
			(int)strtol( psensor, NULL, 10);
		if (sensors[sensor_cnt].scaling_factor <= 0)//scaling_factor
			sensors[sensor_cnt].scaling_factor = 1;

		sensor_cnt++;
next_sensor:
		psensor_info = strtok_r(NULL, " ", &psave1);
	}
	dbgmsg("%s: sensor_cnt:%d\n", __func__, sensor_cnt);
}

我们来先看下节点/sys/module/msm_thermal/sensor_info节点读取到的信息。以冒号为分割第一个是sensor的type,第二个是sensor的name,第三个是alias,第四个是scaling_factor。

tsens:tsens_tz_sensor0:pop_mem:1 tsens:tsens_tz_sensor1::1 tsens:tsens_tz_sensor2::1 tsens:tsens_tz_sensor3:cpu0-cpu2:1 tsens:tsens_tz_sensor4:cpu1-cpu3:1 adc:pa_therm0::1 adc:case_therm::1 alarm:pm8909_tz::1000 adc:xo_therm::1 adc:xo_therm_buf::1

2.2 创建sensor

创建sensor有两种方法,一种读取sys/devices/vitual/thermal下的设备创建,另一种可以直接做一个sensor_info的数组,直接遍历数组创建sensor。

2.2.1 读取thermal节点创建sensor

再来看看parse_thermal_zones函数,这个函数主要看/sys/devices/virtual/thermal下面每个目录下的type 是否和我们前面保存的sensors数组中的sensor的name一样,不一样我们直接跳过。一样的话,我们在根据这个sensor的type调用不同的函数。

static void parse_thermal_zones(void)
{
	DIR *tdir = NULL;
	struct dirent *tdirent = NULL;
	char name[MAX_PATH] = {0};
	char cwd[MAX_PATH] = {0};
	int cnt = 0, ret = 0;

	if (!getcwd(cwd, sizeof(cwd)))
		return;

	if (sensor_cnt <= 0)
		return init_user_space_sensors();

	ret = chdir(THERMAL_SYSFS); /* Change dir to read the entries. Doesnt work
                                 otherwise */
	tdir = opendir(THERMAL_SYSFS);//sys/devices/virtual/thermal目录
	if (!tdir || ret) {
		msg("%s: Unable to open %s\n", __func__, THERMAL_SYSFS);
		return;
	}
	while ((tdirent = readdir(tdir))) {
		char buf[MAX_PATH];
		DIR *tzdir = NULL;
		tzdir = opendir(tdirent->d_name);
		if (!tzdir)
			continue;
		snprintf(name, MAX_PATH, SENSOR_TZ_TYPE, tdirent->d_name);//sys/devices/virtual/thermal目录下个各个子目录下的type值
		dbgmsg("%s: Opening %s\n", __func__, name);
		ret = read_line_from_file(name, buf, sizeof(buf));
		if (ret <= 0)
			continue;
		buf[strlen(buf) -1] = '\0';
		for (cnt = 0; cnt < sensor_cnt; cnt++) {
			if (strncmp(buf, sensors[cnt].name,//每一个type值和sensors数组中sensor的那么做对比,不同直接continue
					MAX_SENSOR_NAME_LEN))
				continue;
			if (!strncmp(sensors[cnt].type, TSENS_TYPE,//类型不同调用不同的函数
					strlen(TSENS_TYPE))
				|| !strncmp(sensors[cnt].type, LLM_TYPE,
                                        strlen(LLM_TYPE))) {
				add_tgt_tsens_sensors(sensors[cnt].name, &sensors[cnt]);
				dbgmsg(
				"%s: Added sensor: %s to %s sensor list\n",
				__func__, buf, sensors[cnt].type);
			} else if (!strncmp(sensors[cnt].type, ALARM_TYPE,
					strlen(ALARM_TYPE)) ||
				(!strncmp(sensors[cnt].type, ADC_TYPE,
					strlen(ADC_TYPE)))) {
				add_tgt_gen_sensors(sensors[cnt].name,
							&sensors[cnt]);
				dbgmsg(
				"%s: Added sensor: %s to %s sensor list\n",
				__func__, buf, sensors[cnt].type);
			}
		}
		closedir(tzdir);
	}
	closedir(tdir);
	ret = chdir(cwd); /* Restore current working dir */
}

我们先来看下sys/devices/virtual/thermal目录下的各个目录

然后再来看各个目录下type的值。

温控daemon(三)sensor初始化_第1张图片

我们接着看上面根据sensor的type不同调用了不同的函数。 如果是tsens和llm的type调用add_tgt_tsens_sensors函数

static int add_tgt_tsens_sensors(char *sensor_name, struct msm_sensor_info *sens_info)
{
	int ret_val = 0;
	struct sensor_info *sensor;

	sensor = malloc(sizeof(struct sensor_info));//创建sensor
	if (sensor == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor, 0, sizeof(struct sensor_info));

	sensor->name = malloc(MAX_SENSOR_NAME_LEN);
	if (sensor->name == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor->name, 0, MAX_SENSOR_NAME_LEN);

	strlcpy(sensor->name, sensor_name, MAX_SENSOR_NAME_LEN);
	sensor->setup = tsens_sensors_setup;//获取到sensor的fd,就是各个zone下面的temp文件
	sensor->shutdown = tsens_sensors_shutdown;//close fd
	sensor->get_temperature = tsens_sensor_get_temperature;//获取温度的方法,从fd读取
	sensor->get_trip_temperature = NULL;
	sensor->interrupt_wait = tsens_sensor_interrupt_wait;
	sensor->update_thresholds = tsens_sensor_update_thresholds;
	sensor->tzn = 0;
	sensor->data = NULL;
	sensor->interrupt_enable = 1;
	sensor->scaling_factor = sens_info->scaling_factor;
	pthread_mutex_init(&(sensor->read_mtx), NULL);
	add_tgt_sensor(sensor);//新建一个sensors_mgr_sensor_info对象

error_handler:
	if (ret_val) {
		if (sensor) {
			if (sensor->name)
				free(sensor->name);
			free(sensor);
		}
	}
	return ret_val;
}

add_tgt_sensor函数就是新建一个sensors_mgr_sensor_info对象,并且将sensor_info中的name alias,方法都复制过来。

static int add_tgt_sensor(struct sensor_info *sensor)
{
	int ret_val = 0;
	struct sensors_mgr_sensor_info *sensor_mgr = NULL;

	dbgmsg("%s: Add sensor:%s to sensor list\n", __func__, sensor->name);
	sensor_mgr = malloc(sizeof(struct sensors_mgr_sensor_info));
	if (sensor_mgr == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor_mgr, 0, sizeof(struct sensors_mgr_sensor_info));

	sensor_mgr->name = sensor->name;
	sensor_mgr->alias = find_alias(sensor->name);

	if (sensor->setup(sensor) == 0) {//会在这里调用sensor中的setup获取sensor的fd
		msg("%s: %s sensor setup failed failed.\n",
				__func__, sensor->name);
		ret_val = -(EFAULT);
		goto error_handler;
	}

	sensor_mgr->data = (void*) sensor;
	sensor->sensor_mgr = sensor_mgr;

	sensor_mgr->get_temperature = generic_read;
	sensor_mgr->shutdown = generic_shutdown;

	if (sensor->interrupt_wait)
		sensor_mgr->wait = generic_wait;
	if (sensor->update_thresholds)
		sensor_mgr->update_thresholds = generic_update_thresholds;
	if (sensor->get_trip_temperature)
		sensor_mgr->get_trip_temperature = generic_trip_temp_read;

	sensors_manager_add_sensor(sensor_mgr);//将这个sensor放入sensor_list中

error_handler:
	if (ret_val) {
		if (sensor_mgr)
			free(sensor_mgr);
	}
	return ret_val;
}

如果是sensor的type是alarm和adc的话调用add_tgt_gen_sensors函数,这个函数和上面的函数类似,最后也是调用add_tgt_sensor函数创建sensors_mgr_sensor_info对象最后加入sensor_list中

static int add_tgt_gen_sensors(char *sensor_name, struct msm_sensor_info *sens_info)
{
	int ret_val = 0;
	struct sensor_info *sensor;

	sensor = malloc(sizeof(struct sensor_info));
	if (sensor == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor, 0, sizeof(struct sensor_info));

	sensor->name = malloc(MAX_SENSOR_NAME_LEN);
	if (sensor->name == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor->name, 0, MAX_SENSOR_NAME_LEN);

	strlcpy(sensor->name, sensor_name, MAX_SENSOR_NAME_LEN);
	sensor->setup = thermal_sensor_setup;
	sensor->shutdown = thermal_sensor_shutdown;
	sensor->get_temperature = thermal_sensor_get_temperature;
	sensor->get_trip_temperature = NULL;
	sensor->update_thresholds = NULL;
	sensor->scaling_factor = sens_info->scaling_factor;
	if (!strncmp(sens_info->type, ALARM_TYPE, strlen(ALARM_TYPE))) {
		sensor->interrupt_enable = 1;
		sensor->interrupt_wait = thermal_sensor_interrupt_wait;
	} else if (!strncmp(sens_info->type, USERSPACE_TYPE,
				strlen(USERSPACE_TYPE))) {
		sensor->interrupt_enable = 1;
		sensor->interrupt_wait = thermal_sensor_interrupt_wait;
		sensor->update_thresholds = thermal_sensor_update_thresholds;
		sensor->get_trip_temperature = thermal_sensor_get_trip_temp;
		sensor->scaling_factor = 1000;
	} else {
		sensor->interrupt_enable = 0;
		sensor->interrupt_wait = NULL;
	}
	pthread_mutex_init(&(sensor->read_mtx), NULL);
	sensor->tzn = 0;
	sensor->data = NULL;
	add_tgt_sensor(sensor);

error_handler:
	if (ret_val) {
		if (sensor) {
			if (sensor->name)
				free(sensor->name);
			free(sensor);
		}
	}
	return ret_val;
}

我们再来重新看下add_tgt_sensor函数,注意我们传进来的参数sensor类型是sensor_info,而这里我们新建的sensor_mgr是sensors_mgr_sensor_info

static int add_tgt_sensor(struct sensor_info *sensor)
{
	int ret_val = 0;
	struct sensors_mgr_sensor_info *sensor_mgr = NULL;

	dbgmsg("%s: Add sensor:%s to sensor list\n", __func__, sensor->name);
	sensor_mgr = malloc(sizeof(struct sensors_mgr_sensor_info));
	if (sensor_mgr == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor_mgr, 0, sizeof(struct sensors_mgr_sensor_info));

	sensor_mgr->name = sensor->name;//name直接使用
	sensor_mgr->alias = find_alias(sensor->name);//从sensors数组中找

	if (sensor->setup(sensor) == 0) {//调用sensor的setup函数
		msg("%s: %s sensor setup failed failed.\n",
				__func__, sensor->name);
		ret_val = -(EFAULT);
		goto error_handler;
	}

	sensor_mgr->data = (void*) sensor;//将sensor放入sensor_mgr的data
	sensor->sensor_mgr = sensor_mgr;

	sensor_mgr->get_temperature = generic_read;//sensor_mgr的函数都是最后通过其data(sensor的各个函数执行)
	sensor_mgr->shutdown = generic_shutdown;

	if (sensor->interrupt_wait)
		sensor_mgr->wait = generic_wait;
	if (sensor->update_thresholds)
		sensor_mgr->update_thresholds = generic_update_thresholds;
	if (sensor->get_trip_temperature)
		sensor_mgr->get_trip_temperature = generic_trip_temp_read;

	sensors_manager_add_sensor(sensor_mgr);

error_handler:
	if (ret_val) {
		if (sensor_mgr)
			free(sensor_mgr);
	}
	return ret_val;
}

我们举个读取温度的为例,最终就是通过sensor_mgr的data,就是sensor的get_temperature函数执行。

static int generic_read(struct sensors_mgr_sensor_info *sensor_mgr)
{
	struct sensor_info *sensor = (struct sensor_info *)sensor_mgr->data;
	return sensor->get_temperature(sensor);
}

我们再来看sensors_manager_add_sensor函数,将sensor_mgr放入sensor_list列表中。然后创建了一个线程执行sensor_monitor函数,sensor_mgr作为参数传入sensor_monitor函数。

int sensors_manager_add_sensor(struct sensors_mgr_sensor_info *sensor_mgr)
{
	if (sensor_mgr == NULL) {
		msg("%s: Invalid argument\n", __func__);
		return -(EINVAL);
	}

	dbgmsg("%s: add sensor %s\n", __func__, sensor_mgr->name);
	if (!sensor_mgr->default_polling_interval)
		sensor_mgr->default_polling_interval = SENSOR_DEFAULT_POLLING_INTERVAL;
	/* Just add new device to begining of list */
	sensor_mgr->next_sensor = sensor_list;
	sensor_list = sensor_mgr;
	sensor_cnt++;
	if (sensor_mgr->alias)
		alias_cnt++;

	pthread_mutex_init(&(sensor_mgr->req_wait_mutex), NULL);
	pthread_cond_init(&(sensor_mgr->req_wait_cond), NULL);
	pthread_create(&(sensor_mgr->monitor_thread), NULL,
			       sensor_monitor, sensor_mgr);
	return 0;
}

2.2.2 sensor监控函数

下面我们就来看下sensor_monitor函数,这个函数在没创建一个sensor最后放入sensor_list的时候开启一个线程对该sensor进行监控。

static void *sensor_monitor(void *vsensor_mgr)
{
	struct sensors_mgr_sensor_info *sensor_mgr = vsensor_mgr;

	while (sensor_mgr->thread_shutdown != 1) {//这个只有在sensor被remove的时候才会退出
		/* Wait here until there is actually a request to process */
		if (!sensor_mgr->req_active) {
			dbgmsg("%s: %s Wait for client request.\n", __func__, sensor_mgr->name);
			pthread_mutex_lock(&(sensor_mgr->req_wait_mutex));
			while (!sensor_mgr->req_active) {//只有当sensor_mgr的req_active为1该线程才会继续
				pthread_cond_wait(&(sensor_mgr->req_wait_cond),
						&(sensor_mgr->req_wait_mutex));
			}
			pthread_mutex_unlock(&(sensor_mgr->req_wait_mutex));
		}
		dbgmsg("%s: %s Sensor wait.\n", __func__, sensor_mgr->name);
		sensor_wait(sensor_mgr);//线程等待相关

		if (sensor_mgr->get_trip_temperature)
			sensor_mgr->last_reading =
				sensor_mgr->get_trip_temperature(sensor_mgr);
		else
			sensor_mgr->last_reading =//获取温度保存在last_reading中
				sensor_mgr->get_temperature(sensor_mgr);
		dbgmsg("%s: %s Reading %d .\n", __func__, sensor_mgr->name,
		       sensor_mgr->last_reading);
		.......//log
		notify_clnts(sensor_mgr);//调用notify_clnts通知各个client
	}

	return NULL;
}

我们先来看下sensor_wait就是

static void sensor_wait(struct sensors_mgr_sensor_info *sensor_mgr)
{
	if (sensor_mgr->wait)
		sensor_mgr->wait(sensor_mgr);
	else {
		uint32_t polling_interval =
			(sensor_mgr->active_thresh.polling_interval_valid)?
			(sensor_mgr->active_thresh.polling_interval):
			(sensor_mgr->default_polling_interval);
		dbgmsg("%s: %s Wait start. %dms\n", __func__, sensor_mgr->name, polling_interval);
		usleep(polling_interval*1000);
		dbgmsg("%s: %s Wait done.\n", __func__, sensor_mgr->name);
	}
}

每一个sensor_mgr的wait函数,最后都是调用的sensor_info的interrupt_wait函数,我们来看下如下的,都是利用condition来等待。

void thermal_sensor_interrupt_wait(struct sensor_info *sensor)
{
	struct thermal_sensor_data *sensor_data;

	if (NULL == sensor ||
	    NULL == sensor->data) {
		msg("%s: unexpected NULL", __func__);
		return;
	}

	sensor_data = (struct thermal_sensor_data *) sensor->data;

	if (sensor->interrupt_enable) {
		/* Wait for sensor threshold condition */
		pthread_mutex_lock(&(sensor_data->thermal_sensor_mutex));
		while (!sensor_data->threshold_reached) {
			pthread_cond_wait(&(sensor_data->thermal_sensor_condition),
					&(sensor_data->thermal_sensor_mutex));
		}
		sensor_data->threshold_reached = 0;
		pthread_mutex_unlock(&(sensor_data->thermal_sensor_mutex));
	}
}

我们再来看下notify_clnts函数,先是遍历了client的request.thresh然后调用回调,后面还调用了update_active_thresh函数最后会调用sensor_info的update_thresholds,我们后续再分析。

static int notify_clnts(struct sensors_mgr_sensor_info *sensor_mgr)
{
	struct sensor_client_type *client = NULL;
	enum sensor_notify_event_type thresh_event;

	if (sensor_mgr == NULL)
		return -(EINVAL);

	client = sensor_mgr->client_list;

	THERM_MUTEX_LOCK(&ts_clnt_mtx);
	while (client != NULL) {
		if (client->request_active) {
			struct thresholds_req_t *thresh = &client->request.thresh;//遍历client的request.thresh

			/* Notify clients of thresh crossings */
			thresh_event = SENSOR_NOTIFY_NORMAL_THRESH_EVENT;
			if (thresh->high_valid &&
			    (sensor_mgr->last_reading >= thresh->high)) {
				thresh_event = SENSOR_NOTIFY_HIGH_THRESH_EVENT;
			} else if (thresh->low_valid &&
				   (sensor_mgr->last_reading <= thresh->low)) {
				thresh_event = SENSOR_NOTIFY_LOW_THRESH_EVENT;
			}

			if (thresh_event != SENSOR_NOTIFY_NORMAL_THRESH_EVENT) {
				client->request_active = 0;
				client->request.notify_cb_func(client,//调用request的回调函数
							       thresh_event,
							       sensor_mgr->last_reading,
							       client->request.notify_cb_data);
			}
		}
		client = client->next_clnt;
	}
	THERM_MUTEX_UNLOCK(&ts_clnt_mtx);
	update_active_thresh(sensor_mgr);
	return 0;
}

 

2.2.3 读取sensor_info数组创建sensor

最后我们再来看看,bcl sensor的创建。这里和前面alarm adc tsens类型的sensor创建不一样,前面我们通过读取节点信息等等一步步最后得到sensor_info后再调用的add_tgt_sensor函数创建最后色sensor。这里直接调用了add_tgt_sensors_set函数。

int sensors_init(int minimum_mode)
{
        ......
	/* BCL */
	if (add_tgt_sensors_set(bcl_sensors,
			   ARRAY_SIZE(bcl_sensors)) != 0) {
		msg("%s: Error adding BCL TS\n", __func__);
		ret_val = -(EFAULT);
	}

	return ret_val;
}

我们来看下add_tgt_sensors_set函数,这里就是遍历传进来的bcl_sensors的list,这个已经是sensor_info类型的数组了,然后我们遍历这个数组,依次调用add_tgt_sensor创建sensor。

int add_tgt_sensors_set(struct sensor_info *sensor_arr, int arr_size)
{
	int idx = 0;
	int ret_val = 0;

	for (idx = 0; idx < arr_size; idx++) {
		if (add_tgt_sensor(&sensor_arr[idx]) != 0) {
			msg("%s: Error adding %s\n", __func__,
			    sensor_arr[idx].name);
			ret_val = -(EFAULT);
			break;
		}
	}

	return ret_val;
}

我们来看下bcl_sensors数组,目前只有一个sensor,就是sensor_info的结构体。

static struct sensor_info bcl_sensors[] = {
	{
		.name = "bcl",
		.setup = bcl_setup,
		.shutdown = bcl_shutdown,
		.get_temperature = bcl_get_iavail,
		.interrupt_wait = bcl_interrupt_wait,
		.update_thresholds = bcl_update_thresholds,
		.tzn = 0,
		.data = NULL,
		.get_trip_temperature = NULL,
		.interrupt_enable = 1,
	}
};

这样sensor的各个函数都分析了,下面我们从sensor监控温度的流程上进一步分析。

3.  sensor监控温度的流程

上面我们只是分析了一些函数,没有从流程上分析sensor是如何监控温度以及和各个算法联系起来的。

之前分析过add_tgt_tsens_sensors函数,这个函数的sensor主要是监控cpu、gpu的温度。我们再来看下这个函数。在add_tgt_sensor函数中我们会调用每个sensor的setup方法,每个sensor的setup方法我们要注意,然后我么还需要注意tsens_sensor_interrupt_wait和tsens_sensor_update_thresholds函数。

static int add_tgt_tsens_sensors(char *sensor_name, struct msm_sensor_info *sens_info)
{
	int ret_val = 0;
	struct sensor_info *sensor;

	sensor = malloc(sizeof(struct sensor_info));
	if (sensor == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor, 0, sizeof(struct sensor_info));

	sensor->name = malloc(MAX_SENSOR_NAME_LEN);
	if (sensor->name == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor->name, 0, MAX_SENSOR_NAME_LEN);

	strlcpy(sensor->name, sensor_name, MAX_SENSOR_NAME_LEN);
	sensor->setup = tsens_sensors_setup;
	sensor->shutdown = tsens_sensors_shutdown;
	sensor->get_temperature = tsens_sensor_get_temperature;
	sensor->get_trip_temperature = NULL;
	sensor->interrupt_wait = tsens_sensor_interrupt_wait;//有自己的wait函数
	sensor->update_thresholds = tsens_sensor_update_thresholds;//更新sensor的thresholds的low和high
	sensor->tzn = 0;
	sensor->data = NULL;
	sensor->interrupt_enable = 1;//允许中断
	sensor->scaling_factor = sens_info->scaling_factor;
	pthread_mutex_init(&(sensor->read_mtx), NULL);
	add_tgt_sensor(sensor);

error_handler:
	if (ret_val) {
		if (sensor) {
			if (sensor->name)
				free(sensor->name);
			free(sensor);
		}
	}
	return ret_val;
}

我们先来看下sensor_monitor函数,先需要sensor的req_active为1,代表这个时候sensor的client有申请(这个在后面的算法会提到),这个时候我们再调用sensor_wait,这个函数会去等待

static void *sensor_monitor(void *vsensor_mgr)
{
	struct sensors_mgr_sensor_info *sensor_mgr = vsensor_mgr;

	while (sensor_mgr->thread_shutdown != 1) {
		/* Wait here until there is actually a request to process */
		if (!sensor_mgr->req_active) {
			dbgmsg("%s: %s Wait for client request.\n", __func__, sensor_mgr->name);
			pthread_mutex_lock(&(sensor_mgr->req_wait_mutex));
			while (!sensor_mgr->req_active) {
				pthread_cond_wait(&(sensor_mgr->req_wait_cond),
						&(sensor_mgr->req_wait_mutex));
			}
			pthread_mutex_unlock(&(sensor_mgr->req_wait_mutex));
		}
		dbgmsg("%s: %s Sensor wait.\n", __func__, sensor_mgr->name);
		sensor_wait(sensor_mgr);

		if (sensor_mgr->get_trip_temperature)
			sensor_mgr->last_reading =
				sensor_mgr->get_trip_temperature(sensor_mgr);
		else
			sensor_mgr->last_reading =
				sensor_mgr->get_temperature(sensor_mgr);
		dbgmsg("%s: %s Reading %d .\n", __func__, sensor_mgr->name,
		       sensor_mgr->last_reading);
		if (!strncmp(sensor_mgr->name, "bcl", 3)) {
			thermalmsg(LOG_LVL_DBG, (LOG_LOGCAT | LOG_LOCAL_SOCKET),
				   "%s:%s:%d mA\n", SENSORS,
				   sensor_mgr->name, sensor_mgr->last_reading);
		} else if (!strncmp(sensor_mgr->name, "bcm", 3)) {
			thermalmsg(LOG_LVL_DBG, (LOG_LOGCAT | LOG_LOCAL_SOCKET),
				   "%s:%s:%d mPercent\n", SENSORS,
				   sensor_mgr->name, sensor_mgr->last_reading);
		} else {
			thermalmsg(LOG_LVL_DBG, (LOG_LOGCAT | LOG_LOCAL_SOCKET),
				   "%s:%s:%d mC\n", SENSORS,
				   sensor_mgr->name, sensor_mgr->last_reading);
		}
		notify_clnts(sensor_mgr);
	}

	return NULL;
}

我们来看这个sensor_wait函数,sensor有wait函数就去调用wait函数。没有就用usleep来替代,这个时候polling_interval就是每个配置算法中的采样率。

static void sensor_wait(struct sensors_mgr_sensor_info *sensor_mgr)
{
	if (sensor_mgr->wait)
		sensor_mgr->wait(sensor_mgr);
	else {
		uint32_t polling_interval =
			(sensor_mgr->active_thresh.polling_interval_valid)?
			(sensor_mgr->active_thresh.polling_interval):
			(sensor_mgr->default_polling_interval);
		dbgmsg("%s: %s Wait start. %dms\n", __func__, sensor_mgr->name, polling_interval);
		usleep(polling_interval*1000);
		dbgmsg("%s: %s Wait done.\n", __func__, sensor_mgr->name);
	}
}

我们再来看上面的sensor的wait函数,这个函数先看这个sensor是否允许中断,如果允许然后一直等待condition,直到某个地方broadcast这个condition。下一步我们就要看哪个地方broadcast这个condition。

void tsens_sensor_interrupt_wait(struct sensor_info *sensor)
{
	struct tsens_data *tsens;

	if (NULL == sensor ||
	    NULL == sensor->data) {
		msg("%s: unexpected NULL", __func__);
		return;
	}
	if (sensor->interrupt_enable) {
		tsens = (struct tsens_data *) sensor->data;
		/* Wait for sensor threshold condition */
		pthread_mutex_lock(&(tsens->tsens_mutex));
		while (!tsens->threshold_reached) {
			pthread_cond_wait(&(tsens->tsens_condition),
					&(tsens->tsens_mutex));
		}
		tsens->threshold_reached = 0;
		pthread_mutex_unlock(&(tsens->tsens_mutex));
	}
}

我们来看前面的tsens_sensors_setup函数,最后会建一个thread来执行tsens_uevent函数。

int tsens_sensors_setup(struct sensor_info *sensor)
{
	int fd = -1;
	int sensor_count = 0;
	char name[MAX_PATH] = {0};
	int tzn = 0;
	struct tsens_data *tsens = NULL;

	tzn = get_tzn(sensor->name);
	if (tzn < 0) {
		msg("No thermal zone device found in the kernel for sensor %s\n", sensor->name);
		return sensor_count;
	}
	sensor->tzn = tzn;

	snprintf(name, MAX_PATH, TZ_TEMP, sensor->tzn);
	fd = open(name, O_RDONLY);
	if (fd < 0) {
		msg("%s: Error opening %s\n", __func__, TZ_TEMP);
		return sensor_count;
	}

	/* Allocate TSENS data */
	tsens = (struct tsens_data *) malloc(sizeof(struct tsens_data));
	if (NULL == tsens) {
		msg("%s: malloc failed", __func__);
		close(fd);
		return sensor_count;
	}
	memset(tsens, 0, sizeof(struct tsens_data));
	sensor->data = (void *) tsens;

	sensor_count++;
	pthread_mutex_init(&(tsens->tsens_mutex), NULL);
	pthread_cond_init(&(tsens->tsens_condition), NULL);
	tsens->sensor_shutdown = 0;
	tsens->threshold_reached = 0;
	tsens->sensor = sensor;
	sensor->fd = fd;
	init_tsens_trip_type(tsens);

	if (sensor->interrupt_enable) {
		pthread_create(&(tsens->tsens_thread), NULL,
			       tsens_uevent, sensor);
	}

	return sensor_count;
}

我们来分析下这个函数,这个函数就是去读每个sensor的/sys/devices/virtual/thermal/thermal_zone%d/type节点了,然后使用poll,看看是否有事件可以读取,然后再去将上面提到的condition去broadcast,这样sensor_wait的等待就结束了。那么这个节点什么时候会有事件呢,稍后我们会提到一个update threshold这个,这个最后就是往sensor驱动下一个threshold的low和high,只要sensor驱动读取的数据大于high或者小于low,就会触发/sys/devices/virtual/thermal/thermal_zone%d/type节点了,就会有数据上来,这个时候sensor_wait就结束等待了。

static void *tsens_uevent(void *data)
{
	int err = 0;
	struct sensor_info *sensor = (struct sensor_info *)data;
	struct pollfd fds;
	int fd;
	char uevent[MAX_PATH] = {0};
	char buf[MAX_PATH] = {0};
	struct tsens_data *tsens = NULL;

	if (NULL == sensor ||
	    NULL == sensor->data) {
		msg("%s: unexpected NULL", __func__);
		return NULL;
	}
	tsens = (struct tsens_data *) sensor->data;

	/* Looking for tsens uevent */
	snprintf(uevent, MAX_PATH, TZ_TYPE, sensor->tzn);

	fd = open(uevent, O_RDONLY);
	if (fd < 0) {
		msg("Unable to open %s to receive notifications.\n", uevent);
		return NULL;
	};

	while (!tsens->sensor_shutdown) {
		fds.fd = fd;
		fds.events = POLLERR|POLLPRI;
		fds.revents = 0;
		err = poll(&fds, 1, -1);
		if (err == -1) {
			msg("Error in uevent poll.\n");
			break;
		}

		err = read(fd, buf, sizeof(buf));
		if (err < 0)
			msg("sysfs[%s] read error:%d\n", uevent, errno);

		lseek(fd, 0, SEEK_SET);

		dbgmsg("%s: %s", __func__, buf);

		/* notify the waiting threads */
		pthread_mutex_lock(&(tsens->tsens_mutex));
		tsens->threshold_reached = 1;//sensor的threshold被触发
		pthread_cond_broadcast(&(tsens->tsens_condition));//broadcast condition
		pthread_mutex_unlock(&(tsens->tsens_mutex));
	}
	close(fd);

	return NULL;
}

我们再来看函数,就会去遍历每一个client,如果当前的温度超过了该client thresh的high或者low就会调用该client的回调(其实就去处理该配置算法的流程了),最后还会调用update_active_thresh函数来更新sensor的thresh值。

static int notify_clnts(struct sensors_mgr_sensor_info *sensor_mgr)
{
	struct sensor_client_type *client = NULL;
	enum sensor_notify_event_type thresh_event;

	if (sensor_mgr == NULL)
		return -(EINVAL);

	client = sensor_mgr->client_list;

	THERM_MUTEX_LOCK(&ts_clnt_mtx);
	while (client != NULL) {
		if (client->request_active) {
			struct thresholds_req_t *thresh = &client->request.thresh;

			/* Notify clients of thresh crossings */
			thresh_event = SENSOR_NOTIFY_NORMAL_THRESH_EVENT;
			if (thresh->high_valid &&
			    (sensor_mgr->last_reading >= thresh->high)) {
				thresh_event = SENSOR_NOTIFY_HIGH_THRESH_EVENT;
			} else if (thresh->low_valid &&
				   (sensor_mgr->last_reading <= thresh->low)) {
				thresh_event = SENSOR_NOTIFY_LOW_THRESH_EVENT;
			}

			if (thresh_event != SENSOR_NOTIFY_NORMAL_THRESH_EVENT) {
				client->request_active = 0;
				client->request.notify_cb_func(client,//调用各个client的回调
							       thresh_event,
							       sensor_mgr->last_reading,
							       client->request.notify_cb_data);
			}
		}
		client = client->next_clnt;
	}
	THERM_MUTEX_UNLOCK(&ts_clnt_mtx);
	update_active_thresh(sensor_mgr);
	return 0;
}

我们来看下update_active_thresh函数,其实就是遍历各个client获取thresh.high thresh.low然后比较保存在sensor中,然后调用sensor的update_thresholds函数。这函数在各个算法初始化的时候都会去调用,用来设置各个client thresh的low、high然后设置到sensor中(比如ss算法中会去调用sensors_manager_set_thresh_lvl函数设置client的thresh,最后还是调用update_active_thresh函数来更新sensor中的值)

static int update_active_thresh(struct sensors_mgr_sensor_info *sensor_mgr)
{
	struct sensor_client_type  *client = NULL;
	struct sensor_thresh_req *active = NULL;
	uint8_t                active_req = 0;


	if (sensor_mgr == NULL)
		return -(EINVAL);

	active = &sensor_mgr->active_thresh;

	memset(active, 0, sizeof(struct sensor_thresh_req));
	active->thresh.low = INT32_MIN;
	active->thresh.high  = INT32_MAX;
	active->polling_interval = UINT32_MAX;

	client = sensor_mgr->client_list;
	THERM_MUTEX_LOCK(&ts_clnt_mtx);
	while (client != NULL) {
		if (!client->request_active) {
			client = client->next_clnt;
			continue;
		}

		struct sensor_thresh_req *thresh = &client->request;
		if (thresh->thresh.descending_threshold)
			active->thresh.descending_threshold = 1;
		/* Find active high */
		if (thresh->thresh.high_valid) {
			active->thresh.high_valid = 1;
			active->thresh.high = MIN(active->thresh.high,
							thresh->thresh.high);
		}

		/* Find active low */
		if (thresh->thresh.low_valid) {
			active->thresh.low_valid = 1;
			active->thresh.low = MAX(active->thresh.low,
						       thresh->thresh.low);
		}

		/* Find min polling interval */
		if (thresh->polling_interval_valid) {
			active->polling_interval_valid = 1;
			active->polling_interval = MIN(active->polling_interval,
							     thresh->polling_interval);
		}

		active_req = 1;
		client = client->next_clnt;
	}

	if ((active->thresh.high > active->thresh.low) &&//当high大于low 并且high_valid或者low_valid才需要更新sensor的threshold
	    (active->thresh.high_valid || active->thresh.low_valid)) {
		/* We can take advantage of interrupt */
		sensor_mgr->active_thresh_valid = 1;
	} else {
		sensor_mgr->active_thresh_valid = 0;
	}


	/* Room for optimization if thresholds didn't change. */
	if (sensor_mgr->active_thresh_valid &&
	    sensor_mgr->update_thresholds) {
		sensor_mgr->update_thresholds(sensor_mgr);//更新sensor的threshold
	}

	if (!sensor_mgr->req_active && active_req) {
		/* Advertise there is now an active request available */
		pthread_mutex_lock(&(sensor_mgr->req_wait_mutex));
		sensor_mgr->req_active = 1;
		pthread_cond_broadcast(&(sensor_mgr->req_wait_cond));
		pthread_mutex_unlock(&(sensor_mgr->req_wait_mutex));
	} else {
		sensor_mgr->req_active = active_req;
	}
	THERM_MUTEX_UNLOCK(&ts_clnt_mtx);
	return 0;
}

我们再来看上面这个sensor的update_thresholds函数

void tsens_sensor_update_thresholds(struct sensor_info *sensor,
				    struct thresholds_req_t *thresh)
{
	struct tsens_data *tsens;

	if (NULL == thresh ||
	    NULL == sensor ||
	    NULL == sensor->data) {
		msg("%s: unexpected NULL", __func__);
		return;
	}
	tsens = (struct tsens_data *) sensor->data;

	/* Convert thresholds to Celsius for TSENS*/
	thresh->high = RCONV(thresh->high);
	thresh->low = RCONV(thresh->low);

	set_thresholds(tsens, thresh);
}

主要还是看set_thresholds函数,这个函数主要会去设置 /sys/devices/virtual/thermal/thermal_zone%d/trip_point_%d_temp,其中一个是threshold的low,另一个是threshold的high,设置完之后还需要对/sys/devices/virtual/thermal/thermal_zone%d/trip_point_%d_type节点设置enabled或者disabled(注意这个里的enabled和disabled只是对sensor驱动下一次中断而言)。这样当sensor检测到温度大于high或者小于low,这个时候/sys/devices/virtual/thermal/thermal_zone%d/type节点就会有事件了,sensor_wait就不会去wait了,这样就可以调用各个client的回调来开启各个配置算法的流程。

static void set_thresholds(struct tsens_data *tsens, struct thresholds_req_t *thresh)
{
	char minname[MAX_PATH]= {0};
	char maxname[MAX_PATH]= {0};
	char buf[LVL_BUF_MAX] = {0};
	int ret = 0;
	int mintemp = 0;

	if (NULL == tsens) {
		msg("%s: unexpected NULL", __func__);
		return;
	}

	snprintf(minname, MAX_PATH, TSENS_TZ_TRIP_TEMP, tsens->sensor->tzn, tsens->trip_min);
	snprintf(maxname, MAX_PATH, TSENS_TZ_TRIP_TEMP, tsens->sensor->tzn, tsens->trip_max);

	/* Set thresholds in legal order */
	if (read_line_from_file(minname, buf, sizeof(buf)) > 0) {
		mintemp = atoi(buf);
	}

	if (thresh->high >= (mintemp / tsens->sensor->scaling_factor)) {
		/* set high threshold first */
		if (thresh->high_valid) {
			dbgmsg("Setting up TSENS thresholds high: %d\n", thresh->high);
			snprintf(buf, LVL_BUF_MAX, "%d", thresh->high * tsens->sensor->scaling_factor);
			ret = write_to_file(maxname, buf, strlen(buf));
			if (ret <= 0)
				msg("TSENS threshold high failed to set %d\n", thresh->high);
		}
		enable_threshold(tsens, tsens->trip_max, thresh->high_valid);

		if (thresh->low_valid) {
			dbgmsg("Setting up TSENS thresholds low: %d\n", thresh->low);
			snprintf(buf, LVL_BUF_MAX, "%d", thresh->low * tsens->sensor->scaling_factor);
			ret = write_to_file(minname, buf, strlen(buf));
			if (ret <= 0)
				msg("TSENS threshold low failed to set %d\n", thresh->low);
		}
		enable_threshold(tsens, tsens->trip_min, thresh->low_valid);

	} else {
		if (thresh->low_valid) {
			dbgmsg("Setting up TSENS thresholds low: %d\n", thresh->low);
			snprintf(buf, LVL_BUF_MAX, "%d", thresh->low * tsens->sensor->scaling_factor);
			ret = write_to_file(minname, buf, strlen(buf));
			if (ret <= 0)
				msg("TSENS threshold low failed to set %d\n", thresh->low);
		}
		enable_threshold(tsens, tsens->trip_min, thresh->low_valid);

		if (thresh->high_valid) {
			dbgmsg("Setting up TSENS thresholds high: %d\n", thresh->high);
			snprintf(buf, LVL_BUF_MAX, "%d", thresh->high * tsens->sensor->scaling_factor);
			ret = write_to_file(maxname, buf, strlen(buf));
			if (ret <= 0)
				msg("TSENS threshold high failed to set %d\n", thresh->high);
		}
		enable_threshold(tsens, tsens->trip_max, thresh->high_valid);
	}
}

上面我们基本分析了sensor监控温度的流程,上面我们分析的是tsens的sensor,下面我们再来看看下面sensor。有区分sensor的类型来做处理,有没有update_thresholds函数。有没有interrupt_wait函数的,如果没有interrupt_wait就是用usleep函数来达到wait的目的,wait的interval就是用算法配置中的采样率。

static int add_tgt_gen_sensors(char *sensor_name, struct msm_sensor_info *sens_info)
{
	int ret_val = 0;
	struct sensor_info *sensor;

	sensor = malloc(sizeof(struct sensor_info));
	if (sensor == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor, 0, sizeof(struct sensor_info));

	sensor->name = malloc(MAX_SENSOR_NAME_LEN);
	if (sensor->name == NULL) {
		msg("%s: malloc failed.\n", __func__);
		ret_val = -(ENOMEM);
		goto error_handler;
	}
	memset(sensor->name, 0, MAX_SENSOR_NAME_LEN);

	strlcpy(sensor->name, sensor_name, MAX_SENSOR_NAME_LEN);
	sensor->setup = thermal_sensor_setup;
	sensor->shutdown = thermal_sensor_shutdown;
	sensor->get_temperature = thermal_sensor_get_temperature;
	sensor->get_trip_temperature = NULL;
	sensor->update_thresholds = NULL;
	sensor->scaling_factor = sens_info->scaling_factor;
	if (!strncmp(sens_info->type, ALARM_TYPE, strlen(ALARM_TYPE))) {
		sensor->interrupt_enable = 1;
		sensor->interrupt_wait = thermal_sensor_interrupt_wait;//alarm类型sensor有wait函数,但是没有threshold
	} else if (!strncmp(sens_info->type, USERSPACE_TYPE,
				strlen(USERSPACE_TYPE))) {
		sensor->interrupt_enable = 1;
		sensor->interrupt_wait = thermal_sensor_interrupt_wait;
		sensor->update_thresholds = thermal_sensor_update_thresholds;
		sensor->get_trip_temperature = thermal_sensor_get_trip_temp;
		sensor->scaling_factor = 1000;
	} else {
		sensor->interrupt_enable = 0;//这个interrupt不允许
		sensor->interrupt_wait = NULL;
	}
	pthread_mutex_init(&(sensor->read_mtx), NULL);
	sensor->tzn = 0;
	sensor->data = NULL;
	add_tgt_sensor(sensor);

error_handler:
	if (ret_val) {
		if (sensor) {
			if (sensor->name)
				free(sensor->name);
			free(sensor);
		}
	}
	return ret_val;
}

这样sensor监控温度,sensor_monitor函数wait如何唤醒,以及如何启动配置算法的流程,都分析清楚了。

你可能感兴趣的:(android,thermal)