1.高通SEE 虚拟sensor分析
在SEE中,处理硬件sensor,高通实现的platform sensor,还有一类是通过硬件sensor等各种数据计算,抽象出来的虚拟sensor。
我们以高通提供的参考为例,看如何添加一个虚拟sensor和虚拟sensor执行流程。
1.pb协议文件定位sensor类型数据
在Non-HLOS\adsp_proc\ssc_api\pb\sns_oem1.proto中定义了oem1这个虚拟sensor的sns_oem1_msgid和sns_oem1_data。
syntax = "proto2";
import "nanopb.proto";
import "sns_std_sensor.proto";enum sns_oem1_msgid
{option (nanopb_enumopt).long_names = false;SNS_OEM1_MSGID_SNS_OEM1_DATA = 1024;
}// Data Message
// Output data event generated by the oem1 sensor.
message sns_oem1_data
{// oem1 Vector along axis x,y,z in m/s2repeated float oem1 = 1 [(nanopb).max_count = 3];// Accuracy of the datarequired sns_std_sensor_sample_status accuracy = 2;
}
这个文件在pb工具编译后,将生成对应的.c和.h文件。pb是一种数据打包协议,SEE中传递数据和事件信息,全都通过pb进行打包,打包将会包含这笔数据的msgid,表示是什么数据。对应oem1这个sensor, 如果是数据类型是sns_oem1_msgid,则还会包含sns_oem1_data类型数据。
2.sensor
虚拟sensor的在sns_oem1.c中的sns_oem1_register方法。这个方法将被调用,用来将sensor和sensor_instance对应的api注册到framework。
sns_rc sns_oem1_register(sns_register_cb const *register_api)
{register_api->init_sensor(sizeof(sns_oem1_sensor_state),&sns_oem1_api,&sns_oem1_sensor_instance_api);return SNS_RC_SUCCESS;
}
sns_oem1_register被放到framework的一个数组中,用来逐个注册sensor。register_api方法有framework提供,代码如下:
extern sns_sensor_cb sensor_cb;sensor_cb = (sns_sensor_cb){.struct_len = sizeof(sensor_cb),.get_service_manager = &get_service_manager,.get_sensor_instance = &get_sensor_instance,.create_instance = &sns_sensor_instance_init,.remove_instance = &sns_sensor_instance_deinit,.get_library_sensor = &get_library_sensor,.get_registration_index = &get_registration_index,};
这个结构的具体意义已经在结构注释中说明。
另外这里有sensor_api和sensor_inst_api。虚拟sensor中sensor用户虚招要使用的其他sensor, 发布sensor attr表示这个sensor存在,以及创建和管理sensor instance。sensor instance是实际存在和发布数据的实体。
我们在看sns_sensor_instance_api和sns_sensor_api这两个结构。我们首先看sensor_api.
typedef struct sns_sensor_api
{uint32_t struct_len;sns_rc (*init)(sns_sensor *const this);//初始化sns_rc (*deinit)(sns_sensor *const this);//反初始化释放资源sns_sensor_uid const* (*get_sensor_uid)(sns_sensor const *const this); //获取sensor uidsns_rc (*notify_event)(sns_sensor *const this); //通知sensor有数据struct sns_sensor_instance* (*set_client_request)(sns_sensor *const this,struct sns_request const *exist_request,struct sns_request const *new_request,bool remove); //接收client的request
}
sensor_api的init在开机时被framework调用。
sns_rc
sns_oem1_init(sns_sensor *const this)
{sns_oem1_sensor_state *state = (sns_oem1_sensor_state*)this->state->state;// cb获取sensor managerstruct sns_service_manager *smgr = this->cb->get_service_manager(this);float data[3];state->diag_service = (sns_diag_service*)smgr->get_service(smgr, SNS_DIAG_SERVICE);// set default output value corresponding to OEM1_FACING_DOWN to 50. will // rewrite if registry sensor is availablestate->config.down_value = 50.0;state->first_pass = true;// determine encoded output event sizestate->config.encoded_data_event_len =pb_get_encoded_size_sensor_stream_event(data, 3);// 通过sensor的datatype查找sensor对应的suid.在frmework中会将每个sensor的datatype和suid绑定,这些sensor是本虚拟sensor数据来源SNS_SUID_LOOKUP_INIT(state->suid_lookup_data, NULL);sns_suid_lookup_add(this, &state->suid_lookup_data, "gyro");//accelsns_suid_lookup_add(this, &state->suid_lookup_data, "registry");
#ifndef OEM1_SUPPORT_DIRECT_SENSOR_REQUESTsns_suid_lookup_add(this, &state->suid_lookup_data, "resampler");
#endif//发布snesor信息,包括sensor的datatype, sample rate等publish_attributes(this);SNS_PRINTF(MED, this, "OEM1 init success and attributes published");return SNS_RC_SUCCESS;
}
在sns_suid_lookup_add查找suid完成,会通过sensor framework调用sensor_api->notify_event。sns_suid_lookup_add()方法将创建和suid_sensor的流并做请求,请求后的回复通过framework调用notify_event。如果找到则宣布sensor就绪。
sns_rc
sns_oem1_notify_event(sns_sensor *const this)//接收sns_suid_lookup_add返回
{sns_oem1_sensor_state *state = (sns_oem1_sensor_state*)this->state->state;SNS_PRINTF(LOW, this, "sns_oem1_notify_event");sns_suid_lookup_handle(this, &state->suid_lookup_data);if(sns_suid_lookup_complete(&state->suid_lookup_data)) {publish_available(this);sns_suid_lookup_deinit(this, &state->suid_lookup_data);}return SNS_RC_SUCCESS;
}
publish_available发布改sensor可用。到这里sensor就准备好了。
sensor发布出去后,AP测就可以查询到并且使用。当AP测应用程序激活sensor,sensor_api->set_client_request将被调用,而且AP测发送过来的数据,也是通过pb打包的。
sns_sensor_instance*
sns_oem1_set_client_request(sns_sensor *const this,sns_request const *curr_req,sns_request const *new_req,bool remove)
{sns_sensor_instance *curr_inst =sns_sensor_util_find_instance(this,curr_req,this->sensor_api->get_sensor_uid(this));sns_sensor_instance *rv_inst = NULL;sns_sensor_instance *match_inst = NULL;// 接收到到config messageelse if((new_req->message_id == SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG) || (new_req->message_id == SNS_STD_SENSOR_MSGID_SNS_STD_ON_CHANGE_CONFIG)){pb_simple_cb_arg arg ={ .decoded_struct = &config, .fields = sns_std_sensor_config_fields };request.payload = (struct pb_callback_s){ .funcs.decode = &pb_decode_simple_cb, .arg = &arg };//获取到请求的流stream = pb_istream_from_buffer(new_req->request, new_req->request_len);//从流中解析出请求数据,标准sensor请求数据只有sample_rateif(pb_decode(&stream, sns_std_request_fields, &request)){decoded_req.message_id = new_req->message_id;decoded_req.request_len = sizeof(config);decoded_req.request = &config;match_inst = sns_sensor_util_find_instance_match(this, &decoded_req, &find_instance_match);}//然后创建sensor instance,将请求的设置在instance中设置rv_inst = this->cb->create_instance(this,(sizeof(sns_oem1_inst_state)));if(NULL != rv_inst){rv_inst->cb->add_client_request(rv_inst, new_req);
#ifndef OEM1_SUPPORT_EVENT_TYPEthis->instance_api->set_client_config(rv_inst, &decoded_req);
#elsethis->instance_api->set_client_config(rv_inst, new_req);
#endif}}}
上面代码接收来自client的config请求,并根据请求创建或者复用一个sensor instance,设置需要的配置。到这里就进入到sensor instance。
3.sensor instance
sensor管理者sensor instance,sensor instance实际管理者sensor数据。create_instance由framework完成,具体实现为:
sensor_cb = (sns_sensor_cb){.struct_len = sizeof(sensor_cb),.get_service_manager = &get_service_manager,.get_sensor_instance = &get_sensor_instance,.create_instance = &sns_sensor_instance_init,.remove_instance = &sns_sensor_instance_deinit,.get_library_sensor = &get_library_sensor,.get_registration_index = &get_registration_index,};sns_rc
sns_sensor_init(uint32_t state_len, struct sns_sensor_api const *sensor_api,struct sns_sensor_instance_api const *instance_api) {sensor->sensor.cb = &sensor_cb;}
现在看sensor instance的注册入口:
sns_sensor_instance_api sns_oem1_sensor_instance_api =
{.struct_len = sizeof(sns_sensor_instance_api),.init = &sns_oem1_inst_init,.deinit = &sns_oem1_inst_deinit,.set_client_config = &sns_oem1_inst_set_client_config,.notify_event = &sns_oem1_inst_notify_event
};
sns_sensor_instance_init()创建instance将会调用到sns_sensor_instance_api->init,完成instance的init过程。
在init中我们查找在sensor中寻找的sensor uid,并且对需要的非resampler sensor创建流。resampler sensor的流放到请求resampler之前。
sns_rc
sns_oem1_inst_init(sns_sensor_instance *this,sns_sensor_state const *state){sns_service_manager *service_mgr = this->cb->get_service_manager(this);sns_stream_service *stream_service = (sns_stream_service*)service_mgr->get_service(service_mgr, SNS_STREAM_SERVICE);sns_suid_lookup_get(&sensor_state->suid_lookup_data, "gyro", &inst_state->accel_suid);stream_service->api->create_sensor_instance_stream(stream_service,this,inst_state->accel_suid,&inst_state->accel_stream);}
1.高通SEE 虚拟sensor分析相关推荐
- 高通SDM845平台Sensor学习——3.SLPI(Physical Sensor)
####三:Sensor SLPI层代码分析 #### 在学习SLPI侧代码前我们先了解下SEE的registry&config. registry 放在/persist/sensors/re ...
- 高通SDM845平台Sensor学习——2.Hal层
二:Sensor Hal层代码分析 Hal code放在/vendor/qcom/proprietary/sensors-see/中 sensors-hal文件夹中包含framework和sensor ...
- 高通SDM845平台Sensor学习——2.Hal层--
二:Sensor Hal层代码分析 Hal code放在/vendor/qcom/proprietary/sensors-see/中 sensors-hal文件夹中包含framework和sensor ...
- 高通SDM845平台Sensor学习——4.SLPI(SAM Sensor)
四:Sensor SLPI层SAM Sensor实例分析 上文中,我们大致了解了物理sensor driver整个流程,但在项目中,一般写这种sensor driver的情况很少.这种sensor d ...
- 高通SDM845平台Sensor学习——1.框架
一:简介 高通从SDM845平台开始,Sensor使用新的架构SEE(Sensors Execution Environment),和之前架构不同,新的架构有着太多的优点. 首先,先对比下新架构和旧架 ...
- 高通Android display架构分析
目录(?)[-] Kernel Space Display架构介绍 函数和数据结构介绍 函数和数据结构介绍 函数和数据结构介绍 数据流分析 初始化过程分析 User Space display接口 K ...
- 高通SDM845平台Sensor学习——4.SLPI(SAM Sensor)--
四:Sensor SLPI层SAM Sensor实例分析 上文中,我们大致了解了物理sensor driver整个流程,但在项目中,一般写这种sensor driver的情况很少.这种sensor d ...
- 高通SDM855平台Sensor学习——1.框架
一:简介 高通从SDM845平台开始,Sensor使用新的架构SEE(Sensors Execution Environment),和之前架构不同,新的架构有着太多的优点. 首先,先对比下新架构和旧架 ...
- 高通8155/8295 boot分析
目录 前言 通用boot流程 8155/8295 boot流程概述 前言 本文将基于高通8155/8295 Q+A hypervisor平台分析整个boot的启动流程.高通其他SOC芯片的启动流程大致 ...
最新文章
- nand flash 扇区的管理以及初始化
- IntelliJ IDEA 导入 IntelliJ IDEA 创建好的JavaWeb项目!
- artTemplate的使用总结
- proxy in nodejs code
- leetcode初级算法1.删除排序数组中的重复项
- wangeditor html编辑,Vue整合wangEditor富文本编辑器
- HDU5212 CODE【莫比乌斯函数】
- ArcGIS For Flex学习之Mapping---Map Extent and Mouse Coordinates
- fftw3 嵌入式linux安装,Ubuntu18.04下快速的安装UHD与GnuRadio并连接USRP设备
- php中admin文件什么意思,开始使用 · tpAdmin 文档 · 看云
- 打印服务器 支持 佳能 2900+打印机,Deepin20(1002版本)安装佳能Canon LBP2900+打印机
- 这5种数据挖掘技术,大数据玩的贼溜!
- HTML YouTube 视频
- python淘宝cookies抢购_Python爬虫利用cookie抓取淘宝商品比价
- 铁路警方启用AI眼镜,当场抓逃犯!外媒惊叹不已!
- Python实现回归树
- P1535 游荡的奶牛
- 洛谷 P5664 Emiya 家今天的饭【dp】
- 理工男学计算机,案例分享 | 一名“理工男”的春天
- 那些年啊,那些事——一个程序员的奋斗史 ——113
热门文章
- 基于原生js和css3实现barrage弹幕效果
- 支付宝做社交缺什么?
- 2022人工智能顶会时间序列论文汇总
- JQuery事件的基本使用
- 物理系统仿真有哪些作用和功能?速看
- 荣耀V9可以升级鸿蒙吗,荣耀手机能升级鸿蒙系统吗,支持鸿蒙系统的荣耀手机有哪些...
- 拼多多新店正确起步方法!
- 苹果天气不显示_手机锁屏显示天气预报可不只安卓有,iPhone也能显示!太实用了吧...
- C++ 操作重载与类型转换 《C++Primer》第14章 读书笔记
- 包邮送33本11.11京东TOP5的精选书,先到先得!