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的操作方法:

posted @ 2021-06-19 18:08  mail181  阅读(70)  评论(0)    收藏  举报