写在前面

17年到23年这么多年了只有几篇文章,看了几篇博客和高通文档后还是对SEE一脸懵逼,只能自己瞎JB乱看一通代码,然后再瞎JB记录一下,也不知道对不对。目标是把注册驱动时要填充的那两个结构体的东西大概是个什么鬼弄明白一下。

以基线自带的hall sensor driver为例分析

// 驱动的入口函数sns_register_bu52053nvx
sns_rc sns_register_bu52053nvx(sns_register_cb const *register_api)
{// 将sensor注册到sensor framework中//  @param1:各个sensor驱动自定义数据需要的长度,不超过1k, framework会额外分配该大小内存空间并存其首地址到state指针//  @param2:这里引入sensor的概念,后面介绍//  @param3:这里引入sensor_instance的概念,后面介绍register_api->init_sensor(sizeof(BU52053NVX_STATE), &bu52053nvx_sensor_api, &bu52053nvx_sensor_instance_api);return (SNS_RC_SUCCESS);
}

以hall sensor注册入口为切入点找到的初始化流程:sensor framework的初始化流程

// step 2 的 sns_sensor_init_fw() 代码片段
// 初始化全局变量sensor_cb,在第9步hall sensor注册时赋值给它的cb,这样hall sensor驱动就可以使用这些callback函数了
sns_sensor_cb sensor_cb SNS_SECTION(".data.sns");
sns_rc sns_sensor_init_fw(void)
{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,.create_instance_v2 = &sns_sensor_instance_init_v2,};
}
// step 3 sns_sensor_instance_init_fw() 代码片段
// 和2一样只是初始化一个全局变量instance_cb,在创建相应sensor的instance时赋值给它的cb
sns_rc sns_sensor_instance_init_fw(void)
{instance_cb = (sns_sensor_instance_cb){.struct_len = sizeof(instance_cb),.get_service_manager = &get_service_manager,.get_client_request = &get_client_request,.remove_client_request = &remove_client_request,.add_client_request = &add_client_request};return SNS_RC_SUCCESS;
}
// step 4 sensor_list对于driver来说是python根据编译脚本生成的,即在por.py中配置要编译的sensor
register_sensors(const sns_register_entry *sensor_list, uint32_t list_len)
{sns_register_cb reg_cb = (sns_register_cb){.struct_len = sizeof(reg_cb),.init_sensor = &sns_sensor_init};for(int i = 0; i < list_len; i++){for(int j = 0; j < sensor_list[i].cnt; j++){sns_sensor_library *library = sns_sensor_library_init(sensor_list[i].func, j, sensor_list[i].is_islandLib); // 5sensor_list[i].func(&reg_cb); // 6sns_sensor_library_start(library);  // 10}}}
// 调用时序图的第9步
sns_sensor_init(uint32_t state_len, struct sns_sensor_api const *sensor_api,struct sns_sensor_instance_api const *instance_api)
{sns_rc rv = SNS_RC_SUCCESS;sns_isafe_list_iter iter;sns_fw_sensor *sensor = NULL;sns_sensor_library *library;bool island_sensor = is_island_sensor(sensor_api, instance_api);// 需要为attr和state分配空间这里计算大小// hall驱动中经常见到的state就是这东西BU52053NVX_STATE    *state       = (BU52053NVX_STATE *)this->state->state;// hall驱动中bu52053nvx_publish_attributes(sns_sensor *const this)中attruint8_t attr_idx = 0;uint8_t state_idx = 0;size_t alloc_size = sns_cstruct_extn_compute_total_size(sizeof(*sensor),2,ALIGN_8(sizeof(struct sns_sensor_state) + state_len) + ALIGN_8(sizeof(struct sns_attribute_info)));// 根据sns_bu52053nvx.scons中是否配置add_island_files = bu52053nvx_island_enable// 来分配内存,如以下高通文档描述的6225平台island的空间大小// ADSP subsystem《SM6225 Sensors Overview》Total Island memory - 1 MB, // PoR configuration:512 KB for sensors, CoreBSP, and existing dependencies// 512 KB for audio and relevant CoreBSP dependencies// 非island的内存位于DDR,之前有项目添加过一个功能,在开启该功能时,把添加的这个驱动// 配置到island会额外增加0.3mA的电流,非island增加5mA,而机器在飞行模式待机时的电流4mAif(island_sensor){sensor = sns_malloc(SNS_HEAP_ISLAND, alloc_size);}if(NULL == sensor){sensor = sns_malloc(SNS_HEAP_MAIN, alloc_size);island_sensor = false;}sns_cstruct_extn_init(&sensor->extn, sensor, sizeof(*sensor), 2);attr_idx = sns_cstruct_extn_setup_buffer(&sensor->extn, sizeof(struct sns_attribute_info));state_idx = sns_cstruct_extn_setup_buffer(&sensor->extn, sizeof(struct sns_sensor_state) + state_len);sensor->sensor.cb = &sensor_cb;sensor->sensor.sensor_api = sensor_api;sensor->sensor.instance_api = instance_api;// 通过cstruct获取分配的state空间地址sensor->sensor.state = (struct sns_sensor_state*)sns_cstruct_extn_get_buffer(&sensor->extn, state_idx);sensor->sensor.state->state_len = state_len;// 通过cstruct获取分配的attr空间地址sensor->attr_info = sns_cstruct_extn_get_buffer(&sensor->extn, attr_idx);// 调用sns_attr_svc_sensor_init(sns_fw_sensor *sensor)for(uint8_t i = 0; i < ARR_SIZE(state_init); i++)if(NULL != state_init[i].init)state_init[i].init(sensor);sensor->island_operation = island_sensor ?SNS_ISLAND_STATE_IN_ISLAND : SNS_ISLAND_STATE_NOT_IN_ISLAND;sensor->removing = false;sensor->library = library;sensor->diag_config.config = default_datatype;// data_stream这个后续分析sns_isafe_list_init(&sensor->data_streams);sns_isafe_list_init(&sensor->sensor_instances);sns_isafe_list_item_init(&sensor->list_entry, sensor);sns_osa_lock_acquire(library->library_lock);sns_isafe_list_iter_init(&iter, &library->sensors, false);sns_isafe_list_iter_insert(&iter, &sensor->list_entry, true);sns_osa_lock_release(library->library_lock);return rv;
}

类图

代码一通看下来SEE是按面向对象写的,但是用的C语言实现,既然这样那按照C++去理解,那在这里就瞎JB画个类图。

sns_sensor           sns_fw_sensor            sns_fw_sensor              sns_fw_sensor_instance

// sns_sensor 的定义
typedef struct sns_sensor {/* Functions which call back into the framework; provided by the Framework */struct sns_sensor_cb const *cb;/* API implementation provided for and by this Sensor */struct sns_sensor_api const *sensor_api;/* The associated API for a Sensor Instance created for and by this Sensor. */struct sns_sensor_instance_api const *instance_api;/* State space allocated by the Framework for the sole use of the Sensor developer. */struct sns_sensor_state *state;
} sns_sensor;// 驱动中可以看到参数的传递都是sns_sensor 而不是 sns_fw_sensor
static sns_rc bu52053nvx_hall_init(sns_sensor *const this)
{BU52053NVX_STATE *state = (BU52053NVX_STATE *)this->state->state;
}// sns_fw_sensor 的定义
typedef struct sns_fw_sensor
{sns_sensor sensor;...
}// 在framework中使用sns_fw_sensor 而不是 sns_sensor
get_sensor_instance(sns_sensor const *this, bool first)
{sns_fw_sensor *sensor = (sns_fw_sensor*)this;...
}

1. sns_sensor是基类,sns_fw_sensor 继承自 sns_sensor,和C++中继承的内存布局一致

2. 在hall驱动中定义的私有数据通过sns_sensor成员state访问

3. sns_fw_sensor分为两部分,开放给dirver用的放在sns_sensor中,不想被driver知晓的部分放在sns_fw_sensor,

framework调用driver的函数时把参数sns_fw_sensor强制转换为sns_sensor,driver拿到的只有sns_sensor部分的内存,无法访问framework部分

4. sns_sensor_cb为framework开放给driver调用的接口

5. sns_sensor_api中的init() 和 deinit() 是sns_sensor这个构造和析构函数

理解 sns_sensor 和 sns_sensor_instance 的关系

以下为高通文档中对 sensor 和 sensor instance 的说明

  • sensor是异步数据的生产者和/或消费者。
  • 每个sensor可以实例化一次或多次sensor instance。

每个sensor instance都使用特定的配置进行操作。

对instance的任何数据请求可能会导致创建sensor instance实例或共享现有实例。

  • sensor instance实例是按需创建的,由sensor决定。

sensor完全管理其对应sensor instance的生命周期和配置,并负责向客户端发送配置更新和初始状态事件。

强烈建议供应商以尽可能少的sensor instance来处理所有客户请求。

sensor instance生成的data stream将发送给所有活动client。

  • 单个sensor instance实例可以由多个sensor共享和配置。

这种操作模式通常用于硬件传感器的组合驱动程序,其中sensor代表支持的数据类型,而sensor instance是唯一与硬件通信和配置的模块。

想想当时学C++的时候,老是听到这样一句话:类是对一类事物的抽象,比如说小汽车抽象为Car这个类,一台奔驰车就是具体实例。

所以我认为这是高通设计sns_sensor 和 sns_sensor_instance 的初衷。get_sensor_uid放在sensor中,说明不依赖于instance,属于sensor的static 方法。

遗留

sensor instance, data stream, event service

QCOM Sensor SEE 分析--初始化相关推荐

  1. BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) -- 转贴自 wolfenstein (NeverSayNever)

    BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) author:wolfenstein Tracker在BT中是一个很重要的部分.这个名词我注意到以前的文章中都是直接引用,没 ...

  2. BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化)

    BT源代码学习心得(六):跟踪服务器(Tracker)的代码分析(初始化) 发信人: wolfenstein (NeverSayNever), 个人文集 标  题: BT源代码学习心得(六):跟踪服务 ...

  3. 高通平台 input类 sensor驱动分析 : 光感/距感 stk3x1x driver分析

    stk3x1x driver分析 1:注册驱动 定义 i2c_driver static struct i2c_driver stk_ps_driver = {.driver = {.name = D ...

  4. Android Qcom Sensor架构学习

    Android Sensor Brief Flow Android Sensor Specific Flow ADSP SSC ADSP.VT.5.4.1/adsp_proc/ssc_api/pb/ ...

  5. android sensor简略分析

    1.相关代码路径 frameworks\base\core\java\android\hardware\SensorManager.java frameworks\base\core\java\and ...

  6. mybatis 源码分析, 初始化

    分析版本 我们先分析xml配置文件形式的 mybatis, 等我们分析完毕了, 可以去分析 mybatis 和 spring 的对接 pom.xml <dependency><gro ...

  7. tomcat源码分析--初始化与启动

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 在阅读tomcat源码前,我们一般都会有如下几个疑问: - web容器和servlet容器的区别是什么: - 在spr ...

  8. 重力感应器G—sensor 驱动分析

    重力传感器代码分析 重力传感器驱动的功能,主要是向HAL层提供IOCTRL接口,并通过input设备上报数据.芯片实际数据的读取是采用i2c协议读取原始数据,并且作为i2c设备挂载在系统上工作的. 1 ...

  9. ABP框架(.Net Core)-分析初始化过程

    本文通过搭建一个基于ABP简单的WebAPI Demo了解ABP的初始化过程. 简单的WebAPI DEMO 首先让我们建立一个项目: TestAbp.IService: IMyService中主要定 ...

最新文章

  1. JVM---虚拟机栈(动态链接与方法返回地址)
  2. 豆瓣评分9分+,每一部看完不禁感慨!这里是神州大地!
  3. matlab 三维 作图 坐标轴_MATLAB学习——MATLAB中的三维绘图指令
  4. Codeforces Round #FF
  5. rap2检测哪些接口在使用_Apifox for Mac(接口调试管理工具)
  6. python代码技巧_几个小技巧让你的Python代码更Pythonic
  7. 卡尔曼滤波(kalman filter)
  8. javaScript调用函数失败
  9. 计算机网络 第章 运输层
  10. 工作资讯002---FaaS和PaaS的关系_Iaas_Paas_Saas
  11. 线上python课程一般多少钱-python培训班一般多少钱?一篇文章告诉你
  12. GB35114—⑤、附 录C
  13. camera(二) DVP接口
  14. 如何利用线程堆栈定位问题
  15. 5G无线技术基础自学系列 | 新多址接入
  16. Crate 数据库安装与使用
  17. python PIL库对图片按比例进行分割
  18. 【sdx62】WCN6855 WCN6856 WiFi 增加强制40MHz频宽的功能实现
  19. 一语成谶:灾祸普遍是自己说大话感…
  20. c++实训 选猴子当大王

热门文章

  1. 找茬微信小程序源码完整版
  2. SOLIDWORKS Plastics 模流分析基础与功能介绍
  3. 【c++师傅领进门,修行靠个人】第六篇:内存管理
  4. 如何用 SQL 来查询 Elasticsearch 中的数据?
  5. c语言编写闹钟主程序流程图,[]C51单片机课程设计--定时闹钟.doc
  6. 北京林业大学“计蒜客”杯程序设计竞赛 网络赛 马踏棋盘的问题
  7. 2603: 2012世界末日
  8. java 读取12306最新火车站信息并存储
  9. html 学习 常用的html标签及使用
  10. 前端实现在线预览文件