sensor中间层 --- CalibrationManager

Posted Achillisjack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sensor中间层 --- CalibrationManager相关的知识,希望对你有一定的参考价值。

2, sensor中间层

HAL的中间层通过几个类来描述和管理每个sensor,类CalibrationManager管理sensor用到的校正算法模块,NativeSensorManager类则起承上启下

的作用,  framework层访问标准的HAL接口,然后这些HAL接口再通过NativeSensorManager类接口访问到具体的sensors,同时所有sensor信息也是

由这个类来描述。

CalibrationManager

先看看CalibrationManager的类定义,该类主要用来获取参数校准和转化模块的信息,定义如下:

class CalibrationManager : public Singleton<CalibrationManager> 
public:
//Get the whole algo list provided by the calibration library
const sensor_cal_algo_t** getCalAlgoList();
//Retrive a compatible calibration algo for sensor specified by t
const sensor_cal_algo_t* getCalAlgo(const sensor_t *s);
/* Dump the calibration manager status */
void dump();
~CalibrationManager();
private:
friend class Singleton<CalibrationManager>;
•••

这个类被定义在文件hardware/qcom/ sensor/CalibrationManager.h,方法实现在对应

的cpp文件中;

CalibrationManager类方法如下,

CalibrationManager::CalibrationManager()
:algo_list(NULL), algo_count(0)

loadCalLibs();

这是该类的构造函数,它将algo_list和algo_count都初始为0,只调了一个loadCalLibs函数,这个函数会加载所有的算法库,并从库中获取

所有的算法,它的实现如下:

void CalibrationManager::loadCalLibs()

int fd;
size_t len;
char buf[MAX_CAL_CFG_LEN];
char* cal_libs[MAX_CAL_LIBS];
struct sensor_cal_module_t* modules[MAX_CAL_LIBS];
•••

首先从/system/vendor/etc/calmodule.cfg文件中获取校正算法库的的路径信息,然后加载这些算法库,并从每个算法库中获取所有的算法,

成员变量algo_list数据保存所有的算法地址,成员algo_count记录算法的总个数这里有一个小的知识点:

在CalibrationModule.h中有如下定义:

#define SENSOR_CAL_MODULE_INFO  scmi
#define SENSOR_CAL_MODULE_INFO_AS_STR "scmi"

从上面的代码可知,从库中获取的描述算法模块的变量名都为scmi,因此所有的校准模块必须定义成如下类型:

struct sensor_cal_module_t SENSOR_CAL_MODULE_INFO=;
const sensor_cal_algo_t* CalibrationManager::getCalAlgo(constsensor_t *s/* = NULL*/)

uint32_t i = 0;
int j = 0;
const sensor_cal_algo_t **list = algo_list;
const sensor_cal_algo_t *tmp = NULL;
•••

该函数根据具体sensor_t找到algo_list算法列表中与之匹配的算法,SensorContext的sensor字段会指向一个sensor_t类似的结构体,

sensor_t这个结构体记录了每个sensor的name,handle,type等参数,会在下面章节详细讲述这些参数值的由来;该算法的匹配原则如下:

依次判断算法列表中的某个算法的compatible列表中的任何一个字符串与name字段是否相同,如果是则立马退出循环,并认为这个算法

是最匹配的,返回这个算法;如果不相同,则判断与type字段对应的name是否与compatible列表中的字符串相同,如果是,则用tmp暂存这个

算法,如果不是,则不用暂存这个算法,跳到下一个循环直到所有算法扫描完毕,最后把最后一个匹配的算法返回。该函数仅会被初始化

virtual sensor时调用,因为virtual sensor都是通过实际的sensor通过一定的算法计算得来。

   下面重点分析组织和管理每个sensor的类NativeSensorManager,在分析这个

类之前,先看看一些这个类所涉及的描述sensor的结构体:

struct SensorContext 
char  name[SYSFS_MAXLEN]; // name of the sensor
char  vendor[SYSFS_MAXLEN]; // vendor of the sensor
char  *enable_path; // the control path of this sensor
char  *data_path; // 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
•••

dep_list表示某个sensor依赖于的sensor的列表,例如实际的sensor依赖于它自己,virtual sensor可能依赖于某几个实际的sensor;

相反listener 表示监听这个sensor的其它sensor的列表。

struct SensorEventMap 
char data_name[80];
char data_path[PATH_MAX];
;

这个结构体描述了每个实际物理上的sensor设备驱动的event事件信息,data_path表示event输入事件的文件节点路径;data_name 

存储event设备对应input_dev 中的name字段;

struct sensor_t 
const char*  name;
const char*  vendor;
int  version;
int  handle;
int  type;
......

每个sensor都有一个这样的结构体,它存储了一个sensor的所有属性,如果是实际存在的sensor,这些属性从底驱动的属性节点中获取;

struct SysfsMap 
int offset;
const char *node;
int type;
int required; 
;

这个结构体描述了sensor驱动中每个属性节点的信息,offse表示sensor_t中的某个字段在该结构体中的偏移量,如name字段该值为0,

sensor_t每个属性对应的设备节点名,该名字由驱动决定,所以必须与驱动保持一致,type表示属性的类型,例如字符串、整型,required

字段若为0表示即使该节点找不到,也返回正确;

struct SensorRefMap 
struct listnode list;
struct SensorContext *ctx;
;

这是一个引用,list 字段把某个sensor链入到dep_list和listener 链表中,ctx指向这个引用对应的SensorContext;

以上是关于sensor中间层 --- CalibrationManager的主要内容,如果未能解决你的问题,请参考以下文章

2009 Land Rover Discovery 3 ABS Steering Angle Sensor Calibration Learning with launch X431 Diagnost

sensor中间层 --- CalibrationManager

sensor中间层 --- NativeSensorManager

OpenHarmony 通俗易懂讲解Sensor订阅流程

读取GY-951模块数据(Linux)

心率传感器pulse sensor 与单片机相连接来测心率,中间要加放大和滤波的元器件吗?