招商网站建设方案,广州网站建设公司哪家服务好,网站建设需要材料,山东网站排行不过不同的芯片平台#xff0c;kernel层中的sensor框架是不同的#xff0c;这里针对的是mt8167s平台。不过这里提醒一下#xff0c;MTK平台应该从kernel 3.x版本后就不支持温湿度传感器的框架了#xff0c;不过幸好他们还保留了框架的雏形在#xff0c;我们需要自行解决一…不过不同的芯片平台kernel层中的sensor框架是不同的这里针对的是mt8167s平台。不过这里提醒一下MTK平台应该从kernel 3.x版本后就不支持温湿度传感器的框架了不过幸好他们还保留了框架的雏形在我们需要自行解决一下编译问题。
正文
我们先看一下代码的具体目录
drivers/misc/mediatek/sensors-1.0$ ls
accelerometer/ alsps/ dummy.c humidity/ magnetometer/ sensorHub/ accelgyro/
barometer/ geofence/ hwmon/ Makefile situation/ activity_sensor/
biometric/ gyroscope/ Kconfig sensorfusion/ step_counter
目录结构很清晰不同的sensor都有单独的目录这篇文章我们还是以湿度传感器为例所以这里单独研究一下humidity。还是先看一下代码目录结构
drivers/misc/mediatek/sensors-1.0/humidity$ ls
aht10/ hmdyhub/ humidity.c humidity_factory.c inc/ Kconfig Makefile
humidity.c文件为不同型号的湿度传感器驱动提供一些公共的接口也可以说是MTK为我们抽象一个有关humidity sensor的基本架构。在移植一个新型号的sensor时只要将其通过公共接口注册进系统就可以了。
1、初始化
static struct hmdy_init_info aht10_init_info {.name aht10,.init aht10_local_init,.uninit aht10_local_uninit,};static int __init aht10_init(void)
{hmdy_driver_add(aht10_init_info);AHT_FUN(); return 0;
}
在aht10驱动初始化的时候通过hmdy_driver_add接口把我们的aht10驱动注册进系统
int hmdy_driver_add(struct hmdy_init_info *obj)
{int err 0;int i 0;HMDY_FUN();if (!obj) {HMDY_PR_ERR(HMDY driver add fail, hmdy_init_info is NULL\n);return -1;}for (i 0; i MAX_CHOOSE_HMDY_NUM; i) {if (i 0) {HMDY_LOG(register humidity driver for the first time\n);if (platform_driver_register(humidity_driver))HMDY_PR_ERR(failed to register gensor driver already exist\n);}if (humidity_init_list[i] NULL) {obj-platform_diver_addr humidity_driver;humidity_init_list[i] obj;break;}}if (i MAX_CHOOSE_HMDY_NUM) {HMDY_PR_ERR(HMDY driver add err\n);err -1;}return err;}
其实就是将我们自定义的struct hmdy_init_info aht10_init_info结构体保存到全局变量数组humidity_init_list中。然后在humidity驱动起来的时候会通过hmdy_real_driver_init()接口调用已经注册的sensor的init函数
static int hmdy_real_driver_init(void)
{int i 0;int err 0;for (i 0; i MAX_CHOOSE_HMDY_NUM; i) {if (humidity_init_list[i] ! 0) {err humidity_init_list[i]-init();if (err 0) {break;}}}if (i MAX_CHOOSE_HMDY_NUM) {err -1;}return err;}
这里的init()函数对应到我们sensor的aht10_local_init函数
static int aht10_local_init(void)
{if (i2c_add_driver(aht10_i2c_driver)) {return -1;}if (-1 aht10_init_flag) {return -1;}return 0;
}
到这里就是我们熟悉的I2C设备注册函数了i2c_add_driver()。假设我们的sensor设备也正常加入到系统调用我们自定义的probe函数这里面就需要我们进行三步重要的操作
1设置设备资源 sensor框架为我们提供了接口get_hmdy_dts_func()去解析我们的设备资源包含I2C的地址是否支持设置采样率等等。
2struct hmdy_control_path 我们要设置自己的struct hmdy_control_path结构体初始值
struct hmdy_control_path hmdy_control_path {0};hmdy_control_path.is_use_common_factory false;
hmdy_control_path.open_report_data aht10_open_report_data; /* 作用未知一般直接返回就好 */
hmdy_control_path.enable_nodata aht10_enable_nodata; /* 上层在打开sensor设备的时候会调用到这个函数 */
hmdy_control_path.set_delay aht10_set_delay; /* 字面上是用来设置延时不过如果不需要可以直接返回 */
hmdy_control_path.is_report_input_direct false;
hmdy_control_path.is_support_batch dev_data-hw-is_batch_supported_hmdy; /* 是否支持设置采样率 */ret hmdy_register_control_path(hmdy_control_path); /* 将前面设置好的struct hmdy_control_path结构体通过公共接口注册进系统 */
if (ret) {AHT_INFO(register hmdy control path err\n);goto exit_delete_attr;
}
3struct hmdy_data_path
struct hmdy_data_path hmdy_data_path {0};
hmdy_data_path.get_data aht10_get_humidity_data;
hmdy_data_path.vender_div 10;
ret hmdy_register_data_path(hmdy_data_path);
if (ret) {AHT_INFO(hmdy_register_data_path failed, ret %d\n, ret);goto exit_delete_attr;
}
这个结构体才是重头戏其中get_data接口就是用来获取sensor想要上报的数据
int (*get_data)(int *value, int *status);
其中value就是上报的数据值同时通过status上报sensor的状态。另外上报的数据有时候需要调整一个百分比那么就会用到vender_div值了在调试过程中自行调整即可。设置完毕就可以通过接口hmdy_register_data_path()将我们自定义的结构体注册进系统了。
结语
kernel层框架的要点大概就这么多不同的sensor基本的驱动流程都类似读完我这系列文章后应该就能一通百通了。