本文主要是介绍高通 slpi tcs3701_als_init,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
// set_client_request 设置 来自客服端的请求. 这个客户端是谁? 暂时理解为 hal 层吧…
publish_attributes 调用后,说明 ,sensor 已经准备好了,可以使用了.
此时 ,AP 测 可以查询到并且使用.
看下 tcs3701_als_init
tcs3701_common_init(this);
{tcs3701_state *state = (tcs3701_state*)this->state->state;// 1: 获取 服务. SNS_DIAG_SERVICE 和 SNS_SYNC_COM_PORT_SERVICE
// SNS_SYNC_COM_PORT_SERVICE 这个好像是上电的..struct sns_service_manager *smgr= this->cb->get_service_manager(this);state->diag_service = (sns_diag_service *)smgr->get_service(smgr, SNS_DIAG_SERVICE);state->scp_service = (sns_sync_com_port_service *)smgr->get_service(smgr, SNS_SYNC_COM_PORT_SERVICE);sns_memzero(&state->common, sizeof(tcs3701_common_state));// 2: 发送 请求 注册 interrupt timer 和 registry 这些平台 sensor . /* TCS3701 sensor fetches all common dependent sensor SUIDs. */if (TCS3701_ALS == state->sensor){state->common.start_hw_detect = false;tcs3701_send_suid_req(this, "interrupt", sizeof("interrupt"));tcs3701_send_suid_req(this, "timer", sizeof("timer"));}/* Send registry suid request at last */tcs3701_send_suid_req(this, "registry", sizeof("registry"));
}
看下 这个 tcs3701_send_suid_req 是怎么实现的
首先 看下 sensor 之间是怎么交流的.?
从图片可以看到 有个stream
requset 和 event 都是通过 stream
tcs3701_send_suid_req
{
{tcs3701_state *state = (tcs3701_state*)this->state->state;sns_service_manager *smgr = this->cb->get_service_manager(this);// 1: 获得 SNS_STREAM_SERVICE sns_stream_service *stream_service = (sns_stream_service*)smgr->get_service(smgr, SNS_STREAM_SERVICE);pb_buffer_arg data = (pb_buffer_arg){.buf = data_type, .buf_len = data_type_len};size_t encoded_len;uint8_t buffer[50];sns_memset(buffer, 0, sizeof(buffer));sns_suid_req suid_req = sns_suid_req_init_default;suid_req.has_register_updates = true;suid_req.register_updates = true;suid_req.data_type.funcs.encode = &pb_encode_string_cb;suid_req.data_type.arg = &data;if (NULL == state->fw_stream){
// 2: 创建 sensor stream .我们创建了一个 流 stream_service->api->create_sensor_stream(stream_service,this, sns_get_suid_lookup(), &state->fw_stream);}
// 序列化 ,存放在 buff 里面..encoded_len = pb_encode_request(buffer, sizeof(buffer), &suid_req, sns_suid_req_fields, NULL);if (0 < encoded_len){
// 发送前的一些设置. 设置 msg_id 设置为 SNS_SUID_MSGID_SNS_SUID_REQ . sns_request request = (sns_request){.request_len = encoded_len,.request = buffer, .message_id = SNS_SUID_MSGID_SNS_SUID_REQ};
// send_request : 发送请求. 有个问题,发送给谁??
看下注释:
看这样子像是 发送到其他 sensor 或者服务上的. 这里是发送到了SNS_STREAM_SERVICE 这个 server 上去了??
/*
* Send a request to some other service/Sensor. This request may* update or replace the existing stream, depending on the Sensor* specification* */
state->fw_stream->api->send_request(state->fw_stream, &request);}
}
}
总结下:这个函数做啥了:
1:创建 sensor_stream
2:设置 message id :SNS_SUID_MSGID_SNS_SUID_REQ
3: 发送.
在 tcs3701_common_init 注册了三个 platform sensor 的请求
interrupt , timer ,registry. 在高通中 ,把这种 叫做 datatype
说明 tcs3701 会用到 这三个 platform sensor
继续往下走的话,就是
tcs3701_als_publish_attributes(this);
static void tcs3701_als_publish_attributes(sns_sensor *const this)
{
// 就以 publish name 举例.其他的流程都是一样的..
// 最重要的 就是这个 函数.sns_publish_attributetcs3701_state *state = (tcs3701_state*)this->state->state;{char const name[] = "tcs3701";sns_std_attr_value_data value = sns_std_attr_value_data_init_default;value.str.funcs.encode = pb_encode_string_cb;value.str.arg = &((pb_buffer_arg){.buf = name, .buf_len = sizeof(name)});sns_publish_attribute(this, SNS_STD_SENSOR_ATTRID_NAME,&value, 1, false);}
}
看下 注释:
用 Attribute Service 来发布一个 sensor 的属性…
看下是怎么写的 这个函数. 这里我不得不吐槽下 SI ,函数前面加个限定竟然无法识别到这是个函数.气死!!!
SNS_SECTION(".text.sns")void
sns_publish_attribute(sns_sensor *const sensor,uint32_t attribute_id, sns_std_attr_value_data const *values,uint32_t values_len, bool completed)
{size_t attribute_len = 0;sns_std_attr std_attr = (sns_std_attr){ .attr_id = attribute_id, .value.values.funcs.encode = &sns_pb_encode_attr_cb,.value.values.arg = &((pb_buffer_arg){ .buf = values, .buf_len = values_len }) };if(pb_get_encoded_size(&attribute_len, sns_std_attr_fields, &std_attr)){sns_service_manager *manager = sensor->cb->get_service_manager(sensor);
// 1: 获得 这个 server SNS_ATTRIBUTE_SERVICEsns_attribute_service *attribute_service =(sns_attribute_service*)manager->get_service(manager, SNS_ATTRIBUTE_SERVICE);uint8_t attribute[attribute_len];pb_ostream_t stream = pb_ostream_from_buffer(attribute, attribute_len);// service api 中的 publish_attribute 把 tcs3701 的 name 属性 注册上去了.( 是注册到了 server 里面去了?)if(pb_encode(&stream, sns_std_attr_fields, &std_attr))attribute_service->api->publish_attribute(attribute_service, sensor,attribute, attribute_len, attribute_id, completed);// PEND: Print a message upon errors}
pb_get_encoded_size :数据的长度是
pb_ostream_from_buffer就是把编码后的数据写到buffer里
publish 完毕后, 这个 sensor 初始化就完毕,可以使用了.
// --------------------分界线---------------------------------------------------------------
看下 是怎么 接收事件的
上面 通过 tcs3701_send_suid_req 发送了几个请求
messig_id :SNS_SUID_MSGID_SNS_SUID_REQ
看下是怎么处理这个 事件的
void tcs3701_process_suid_events(sns_sensor *const this)
{
//1: mesg_id 为 SNS_SUID_MSGID_SNS_SUID_EVENT
if (SNS_SUID_MSGID_SNS_SUID_EVENT == event->message_id)
// 2: 后面主要是 从 pb buffer 解码
比如: 这种:
/* If no suids found, ignore the event */if (suid_search.num_of_suids == 0){SNS_PRINTF(ERROR, this, "TCS3701 no SUID found");continue;}}
// uid 赋值 给 state ,后面会用到
/* Save suid based on incoming data type name */if (0 == strncmp(data_type_arg.buf, "interrupt", data_type_arg.buf_len)){SNS_PRINTF(ERROR, this, "TCS3701 save IRQ SUID");state->common.irq_suid = uid_list;}
我们 在回到
tcs3701_sensor_notify_event
sns_rc tcs3701_sensor_notify_event(sns_sensor *const this)
{
// 1: 接收服务上发过来的信息tcs3701_process_suid_events(this);
//2: request_registry
if (!sns_sensor_uid_compare(&state->common.reg_suid, &((sns_sensor_uid){{0}}))){tcs3701_request_registry(this);}
}
在来看下
void tcs3701_request_registry(sns_sensor *const this)
{
//1: 获得 SNS_STREAM_SERVICE 服务sns_service_manager *service_mgr = this->cb->get_service_manager(this);sns_stream_service *stream_svc =(sns_stream_service*)service_mgr->get_service(service_mgr, SNS_STREAM_SERVICE);
//2:create_sensor_stream
stream_svc->api->create_sensor_stream(stream_svc,this, state->common.reg_suid, &state->reg_data_stream);
//3: 注册的是 ALS if (TCS3701_ALS == state->sensor){.....tcs3701_sensor_send_registry_request(this, TCS3701_CONFIG_ALS);}
}
看下 这个是怎么写的
static void tcs3701_sensor_send_registry_request(sns_sensor *const this,
{// 就是 向 server 发送了 SNS_REGISTRY_MSGID_SNS_REGISTRY_READ_REQ 消息}
我曹,真麻烦,还没完. 有点扛不住了. 哎,继续往下看吧…’
// 处理 SNS_REGISTRY_MSGID_SNS_REGISTRY_READ_REQ
void tcs3701_sensor_process_registry_event(sns_sensor *const this, sns_sensor_event *event)
{
// 1: 解析 server 发送过来的数据.
if (SNS_REGISTRY_MSGID_SNS_REGISTRY_READ_EVENT == event->message_id){sns_registry_read_event read_event = sns_registry_read_event_init_default;pb_buffer_arg group_name = {0,0};read_event.name.arg = &group_name;read_event.name.funcs.decode = pb_decode_string_cb;// 2:我们当时申请 注册的就是 这个 TCS3701_CONFIG_ALS
stream = pb_istream_from_buffer((void*)event->event, event->event_len);if (0 == strncmp((char*)group_name.buf, TCS3701_CONFIG_ALS, group_name.buf_len)){// 3: 填充数据.快完了. 看下是怎么填充的..
// 4: item_group_name 注册的 name 比如:TCS3701_CONFIG_ALS
// 5:
sns_registry_decode_arg arg = {.item_group_name = &group_name,.parse_info_len = 1,.parse_info[0] = {.group_name = "config",
// 5: 匹配就要调用这个 .parse_func = sns_registry_parse_phy_sensor_cfg,
// 6: 保存 上面 parse_func的数据.. .parsed_buffer = &state->common.als_registry_cfg}};}
再来看下 sns_registry_parse_phy_sensor_cfg
函数的 作用就是解析 一些 item
SNS_SECTION(".text.sns") bool
sns_registry_parse_phy_sensor_cfg(sns_registry_data_item *reg_item,pb_buffer_arg *item_name,pb_buffer_arg *item_str_val,void *parsed_buffer)
{bool rv = true;.....else if(reg_item->has_sint){sns_registry_phy_sensor_cfg *cfg =(sns_registry_phy_sensor_cfg *)parsed_buffer;
// 解析出来的是 is_dri if(0 == strncmp((char*)item_name->buf, "is_dri", item_name->buf_len)){cfg->is_dri = reg_item->sint;}// hw_id else if(0 == strncmp((char*)item_name->buf,"hw_id",item_name->buf_len)){cfg->hw_id = reg_item->sint;}else if(0 == strncmp((char*)item_name->buf,"res_idx",item_name->buf_len)){cfg->res_idx = reg_item->sint;}else if(0 == strncmp((char*)item_name->buf,"sync_stream",item_name->buf_len)){cfg->sync_stream = (reg_item->sint == 1) ?true : false;}}....
}
是从 tcs3701.als.config 这个文件读取出来的
继续往下看 tcs3701_sensor_process_registry_event
// 设置 decode 的 callback 和sns_registry_decode_arg
read_event.data.items.funcs.decode = &sns_registry_item_decode_cb;read_event.data.items.arg = &arg;
// 开始 decond, 信息保存在 read_event 中.rv = pb_decode(&stream, sns_registry_read_event_fields, &read_event);// 这个 调试 也许用的上,先记录下..
// 解析完毕.数据保存在 state->common.als_registry_cfg 中..
if (rv){state->common.als_registry_cfg_received = true;SNS_PRINTF(LOW, this, "TCS3701 Registry read event for ALS group registry_cfg received ""is_dri:%d, hardware_id:%d resolution_idx:%d, supports_sync_stream:%d",state->common.als_registry_cfg.is_dri, state->common.als_registry_cfg.hw_id,state->common.als_registry_cfg.res_idx, state->common.als_registry_cfg.sync_stream);}
这篇关于高通 slpi tcs3701_als_init的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!