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