• Android Qcom Sensor架构学习


    Android Sensor Brief Flow

    在这里插入图片描述

    Android Sensor Specific Flow

    在这里插入图片描述

    ADSP SSC

    ADSP.VT.5.4.1/adsp_proc/ssc_api/pb/
    ADSP.VT.5.4.1/adsp_proc/ssc/sensors
    ADSP.VT.5.4.1/adsp_proc/ssc/frameworks
    
    • 1
    • 2
    • 3

    ADSP Framework初始化的时候首先通过load image并初始化的静态加载方式register_static_sensors
    ssc_static_lib_builder.py 会编译出静态加载的sensor列表 framework/build/sensor_img/…/sns_static_sensors.c
    sensor的入口是register_function 定义在具体sensor的目录下的scons中 ssc/sensor/xxx/build/xxx.scons island_mode 支持低功耗

    if 'USES_SSC_STATIC_LIB_BUILDER' in env:                 
      env.AddSSCSU(inspect.getfile(inspect.currentframe()),
                   register_func_name = 
    
    • 1
    • 2
    • 3

    如果是动态加载的话,则是ssc/framework/dl/src/sns_dynamic_sensors.c,没具体研究

    registry用于存放sensor信息的,放置在perisist分区,可通过registry sensor获取
    通过/vendor/etc/sensors/config/.json生成

    mnt/vendor/persist/sensors/registry/
    registry
    sensor_list.txt
    sensors_settings
    
    • 1
    • 2
    • 3
    • 4

    在sensor_api::notify_event的过程中一般都会去处理registry,physical sensor包含很多硬件配置

    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;
       
        if(!pb_decode(&stream, sns_registry_read_event_fields, &read_event))
        {
          SNS_PRINTF(ERROR, this, "Error decoding registry event");
        }else
        {
            ...
            sns_registry_phy_sensor_pf_cfg phy_sensor_pf_cfg;
            memset(&phy_sensor_pf_cfg, 0, sizeof(phy_sensor_pf_cfg));
            sns_registry_decode_arg arg = {
              .item_group_name = &group_name,
              .parse_info_len = 1,
              .parse_info[0] = {
                  .group_name = "config",
                  .parse_func = sns_registry_parse_phy_sensor_pf_cfg,
                  .parsed_buffer = &phy_sensor_pf_cfg
              }
            };
    
            read_event.data.items.funcs.decode = &sns_registry_item_decode_cb;
            read_event.data.items.arg = &arg;
    
            rv = pb_decode(&stream, sns_registry_read_event_fields, &read_event);
         ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    json中具体的配置,与解析后的应用后续再研究

    sns_sensor::init -> publish_attibutes (physical sensor -> platform define name)
    ltrx1303_publish_attributes -> "ambient_light"
    icm4x6xx_accel_publish_attributes -> "accel"
    sns_publish_attribute(this, SNS_STD_SENSOR_ATTRID_TYPE, &value, 1, false);
    
    • 1
    • 2
    • 3
    • 4

    HAL SSC

    https://source.android.google.cn/devices/sensors/sensors-multihal?skip_cache=true&hl=zh-cn

    /hardware/interfaces/sensors/common/default/2.X/multihal/HalProxy.cpp
    /vendor/qcom/proprietary/sensors-see/ssc/sns_std_sensor.proto -> sns_std_sensor.pb.h 
    /vendor/qcom/proprietary/sensors-see/sensors-hal-2.0/framework/
    /vendor/qcom/proprietary/sensors-see/sensors-hal-2.0/sensors/
    vendor/qcom/proprietary/sensors-see/registry/config
    
    • 1
    • 2
    • 3
    • 4
    • 5

    SENSOR_MODULE_INIT初始化会注册两个unordered_map: callbacks and datatypes

    sensor_factory::register_sensor  sensorType define in sensors_qti.h    
    sensor_factory::request_datatype dataType   "accel" 
    
    get_available_sensors(callbacks)
         push_back(make_unique<sensor>suid, SENSOR_WAKEUP))    //construct sensor 
         push_back(make_unique<sensor> suid, SENSOR_NO_WAKEUP)) //construct sensor
             set_type                  //QTI_SENSOR_TYPE
             set_string_type           //QTI_SENSOR_STRING_TYPE
             set_nowk_msgid            //SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_PHYSICAL_CONFIG_EVENT
             set_sensor_typename       //"Accelerometer" "SAR Sensor" 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    无论时HAL与ADSP通信,还是ADSP内各sensor的通信,必须通过send_request, 通信的过程必须遵从protocol-buffers
    其中最重要的两点需要suid和msg_id,suid时指定sensor(platform sensor:suid sensor,physical sensor:accel,virtual sensor:amd)

    sensors_hal::activate  ssc_sensor::activate 
    suid_lookup lookup
        const sensor_uid LOOKUP_SUID = {                          //与suid sensor通信
            12370169555311111083ull,
            12370169555311111083ull
        };                 
    pb_req_msg.set_msg_id(SNS_SUID_MSGID_SNS_SUID_REQ);           //请求具体sensor的suid 
                
    lookup.request_suid                                           //通过stringtype获取具体sensor的suid        
    send_sensor_config_request
        create_sensor_config_request()
           pb_req_msg.mutable_suid()->set_suid_high(_suid.high);  //request通信携带具体sensor的suid
           pb_req_msg.mutable_suid()->set_suid_low(_suid.low);
           _ssc_conn->send_request 
                if (stream_type == SNS_STD_SENSOR_STREAM_TYPE_STREAMING)  //attributes中的SNS_STD_SENSOR_ATTRID_STREAM_TYPE
                     pb_req_msg.set_msg_id(SNS_STD_SENSOR_MSGID_SNS_STD_SENSOR_CONFIG);//
                else
                     pb_req_msg.set_msg_id(SNS_STD_SENSOR_MSGID_SNS_STD_ON_CHANGE_CONFIG)   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    APP and Framework

    /frameworks/base/core/java/android/hardware/SensorManager.java
    /frameworks/base/core/java/android/hardware/SystemSensorManager.java
    
    • 1
    • 2
    Typical Sensor Type
    * Sensor.TYPE_LIGHT:光传感器
    * Sensor.TYPE_GRAVITY:重力传感器
    * Sensor.TYPE_PRESSURE:压力传感器
    * Sensor.TYPE_ALL: 所有支持的传感器
    * Sensor.TYPE_ORIENTATION:方向传感器
    * Sensor.TYPE_GYROSCOPE:陀螺仪传感器
    * Sensor.TYPE_MAGNETIC_FIELD:磁场传感器
    * Sensor.TYPE_AMBIENT_TEMPERATURE:温度传感器
    * Sensor.TYPE_LINEAR_ACCELERATION:线性加速度传感器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如果是非典型的sensor类型,或者是客制化的,则需要从所有传感器类型中通过getStringType进行过滤,
    注册并激活所需要的sensor,创建SensorEventQueue用于数据分发调用回调 onAccuracyChanged onSensorChanged
    在注册时需要注意isWakeUpSensor判断,因为在HAL初始化的时候我们知道同一类型sensor又会细分为两种类型
    SENSOR_WAKEUP和SENSOR_NO_WAKEUP,SENSOR_WAKEUP在系统休眠时也可以上报事件,可以用作抬腕唤醒等功能

    Protocol Buf Advantage

    使用谷歌 Protocol Buffers(简称 Protobuf)有以下几个好处:

    高效的序列化:Protobuf 使用二进制编码,相比于基于文本的序列化格式(例如 XML 和 JSON),它的序列化后的数据更加紧凑,占用更少的存储空间,并且传输效率更高。这对于网络传输和存储来说非常重要,尤其是在带宽和存储资源有限的环境下。
    跨语言支持:Protobuf 支持多种编程语言,包括但不限于 C++、Java、Python、Go、C# 等。这意味着你可以使用不同的编程语言开发的应用程序之间进行数据交换,而无需担心语言之间的兼容性问题。
    可扩展性:Protobuf 具有良好的可扩展性,可以轻松地添加、删除或修改消息的字段,而无需破坏现有的数据结构。这使得你的应用程序可以灵活地适应数据结构的变化,而无需进行繁琐的数据迁移或版本管理。
    易于维护:Protobuf 使用结构化的消息定义语言(IDL)来描述数据结构,这使得代码更易于理解和维护。通过定义消息的结构,你可以清晰地了解消息中包含的字段以及其类型,从而更好地理解和操作数据。
    自描述性:Protobuf 的消息格式是自描述的,也就是说,消息中包含了字段的标识符和类型信息。这使得消息能够在不同的系统之间进行交互,并能够正确地解析和处理消息,即使接收方对消息的结构不熟悉。
    总的来说,使用谷歌 Protocol Buffers 可以提供高效的序列化、跨语言支持、可扩展性、易于维护和自描述性等优势,使得数据交换和存储变得更加高效和灵活。

  • 相关阅读:
    后端程序员入门react笔记(五)ajax请求
    Learn Prompt-ChatGPT 精选案例:学习各国语言
    技术管理进阶——什么是管理者之体力、脑力、心力
    (自我介绍范文)java面试自我介绍
    transform + asm资料
    IDEA日志输出格式控制、文件记录日志
    2023年【T电梯修理】考试题及T电梯修理考试报名
    asp.net网站的建立及运行
    Linux安装Jenkins
    Mock数据:单元测试中的心灵鸡汤
  • 原文地址:https://blog.csdn.net/qq_40405527/article/details/127864550