高通 slpi tcs3701_als_init

2023-11-26 10:20
文章标签 init 高通 als slpi tcs3701

本文主要是介绍高通 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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/425519

相关文章

4.15 版本内核调用 init_timer()函数出错

linux/include/linux/timer.h4.15 之前版本struct timer_list {14 /*15 * All fields that change during normal runtime grouped to the16 * same cacheline17 */18 struct hl

Python方法:__init__,__new__,__class__的使用详解

转自:https://blog.csdn.net/qq_26442553/article/details/82464682 因为python中所有类默认继承object类。而object类提供了了很多原始的内建属性和方法,所以用户自定义的类在Python中也会继承这些内建属性。可以使用dir()函数可以查看,虽然python提供了很多内建属性但实际开发中常用的不多。而很多系统提供的内建属性实际

_no_init的作用

__no_init用于禁止系统启动时的变量初始化,什么情况下需要用这个关键字使系统禁止变量的初始化,禁止变量初始化用在什么场合,为什么要这样做,有什么意义吗? 1、看门狗复位的现场恢复,如果初始化了就完全不可恢复了 2、使用nvram保存数据,需要连续记录的。    我有个变量,需要在系统意外复位时,这个变量值能保留,所以采用__no_init来实现,只是上电的时候这个值不是零

iOS中alloc与init

面向对象的3大特性,封装继承和多态. 我遇到过封装相关的问题,因为初级封装简单,常常暴露出被你封装的接口,进一步进行高级封装隐藏接口的时候才发现,封装是一门学问,而这门学问得从最基础的alloc与init讲起.   FatherModel.h #import <Foundation/Foundation.h>@interface FatherModel : NSObject@en

优雅的写init方法

怎么写出高质量的init方法,以下是demo可参考实现,代码实现。 public class BaseTestController {private UnitTest unitTest;public void init(String url, String accessToken){unitTest = UnitTest.getNewInstance();unitTest.setHost(ur

Android14音频进阶之定制ramdisk文件系统init服务(八十三)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧

cocos2dx场景切换中init、onEnter、onEnterTransitionDidFinish的调用顺序

这些方法调用的先后顺序如下(使用 replaceScene 方法): 1. 第2个场景的 scene 方法 2. 第2个场景的 init 方法 3. 第2个场景的 onEnter 方法 4. 转场 5. 第1个场景的 onExit 方法 6. 第2个场景的 onEnterTransitionDidFinish 方法 7. 第1个场景的 dealloc 方

深入理解jvm--Java中init和clinit区别完全解析

init和clinit区别 ①init和clinit方法执行时机不同 init是对象构造器方法,也就是说在程序执行 new 一个对象调用该对象类的 constructor 方法时才会执行init方法,而clinit是类构造器方法,也就是在jvm进行类加载—–验证—-解析—–初始化,中的初始化阶段jvm会调用clinit方法。 ②init和clinit方法执行目的不同 init is t

If an application has more than one locale, then all the strings declared in one language should als

字符串资源多国语言版本的出错问题 假如你仅仅针对国内语言 加上这句即可 //保留中文支持resConfigs "zh"

小米3高通版为何推迟上市:供应链之伤

雷军终于赶在2013年的最后一天宣布小米3高通版上市,而此时距9月5日的发布会已隔近4个月之久。     这其中究竟发生了什么?笔者在一个月时间内陆续采访了高通大中华区总裁王翔、联发科董事长蔡明介、多家国产手机大佬、手机方案商、以及小米内部员工,信息整理如下:     小米3高通版为何推迟近4个月?     在目前智能手机市场,一款旗舰产品的销售生命周期只有9-12个月,而国内品牌更短