二:Sensor Hal层代码分析
Hal code放在/vendor/qcom/proprietary/sensors-see/中
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