android sensor移植

来源:互联网 发布:上海狮翼网络 编辑:程序博客网 时间:2024/06/05 11:49

sensor直接连接到应用处理器,并有linuxkernel管理。本文涉及到kernel驱动,sensor HAL以及SensorService。

sensor架构

安卓提供Sensor API和SensorManager,然而没有提供Sensor HAL和sensor驱动。

电源管理和管脚功能设置在设备树中应当设置好,Sensor类用于支持一些新特性。增加了一些sensor新特性,如:NativeSensorManager,,CalibrationManager,虚拟传感器支持,

传感器驱动

内核sensor驱动,包括电源,pin脚,传感器类,通常传感器驱动位于drivers/input/misc/。

传感器的电源

设备树配置

传感器芯片的驱动由sensor的probe驱动设置,mmc3416xpj的配置驱动如下:

[cpp] view plain copy
  1. memsic@30 { /* Magnetic field sensor */  
  2. compatible = "memsic,mmc3416x";  
  3. reg = <0x30>;  
  4. vdd-supply = <&pm8916_l17>;  
  5. vio-supply = <&pm8916_l6>;  
  6. memsic,dir = "obverse-x-axis-forward";  
  7. memsic,auto-report;  
  8. };  
vdd-supply:指示给传感器供电的电源器件;pm8916_l17电源管理器

vio-supply:IO和I2C需要的数字电源,pm8916_l6是电源管理器

[plain] view plain copy
  1. arch/arm/boot/dts/qcom/xxxx-regulator.dtsi  
更多设备树定义见:

[plain] view plain copy
  1. kernel/Documentation/bindings/input/misc/ .  

regulator

在操作sensor chip之前需要初始化该芯片,regulator_get,regualator_count_voltages,regulator_set_voltages , regulator_enable ,以及regulator_disable。

管脚控制

设备树配置

[plain] view plain copy
  1. akm@c {  
  2. compatible = "ak,ak09911";  
  3. reg = <0x0c>;  
  4. pinctrl-names = "default","sleep";  
  5. pinctrl-0 = <&akm_default>;  
  6. pinctrl-1 = <&akm_sleep>;  
  7. vdd-supply = <&pm8916_l17>;  
  8. vio-supply = <&pm8916_l6>;  
  9. akm,layout = <0x3>;  
  10. akm,gpio_rstn = <&msm_gpio 36 0x0>;  
  11. akm,auto-report;  
  12. };  
  13. akm_reset_pin {  
  14. qcom,pins = <&gp 36>;  
  15. qcom,pin-func = <0>;  
  16. qcom,num-grp-pins = <1>;  
  17. label = "akm_reset_pin";  
  18. akm_default: akm_default {  
  19. drive-strength = <6>;  
  20. bias-pull-up;  
  21. };  
  22. akm_sleep: akm_sleep {  
  23. drive-strength = <2>;  
  24. bias-pull-down;  
  25. };  
  26. };  

pinctrl初始化

在probe是被调用。

pinctrl_get()--获得设备的pinctrl

pinctrl_lookup_state()--获取管脚状态

pinctrl_select_state()--设置硬件管脚状态

可以参考drivers/input/misc/akm09911.c提供的pin脚相关详细信息。

Sensor 类支持

这个是sensor类框架如下:



为了支持这一通用架构,需要按增加一些callback支持。

1.添加头文件

[cpp] view plain copy
  1. #include <linux/sensors.h>  
2.增加sensors_classdev类

[cpp] view plain copy
  1. static struct sensors_classdev sensors_cdev;  
  2. struct sensor_data {  
  3. ... ...  
  4. struct sensors_classdev cdev;  
  5. }  
3.注册设备类

[plain] view plain copy
  1. sensors_classdev_register(&client->dev, &sensor_data->cdev);  

4.在注册设备之前填充结构体相关字段

[plain] view plain copy
  1. .name = "kxtj9-accel",  
  2. .vendor = "Kionix",  
  3. .version = 1,  
  4. .handle = 0,  
  5. .type = 1,  
  6. .max_range = "19.6",  
  7. .resolution = "0.01",  
  8. .sensor_power = "0.2",  
  9. .min_delay = 2000,  
  10. .fifo_reserved_event_count = 0,  
  11. .fifo_max_event_count = 0,  
  12. .enabled = 0  
  13. .delay_msec = 200,  
  14. .sensors_enable = NULL,  
  15. .sensors_poll_delay = NULL,  
  16. }  
5.实现回调

[plain] view plain copy
  1. data->cdev.sensors_enable = sensor_enable_set;  
  2. data->cdev.sensors_poll_delay = sensor_poll_delay_set;  
可以参考drivers/input/misc/mmc3416x.c
推荐使用cdev name注册到sensor类。

Native sensor HAL

其定义于

[plain] view plain copy
  1. hardware/libhardware/include/hardware/sensors.h  

CalibrationManager

数据结构

CalibrationManager加载第三方校正库,calibration 模块数据被用于HAL和第三方库,定义于:

[plain] view plain copy
  1. hardware/qcom/sensors/CalibrationModule.h  
[cpp] view plain copy
  1. struct sensor_cal_algo_t;  
  2. struct sensor_cal_module_t;  
  3. struct sensor_algo_args {  
  4.     int enable;  
  5.     int delay_ms;  
  6.     struct sensor_t sensor;  
  7.     int (*store_calibrate_params)(struct sensor_t *sensor, struct  
  8.     sensors_event_t *bias);  
  9. };  
  10. struct compass_algo_args {  
  11.     struct sensor_algo_args common;  
  12.     uint32_t reserved[16];  
  13. };  
  14. struct gyro_algo_args {  
  15.     struct sensor_algo_args common;  
  16.     float bias[3];  
  17. };  
  18. struct sensor_algo_methods_t {  
  19.     int (*convert)(sensors_event_t *raw, sensors_event_t *result, struct  
  20.     sensor_algo_args *args);  
  21.     /* Note that the config callback is called from a different thread as 
  22.     convert */  
  23.     int (*config)(int cmd, struct sensor_algo_args *args);  
  24. };  
  25. struct sensor_cal_methods_t {  
  26.     int (*init)(const struct sensor_cal_module_t* module, struct  
  27.     sensor_algo_args *args);  
  28.     void (*deinit)();  
  29.     /* Return 0 on success */  
  30.     int (*get_algo_list)(const struct sensor_cal_algo_t **algo);  
  31. };  
  32. struct sensor_cal_algo_t {  
  33.     /* Tag of the algo */  
  34.    int tag;  
  35.    /* Version of the algo */  
  36.    int version;  
  37.    /* Type of sensor this algo supported*/  
  38.    int type;  
  39.    /* The compatible sensors */  
  40.    const char **compatible;  
  41.    /* Sensor calibration module */  
  42.    struct sensor_cal_module_t *module;  
  43.    /* Sensor algo methods */  
  44.    struct sensor_algo_methods_t *methods;  
  45. };  
  46. struct sensor_cal_module_t {  
  47.   /* Tag of the module */  
  48.   uint32_t tag;  
  49.   /* Id of the module */  
  50.   char *id;  
  51.   /* Version of the calibration module */  
  52.   uint32_t version;  
  53.   /* Vendor of the calibration lib */  
  54.   char *vendor;  
  55.   /* Point to the handle of this module */  
  56.   void *dso;  
  57.   /* Number of algos */  
  58.   uint32_t number;  
  59.   /* Callbacks of the calibration lib provided */  
  60.   struct sensor_cal_methods_t *methods;  
  61.   /* The compatible sensors list for this library */  
  62.   int reserved[6];  
  63. };  
sensor_cal_module_t定义了该模块的描述,其保存了对自身的引用,CalibrationManager调用init,deinit以及get_algo_list和矫正库交互,get_cal_algo_list返回库包括的算法,

[plain] view plain copy
  1. struct sensor_algo_methods_t {  
  2.   int (*convert)(sensors_event_t *raw, sensors_event_t *result,  
  3.   struct sensor_algo_args *args);  
  4.   /* Note that the config callback is called from a different  
  5.   thread as convert */  
  6.   int (*config)(int cmd, struct sensor_algo_args *args);  
  7. };  

校正库

校正库可以放在安卓代码库的任何地方,校正库应当被编译成一个共享库,该库位于system/vendor/lib,Sensor HAL使用兼容表选择校正算法,所以兼容表必须被正确设置,

[plain] view plain copy
  1. hardware/qcom/sensors/algo/common/common_wrapper.c  
校正库由calmodule.cfg配置,代码位于/system/vendor/lib。

NativeSensorManager

NativeSensorManager的源代码位于hardware/qcom/sensors/;

图:call和poll流程

NativeSensorManager初始化

NativeSensorManager也许会在open_sensors之前被调用。

初始化过程如下:

1.扫描/dev/input目录,并获得传感器的路径名和设备名

2.通过/sys/class/sensors获得sensor list。

3.将sensor list和设备节点路径相关联

4.初始化硬件驱动(sensorBase 子类)

5.初始化虚拟sensor

命令和数据流管理

NativeSensorManager接收所有的命令和数据。

虚拟设备管理

NativeSensorManager管理,支持的设备是Orientation, Linear Acceleration, Gravity, Rotation Vector, Pseudo Gyroscope, and Uncalibrated Magnetic Field。

原创粉丝点击