高通SDM845平台Sensor学习——2.Hal层

本文详细分析了高通SDM845平台上Sensor Hal层的代码结构和工作原理,重点讲解了sensors文件夹中各sensor类的实现,如accelerometer.cpp,以及framework文件夹的功能。在sensors文件夹中,每个sensor的cpp文件实现了特定的操作,如accelerometer_module_init在加载.so时调用。在framework中,通过sensors_module_t结构与get_sensor_list函数获取sensor列表。文章还介绍了如何启用/禁用Sensor,以及Factory Calibration的过程,包括获取suid、启用sensor和校准操作。
摘要由CSDN通过智能技术生成
二:Sensor Hal层代码分析

Hal code放在/vendor/qcom/proprietary/sensors-see/中

图5

sensors-hal文件夹中包含framework和sensors文件夹,为本文重点分析对象。

首先分析sensors文件夹:
根据C++继承的特性,相同的操作各个class共同拥有,不同的操作每个class可以重写,该文件夹内文件为每个sensor不同的地方,porting sensor主要是在这部分做的。sensors文件夹中包含很多sensor cpp文件比如:accelerometer.cpp为accel sensor的hal层code,step_count.cpp为计步器的hal层的code等等,主要是针对不同sensor type的操作。下面以accelerometer.cpp为例:

//accelerometer.cpp
SENSOR_MODULE_INIT(accelerometer_module_init);

//sensor.h
#define SENSOR_MODULE_INIT(module_init_func) \
    static const bool __mod_init = (module_init_func)();

每个cpp都有SENSOR_MODULE_INIT入口,__mod_init具体实现在code没有找到,不过应该类似kernel中module_init,在系统加载.so时调用。故可知,所有特定sensor的cpp在加载.so时会被调SENSOR_MODULE_INIT进行加载。

//accelerometer.cpp
static bool accelerometer_module_init()
{
    /* register supported sensor types with factory */
    sensor_factory::register_sensor(SENSOR_TYPE_ACCELEROMETER,
                                    get_available_accel_calibrated);
    sensor_factory::register_sensor(SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED,
                                    get_available_accel_uncalibrated);
    sensor_factory::request_datatype(SSC_DATATYPE_ACCEL);
    return true;
}

//sensor_factory.h
static void register_sensor(int type, get_available_sensors_func func)
    {
        try {
            callbacks().emplace(type, func);
        } catch (const std::exception& e) {
            sns_loge("failed to register type %d", type);
        }
    }
static std::unordered_map<int, get_available_sensors_func>& callbacks()
    {
        static std::unordered_map<int, get_available_sensors_func> _callbacks;
        return _callbacks;
    }

//sensor_factory.h
static void request_datatype(const char *datatype)
    {
        try {
            datatypes().insert(std::string(datatype));
        } catch (const std::exception& e) {
            sns_loge("failed to insert %s", datatype);
        }
    }

所以在,在.so被调用后,accelerometer_module_init会被执行!通过register_sensor将type和func放入callbacks的unordered_map中。并将datatype插入到datatypes的unordered_set中,以便后面使用。

下面以get_available_accel_calibrated为例继续研究:

//accelerometer.cpp
static vector<unique_ptr<sensor>> get_available_accel_calibrated()
{
    const vector<sensor_uid>& accel_suids =
         sensor_factory::instance().get_suids(SSC_DATATYPE_ACCEL);  //  No.1
    vector<unique_ptr<sensor>> sensors;
    for (const auto& suid : accel_suids) {
        if (!(sensor_factory::instance().get_settings()              // No.2
                                    & DISABLE_WAKEUP_SENSORS_FLAG)) {
            try {
                sensors.push_back(make_unique<accelerometer>(suid, SENSOR_WAKEUP,  //No.3
                                                         SENSOR_CALIBRATED));
            } catch (const exception& e) {
                sns_loge("failed for wakeup, %s", e.what());
            }
        }
        try {
            sensors.push_back(make_unique<accelerometer>(suid, SENSOR_NO_WAKEUP,
                                                     SENSOR_CALIBRATED));
        } catch (const exception& e) {
            sns_loge("failed for nowakeup, %s", e.what());
        }
    }
    return sensors;
}

No.1中:accel_suids可以通过sensor_factory实例中get_suids函数来获取:

const std::vector<sensor_uid>& sensor_factory::get_suids(const std::string& datatype) const
{
    auto it = _suid_map.find(datatype);
    if (it != _suid_map.end()) {
        return it->second;
    } else {
        static vector<sensor_uid> empty;
        return empty;
    }
}

从_suids_map中查找datatype来获取accel的suid。那什么时候将accel的suid插入到_suids_map中内,在framework文件夹中,后续会介绍。

No.2中:通过getsetting来查看是否有DISABLE_WAKEUP_SENSORS_FLAG flag,若有则为no wakeup,若无则为wake up sensor。

No.3中:为调用accelerometer的构造函数。

accelerometer::accelerometer(sensor_uid suid,
                                sensor_wakeup_type wakeup,
                                sensor_cal_type cal_type):
    ssc_sensor(suid, wakeup)              // No.a
{
    if (cal_type == SENSOR_UNCALIBRATED) {                                    // No.b
        set_type(SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED);
        set_string_type(SENSOR_STRING_TYPE_ACCELEROMETER_UNCALIBRATED);
        set_sensor_typename("Accelerometer-Uncalibrated");
    } else {
        set_type(SENSOR_TYPE_ACCELEROMETER);
        set_string_type(SENSOR_STRING_TYPE_ACCELEROMETER);
        set_sensor_typename("Accelerometer");
    }
   ...
    _cal_type = cal_type;
    set_fifo_reserved_count(ACCEL_RESERVED_FIFO_COUNT);
    set_resampling(true);

    /* convert range from Gs to m/s^2 */
    set_max_range(get_sensor_info().maxRange * ONE_G);
    /* convert resolution from mG to m/s^2 */
    set_resolution(get_sensor_info().resolution * ONE_G / 1000.0);

}

No.a中:继承ssc_sensor,ssc_sensor的构造函数中,主要设置一些common的参数。
No.b中:设置accel中不common的参数。比如string_type、sensor_typename、是否使用resampling、最大range、分辨率等等。

Ok,accelerometer.cpp基本介绍完毕。
对了,还有个handle_sns_std_sensor_event函数是干什么的呢?

//accelerometer.cpp
virtual void handle_sns_std_sensor_event(
        const sns_client_event_msg_sns_client_event& pb_event) override;

void accelerometer::handle_sns_std_sensor_event(
    const sns_client_event_msg_sns_client_event& pb_event)
{
    sns_std_sensor_event pb_sensor_event;
    pb_sensor_event.ParseFromString(pb_event.payload());

    sensors_event_t hal_event = create_sensor_hal_event(pb_event.timestamp());

    if (_cal_type == SENSOR_CALIBRATED) {
        hal_event.acceleration.x = pb_sensor_event.data(0);
        hal_event.acceleration.y = pb_sensor_event.data(1);
        hal_event.acceleration.z = pb_sensor_event.data(2);
        hal_event.acceleration.status =
            sensors_hal_sample_status(pb_sensor_event.status());
      ...
    }

    if (_cal_type == SENSOR_UNCALIBRATED) {
        hal_event.uncalibrated_accelerometer.x_uncalib = pb_sensor_event.data(0);
        hal_event.uncalibrated_accel
  • 12
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值