Android Sensor NativeSensorManager
路径:code/hardware/qcom/sensors/NativeSensorManager.cpp
code/hardware/qcom/sensors/NativeSensorManager.h
两个核心结构:
- SensorContext 结构体
- NativeSensorManager本地类
附带衍生结构
- SysfsMap
- SensorEventMap
- SensorRefMap
class NativeSensorManager : public Singleton<NativeSensorManager> {
friend class Singleton<NativeSensorManager>;
NativeSensorManager();
~NativeSensorManager();
struct sensor_t sensor_list[MAX_SENSORS]; //!< sensorlist数组 >! NoteBy: yujixuan
struct SensorContext context[MAX_SENSORS]; //!< context数组 >! NoteBy: yujixuan
struct SensorEventMap event_list[MAX_SENSORS]; //!< 用于上报的evnet 数组 >! NoteBy: yujixuan
static const struct SysfsMap node_map[]; //sysfs 设备节点名
static const struct sensor_t virtualSensorList[];
static char virtualSensorName[][SYSFS_MAXLEN];
int mSensorCount;
bool mScanned;
int mEventCount;
DefaultKeyedVector<int32_t, struct SensorContext*> type_map;
DefaultKeyedVector<int32_t, struct SensorContext*> handle_map;
DefaultKeyedVector<int, struct SensorContext*> fd_map;
void compositeVirtualSensorName(const char *sensor_name, char *chip_name, int type);
int getNode(char *buf, char *path, const struct SysfsMap *map);
int getSensorListInner();
int getDataInfo();
int registerListener(struct SensorContext *hw, struct SensorContext *virt);
int unregisterListener(struct SensorContext *hw, struct SensorContext *virt);
int syncDelay(int handle);
int initCalibrate(const SensorContext *list);
int initVirtualSensor(struct SensorContext *ctx, int handle, struct sensor_t info);
int addDependency(struct SensorContext *ctx, int handle);
int getEventPath(const char *sysfs_path, char *event_path);
int getEventPathOld(const struct SensorContext *list, char *event_path);
public:
int getSensorList(const sensor_t **list); //!< 获取sensor列表 >! NoteBy: yujixuan
inline SensorContext* getInfoByFd(int fd) { return fd_map.valueFor(fd); };
inline SensorContext* getInfoByHandle(int handle) { return handle_map.valueFor(handle); };
inline SensorContext* getInfoByType(int type) { return type_map.valueFor(type); };
int getSensorCount() {return mSensorCount;}
void dump();
int hasPendingEvents(int handle);
int activate(int handle, int enable);
int setDelay(int handle, int64_t ns);
int syncLatency(int handle);
int readEvents(int handle, sensors_event_t *data, int count); //!< 读取events >! NoteBy: yujixuan
int calibrate(int handle, struct cal_cmd_t *para);
int batch(int handle, int64_t sample_ns, int64_t latency_ns);
int flush(int handle);
};
首先可以注意到的是 NativeSensorManager是继承了Singleton;是单例模式
struct SensorContext {
char name[SYSFS_MAXLEN]; // name of the sensor
char vendor[SYSFS_MAXLEN]; // vendor of the sensor
char enable_path[PATH_MAX]; // the control path of this sensor
char data_path[PATH_MAX]; // the data path to get sensor events
struct sensor_t *sensor; // point to the sensor_t structure in the sensor list
SensorBase *driver; // point to the sensor driver instance
int data_fd; // the file descriptor of the data device node
int enable; // indicate if the sensor is enabled
bool is_virtual; // indicate if this is a virtual sensor
int64_t delay_ns; // the poll delay setting of this sensor
int64_t latency_ns; // the max report latency of this sensor
struct listnode dep_list; // the background sensor type needed for this sensor
struct listnode listener; // the head of listeners of this sensor
};
SensorContext记录了重要的sensor相关数据结构:
sensor_t *sensor; 指向由sensor_t构成的sensor list
SensorBase *driver; 指向 driver,是调用对应sensor 驱动的关键
NativeSensorManager提供了node_map中存放着所有可以解析的节点名,并提供获取它们的方法:
const struct SysfsMap NativeSensorManager::node_map[] = {
{offsetof(struct sensor_t, name), SYSFS_NAME, TYPE_STRING, 1},
{offsetof(struct sensor_t, vendor), SYSFS_VENDOR, TYPE_STRING, 1},
{offsetof(struct sensor_t, version), SYSFS_VERSION, TYPE_INTEGER, 1},
{offsetof(struct sensor_t, type), SYSFS_TYPE, TYPE_INTEGER, 1},
{offsetof(struct sensor_t, maxRange), SYSFS_MAXRANGE, TYPE_FLOAT, 1},
{offsetof(struct sensor_t, resolution), SYSFS_RESOLUTION, TYPE_FLOAT, 1},
{offsetof(struct sensor_t, power), SYSFS_POWER, TYPE_FLOAT, 1},
{offsetof(struct sensor_t, minDelay), SYSFS_MINDELAY, TYPE_INTEGER, 1},
{offsetof(struct sensor_t, fifoReservedEventCount), SYSFS_FIFORESVCNT, TYPE_INTEGER, 0},
{offsetof(struct sensor_t, fifoMaxEventCount), SYSFS_FIFOMAXCNT, TYPE_INTEGER, 0},
#if defined(SENSORS_DEVICE_API_VERSION_1_3)
#if defined(__LP64__)
{offsetof(struct sensor_t, maxDelay), SYSFS_MAXDELAY, TYPE_INTEGER64, 0},
{offsetof(struct sensor_t, flags), SYSFS_FLAGS, TYPE_INTEGER64, 0},
#else
{offsetof(struct sensor_t, maxDelay), SYSFS_MAXDELAY, TYPE_INTEGER, 0},
{offsetof(struct sensor_t, flags), SYSFS_FLAGS, TYPE_INTEGER, 0},
#endif
#endif
};
readEvents
int NativeSensorManager::readEvents(int handle, sensors_event_t* data, int count)
{
const SensorContext *list;
int i, j;
int number = getSensorCount();
int nb;
struct listnode *node;
struct SensorRefMap *item;
list = getInfoByHandle(handle);
if (list == NULL) {
ALOGE("Invalid handle(%d)", handle);
return -EINVAL;
}
do {
nb = list->driver->readEvents(data, count);
} while ((nb == -EAGAIN) || (nb == -EINTR));
for (j = 0; j < nb; j++) {
list_for_each(node, &list->listener) {
item = node_to_item(node, struct SensorRefMap, list);
if (item->ctx->enable && (item->ctx != list)) {
item->ctx->driver->injectEvents(&data[j], 1);
}
}
}
if (list->enable)
return nb;
/* No need to report the events if the sensor is not enabled */
return 0;
}
维护管理 各种 虚拟sensor
支持的虚拟sensor有:
enum {
ORIENTATION = 0,
PSEUDO_GYROSCOPE,
ROTATION_VECTOR,
GAME_ROTATION_VECTOR,
LINEAR_ACCELERATION,
GRAVITY,
POCKET,
VIRTUAL_SENSOR_COUNT,
};
char NativeSensorManager::virtualSensorName[VIRTUAL_SENSOR_COUNT][SYSFS_MAXLEN];
默认初始化填充:(只贴出前两个)
const struct sensor_t NativeSensorManager::virtualSensorList [VIRTUAL_SENSOR_COUNT] = {
[ORIENTATION] = {
.name = virtualSensorName[ORIENTATION],
.vendor = "oem",
.version = 1,
.handle = '_dmy',
.type = SENSOR_TYPE_ORIENTATION,
.maxRange = 360.0f,
.resolution = 1.0f/256.0f,
.power = 1,
.minDelay = 10000,
.fifoReservedEventCount = 0,
.fifoMaxEventCount = 0,
#if defined(SENSORS_DEVICE_API_VERSION_1_3)
.stringType = NULL,
.requiredPermission = NULL,
.maxDelay = 0,
.flags = SENSOR_FLAG_CONTINUOUS_MODE,
#endif
.reserved = {},
},
[PSEUDO_GYROSCOPE] = {
.name = virtualSensorName[PSEUDO_GYROSCOPE],
.vendor = "oem",
.version = 1,
.handle = '_dmy',
.type = SENSOR_TYPE_GYROSCOPE,
.maxRange = 50.0f,
.resolution = 0.01f,
.power = 1,
.minDelay = 10000,
.fifoReservedEventCount = 0,
.fifoMaxEventCount = 0,
#if defined(SENSORS_DEVICE_API_VERSION_1_3)
.stringType = NULL,
.requiredPermission = NULL,
.maxDelay = 0,
.flags = SENSOR_FLAG_CONTINUOUS_MODE,
#endif
.reserved = {},
},
4.2.3 虚拟传感器管理 虚拟传感器由 NativeSensorManager 管理。
目前支持的虚拟传感器有方向、线加速度、重力、旋转矢量、伪陀螺仪和未校准磁场。
但是,大多数虚拟传感器算法是由第三方提供的,例如传感器芯片供应商。
我们还添加了一些示例算法,它们可以工作,但性能不是那么好。
目前的逻辑是查询校准库以找出支持的算法。校准库中定义的算法提供了一个兼容列表,这是为了适应 HAL 中的传感器列表。例如,旋转矢量传感器算法可能包含“oem-
旋转矢量”在兼容列表中。NativeSensorManager 将选择它作为计算旋转矢量传感器数据的默认算法。
NativeSensorManager 也会选择兼容列表中列出的“旋转矢量”的算法,
因为它是旋转的默认名称矢量传感器名称。默认兼容传感器名称的完整列表可以在
“hardware/cqcom/sensors/CalibrationModule.h
4.3 虚拟传感器 通常,虚拟传感器由传感器融合算法提供。
这些融合算法可以由 SoC 供应商和/或传感器供应商提供。
如果设备没有这些实现,Android 还提供旋转矢量、重力和线性加速度的默认实现。
但是,该实现仅在设备具有陀螺仪、加速度计和磁力计时可用。
默认实现无法访问其他实现可以访问的所有数据,并且它必须在 SoC 上运行,
因此它不像其他实现那样准确和节能。设备制造商应尽可能定义自己的融合传感器。
NativeSensorManager 管理虚拟传感器。它实现以下功能:
1.找出设备支持的硬件传感器,检查是否满足融合虚拟传感器的条件。
2.搜索校准库中的所有算法并检查是否有任何融合传感器算法出现。
3.注册虚拟传感器算法。
4.拦截硬件传感器数据流并将其注入到虚拟传感器算法中。
5.将计算出的虚拟传感器事件发送到Android框架。
6.处理虚拟传感器启用/禁用和轮询延迟设置。
4.3.2 虚拟传感器的工作原理 每个虚拟传感器都有一个或多个后台硬件传感器。
每个硬件传感器代表一个 Linux kemel 实现。这些背景传感器称为依赖性传感器。
要激活虚拟传感器,依赖传感器将被实际激活。
该操作由传感器 HAL 处理,对用户空间应用程序是透明的。
硬件传感器数据流向虚拟传感器算法并计算结果。
结果将发送到框架,框架代表虚拟传感器的传感器事件。
4.3.3 添加自定义虚拟传感器 自定义虚拟传感器可以添加到实现中。要添加自定义虚拟传感器,请按照以下步骤操作:
1. 将算法添加到校准库中。可以参考hardware/qcom/sensors/algo/common/common_wrapper.c
2. 更改校准模块。 cfg 以包含校准库。
3. 修改 NativeSensorManager。 cpp 添加对此类虚拟传感器的支持。你可以参考:
5. 实例化虚拟传感器。
NativeSensorManger中实现的方法即 hal中对sensor的操作方法:

浙公网安备 33010602011771号