前言
高通的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层。
首先来看一个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)
else
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
endif
#######################
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_OWNER := ALEX
LOCAL_CFLAGS := -DLOG_TAG=\"Sensors\"
#
# ANDROID version check
MAJOR_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 END
ifeq ($(VERSION_JB),true)
LOCAL_CFLAGS += -DANDROID_JELLYBEAN
endif
# c file
LOCAL_SRC_FILES := SensorBase.cpp
LOCAL_SRC_FILES += InputEventReader.cpp
LOCAL_SRC_FILES += sensors_mpl.cpp
LOCAL_SRC_FILES += LightSensor.cpp
LOCAL_SRC_FILES += ProximitySensor.cpp
# share lib
LOCAL_SHARED_LIBRARIES := libcutils
LOCAL_SHARED_LIBRARIES += libutils
LOCAL_SHARED_LIBRARIES += libdl
LOCAL_SHARED_LIBRARIES += liblog
#LOCAL_SHARED_LIBRARIES += libmllite
include $(BUILD_SHARED_LIBRARY)
从上面我们可以看出将会生意一个名为libsensor.PALS.msm8953.so的档做为库,具体系统是咋么将这个so档起作用的,后面我们再分析,先分析一下HAL层一些做法。