Android Sensor详解(8)sensor hal层分析第一篇
前言
高通的hal层其实分2种,一种是直接从kernel这边报数据上来,由sensorhal层来监听,另外一种是走ADSP的模式,HAL层通过qmi的形式进行监听的。
hal层简介
Google为Sensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层,Android中Sensor的HAL接口定义在:hardware/libhardware/include/hardware/sensors.h
为了理清HAL层的sensor我们必须要理解几个概念,分别是sensor_type,sensor_module,sensor_t,sensor_
/* * SENSOR_TYPE_ACCELEROMETER * reporting-mode: continuous * * All values are in SI units (m/s^2) and measure the acceleration of the * device minus the force of gravity. * * Implement the non-wake-up version of this sensor and implement the wake-up * version if the system possesses a wake up fifo. */#define SENSOR_TYPE_ACCELEROMETER (1)#define SENSOR_STRING_TYPE_ACCELEROMETER "android.sensor.accelerometer"
从上面可以看到此文件定义了sensor的type以及string type.
/** * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM * and the fields of this data structure must begin with hw_module_t * followed by module specific information. */struct sensors_module_t { struct hw_module_t common; /** * Enumerate all available sensors. The list is returned in "list". * @return number of sensors in the list */ int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list); /** * Place the module in a specific mode. The following modes are defined * * 0 - Normal operation. Default state of the module. * 1 - Loopback mode. Data is injected for the supported * sensors by the sensor service in this mode. * @return 0 on success * -EINVAL if requested mode is not supported * -EPERM if operation is not allowed */ int (*set_operation_mode)(unsigned int mode);};
该接口的定义实际上是对标准的硬件模块hw_module_t的一个扩展,增加了一个get_sensors_list函数,用于获取传感器的列表,以及set_operation_mode 设置成相关的mode
struct sensor_t { /* Name of this sensor. * All sensors of the same "type" must have a different "name". */ const char* name; //传感器名字 /* vendor of the hardware part */ const char* vendor; /* version of the hardware part + driver. The value of this field * must increase when the driver is updated in a way that changes the * output of this sensor. This is important for fused sensors when the * fusion algorithm is updated. */ int version; //版本 /* handle that identifies this sensors. This handle is used to reference * this sensor throughout the HAL API. */ int handle; //传感器的handle句柄 /* this sensor's type. */ int type; //传感器类型 /* maximum range of this sensor's value in SI units */ float maxRange; //最大范围 /* smallest difference between two values reported by this sensor */ float resolution; //解析度 /* rough estimate of this sensor's power consumption in mA */ float power; /* this value depends on the reporting mode: * * continuous: minimum sample period allowed in microseconds * on-change : 0 * one-shot :-1 * special : 0, unless otherwise noted */ int32_t minDelay; /* number of events reserved for this sensor in the batch mode FIFO. * If there is a dedicated FIFO for this sensor, then this is the * size of this FIFO. If the FIFO is shared with other sensors, * this is the size reserved for that sensor and it can be zero. */ uint32_t fifoReservedEventCount; /* maximum number of events of this sensor that could be batched. * This is especially relevant when the FIFO is shared between * several sensors; this value is then set to the size of that FIFO. */ uint32_t fifoMaxEventCount; /* type of this sensor as a string. Set to corresponding * SENSOR_STRING_TYPE_*. * When defining an OEM specific sensor or sensor manufacturer specific * sensor, use your reserve domain name as a prefix. * ex: com.google.glass.onheaddetector * For sensors of known type, the android framework might overwrite this * string automatically. */ const char* stringType; /* permission required to see this sensor, register to it and receive data. * Set to "" if no permission is required. Some sensor types like the * heart rate monitor have a mandatory require_permission. * For sensors that always require a specific permission, like the heart * rate monitor, the android framework might overwrite this string * automatically. */ const char* requiredPermission; /* This value is defined only for continuous mode and on-change sensors. It is the delay between * two sensor events corresponding to the lowest frequency that this sensor supports. When lower * frequencies are requested through batch()/setDelay() the events will be generated at this * frequency instead. It can be used by the framework or applications to estimate when the batch * FIFO may be full. * * NOTE: 1) period_ns is in nanoseconds where as maxDelay/minDelay are in microseconds. * continuous, on-change: maximum sampling period allowed in microseconds. * one-shot, special : 0 * 2) maxDelay should always fit within a 32 bit signed integer. It is declared as 64 bit * on 64 bit architectures only for binary compatibility reasons. * Availability: SENSORS_DEVICE_API_VERSION_1_3 */ #ifdef __LP64__ int64_t maxDelay; #else int32_t maxDelay; #endif /* Flags for sensor. See SENSOR_FLAG_* above. Only the least significant 32 bits are used here. * It is declared as 64 bit on 64 bit architectures only for binary compatibility reasons. * Availability: SENSORS_DEVICE_API_VERSION_1_3 */ #ifdef __LP64__ uint64_t flags; #else uint32_t flags; #endif /* reserved fields, must be zero */ void* reserved[2];};
可以看出现在的android 7.1.1已经有了一些变化了,
从前reserved[8]现在已经只有reserved[2]了.
主要的方面新增方面:
* fifoReservedEventCount
* fifoMaxEventCount
* stringType
* requiredPermission
* maxDelay
* flags
为了不误导大家就让大家直接读code里面的注释,毕竟google介绍的还是很详尽的。
* Union of the various types of sensor data * that can be returned. */typedef struct sensors_event_t { /* must be sizeof(struct sensors_event_t) */ int32_t version; /* sensor identifier */ int32_t sensor; /* sensor type */ int32_t type; /* reserved */ int32_t reserved0; /* time is in nanosecond */ int64_t timestamp; union { union { float data[16]; /* acceleration values are in meter per second per second (m/s^2) */ sensors_vec_t acceleration; /* magnetic vector values are in micro-Tesla (uT) */ sensors_vec_t magnetic; /* orientation values are in degrees */ sensors_vec_t orientation; /* gyroscope values are in rad/s */ sensors_vec_t gyro; /* temperature is in degrees centigrade (Celsius) */ float temperature; /* distance in centimeters */ float distance; /* light in SI lux units */ float light; /* pressure in hectopascal (hPa) */ float pressure; /* relative humidity in percent */ float relative_humidity; /* uncalibrated gyroscope values are in rad/s */ uncalibrated_event_t uncalibrated_gyro; /* uncalibrated magnetometer values are in micro-Teslas */ uncalibrated_event_t uncalibrated_magnetic; /* heart rate data containing value in bpm and status */ heart_rate_event_t heart_rate; /* this is a special event. see SENSOR_TYPE_META_DATA above. * sensors_meta_data_event_t events are all reported with a type of * SENSOR_TYPE_META_DATA. The handle is ignored and must be zero. */ meta_data_event_t meta_data; /* dynamic sensor meta event. See SENSOR_TYPE_DYNAMIC_SENSOR_META type for details */ dynamic_sensor_meta_event_t dynamic_sensor_meta; /* * special additional sensor information frame, see * SENSOR_TYPE_ADDITIONAL_INFO for details. */ additional_info_event_t additional_info; }; union { uint64_t data[8]; /* step-counter */ uint64_t step_counter; } u64; }; /* Reserved flags for internal use. Set to zero. */ uint32_t flags; uint32_t reserved1[3];} sensors_event_t;
不过目前就我工作中的话尚未使用到这边,一边来讲厂商更愿意的是自己来定制HAL层。
定制hal层
首先来看一个Android.mk来分析厂商是咋么定制的
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := sensors.PALS.msm8953######################## For 64/32 but build#ifeq ($(TARGET_ARCH), arm64)LOCAL_MODULE_PATH_64 := $(TARGET_OUT_SHARED_LIBRARIES)elseLOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)endif#######################LOCAL_PRELINK_MODULE := falseLOCAL_MODULE_TAGS := optionalLOCAL_MODULE_OWNER := ALEXLOCAL_CFLAGS := -DLOG_TAG=\"Sensors\"## ANDROID version checkMAJOR_VERSION :=$(shell echo $(PLATFORM_VERSION) | cut -f1 -d.)MINOR_VERSION :=$(shell echo $(PLATFORM_VERSION) | cut -f2 -d.)VERSION_JB :=$(shell test $(MAJOR_VERSION) -gt 4 -o $(MAJOR_VERSION) -eq 4 -a $(MINOR_VERSION) -gt 0 && echo true)$(info MAJOR_VERSION=$(MAJOR_VERSION))$(info MINOR_VERSION=$(MINOR_VERSION))#ANDROID version check ENDifeq ($(VERSION_JB),true)LOCAL_CFLAGS += -DANDROID_JELLYBEANendif# c fileLOCAL_SRC_FILES := SensorBase.cppLOCAL_SRC_FILES += InputEventReader.cppLOCAL_SRC_FILES += sensors_mpl.cppLOCAL_SRC_FILES += LightSensor.cppLOCAL_SRC_FILES += ProximitySensor.cpp# share libLOCAL_SHARED_LIBRARIES := libcutilsLOCAL_SHARED_LIBRARIES += libutilsLOCAL_SHARED_LIBRARIES += libdlLOCAL_SHARED_LIBRARIES += liblog#LOCAL_SHARED_LIBRARIES += libmlliteinclude $(BUILD_SHARED_LIBRARY)
从上面我们可以看出将会生意一个名为libsensor.PALS.msm8953.so的档做为库,具体系统是咋么将这个so档起作用的,后面我们再分析,先分析一下HAL层一些做法。
更多相关文章
- 实例+详解剖析Android之自定义View
- 自定义android用户控件,使用回调函数实现自定义事件
- android新闻项目、饮食助手、下拉刷新、自定义View进度条、React
- Android 完美解决自定义preference与ActivityGroup UI更新的问题
- 自定义Android注解Part1:注解变量