SensorKernel层框架分析

接上文

安卓9.0Sensor框架

前言

前面我们已经讲解了sensor框架中的framework到vendor层,这篇文章我们将会讲解kernel层的内容。不过不同的芯片平台,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的地址,是否支持设置采样率等等。

(2)struct 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;
}

(3)struct 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,基本的驱动流程都类似,读完我这系列文章后应该就能一通百通了。

推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

嵌入式Linux

微信扫描二维码,关注我的公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467528.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【习题 5-8 UVA - 230】Borrowers

【链接】 我是链接,点我呀:) 【题意】 在这里输入题意 【题解】 用mapset写个模拟就好。 3个区域 书架、桌子、别人的手上。 其中前两个区域的书都能借出去。 【代码】 #include <bits/stdc.h> using namespace std;set <pair<string, string> > mset1,mse…

java requestparams_java – 如何验证@RequestParams不为空?

我有一个计算器服务,从用户获取操作类型num1和num2.我需要验证用户是否实际输入了这些值,而不是将其留空.RequestMapping(value "/calculate")ResponseBodypublic CalculationResult calculate(RequestParam(name "op") String operation, RequestParam(…

Linux内核LED子系统、请务必看

前言LED子系统你要是说很难嘛&#xff0c;但是它就是控制一些简单的GPIO口&#xff0c;但是你要是说它很简单嘛&#xff0c;但是我也不见得一个初学者很快就能掌握&#xff0c;你如果是刚入门这部分的话&#xff0c;我觉得你还是要去仔细研究下这些驱动。前两天在网上看到一句话…

UVALive 4394 String painter

题目大意&#xff1a;有两个字符串A,B&#xff0c;一次刷可以把A串一段刷成同一个字母&#xff0c;问至少要刷几次才能把A串变成B串。串长≤100。 本来以为是个很简单的区间DP&#xff0c;后来发现直接区间DP是不行的&#xff0c;这玩意有后效性&#xff1a;刷完一整块之后这一…

centos 6.5 安装 lamp 后mysql不能启动_CentOS 6.5 系统 LAMP(Apache+MySQL+PHP)安装步骤

先来解释一下&#xff0c;什么是 LAMP。正如标题所言&#xff0c;LAMP 实际上就是 Linux、Apache、MySQL、PHP 四个名称的缩写&#xff0c;当然最后一个 “P” 还有其他说法是 Perl 或者 Python。不用多说了&#xff0c;本文讲解的就是 Linux、Apache、MySQL、PHP 这四个东西&a…

Redis连接实例

ECS Windows服务器 如果您本地需要通过公网访问 云数据库 Redis&#xff0c;可以在 ECS Windows 云服务器中通过 netsh 进行端口映射实现。 1. 登录 ECS Windows 服务器&#xff0c;在 CMD 执行以下命令。&#xff08;公网地址与 连接地址 请替换 为您的实际地址。&#xff09;…

什么是高内聚,低耦合?

高内聚&#xff0c;低耦合是一个老生常谈的话题&#xff0c;所以拿出来说一下我们在看Linux的一些资料&#xff0c;或者是在面试&#xff0c;又或者跟一个比较牛的大佬讨论技术的时候&#xff0c;可能会听到这个概念。所以&#xff0c;什么是高内聚&#xff0c;低耦合呢&#x…

java 8 兼容_甲骨文限制 Java 9 到 Java 8 的向后兼容性

在开发者们正兴奋着准备把 Java 8 工具包转向 Java 9 的时候&#xff0c;甲骨文的首席执行官提出了要限制两个版本的兼容性。在周一下午 OpenJDK 的邮件列表中的一封邮件中&#xff0c;甲骨文的 Java 平台的首席架构师 Mark Reinhold 指出会对 JDK8 增加更多变化(大概在 2014 年…

Web API 2 入门——创建ASP.NET Web API的帮助页面(谷歌翻译)

在这篇文章中 创建API帮助页面将帮助页面添加到现有项目添加API文档在敞篷下下一步作者&#xff1a;Mike Wasson 创建Web API时&#xff0c;创建帮助页面通常很有用&#xff0c;以便其他开发人员知道如何调用API。您可以手动创建所有文档&#xff0c;但最好尽可能自动生成。 为…

Linux fork的写时复制

这个问题是一个同学在知识星球里面提问的看下面的代码#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/wait.h> #includ…

从单片机工程师的角度看嵌入式Linux

前言 这篇文章简单我们来一起梳理嵌入式Linux的一些知识&#xff0c;方便于一些想跟我一样想要由单片机进阶到嵌入式Linux的朋友做一些参考学习。现在随着嵌入式Linux的教程不断增多&#xff0c;相信应该有不少学单片机的朋友开始折腾这个了吧~嵌入式Linux学哪些东西 1、认识Li…

Java低级编程软件_JAVA语言说低级语言吗

高级语言&#xff1a;C、C、Java、Python、Pascal、Lisp、Prolog、FoxPro、易语言等都是高级语言&#xff0c;相对于低级语言来说&#xff0c;高级语言采用易于识别和记忆的字符来作为关键字&#xff0c;也更接近人类的思维方式&#xff0c;编写容易读写性好&#xff0c;开发效…

智能硬件开发神器免费送!距离产品智能化,只差一个“三明治”的距离

重磅资料包免费领取 针对人群&#xff1a;如果您对“人工智能物联网”感兴趣&#xff0c;尤其是您的企业想做产品/行业智能化&#xff0c;一定不能错过这份“物联网人必备的终极大礼包”哦&#xff5e;这几类行业玩家必看&#xff01;&#xff01;&#xff01;制造商、方案商、…

Java类的继承关键字_Java的第八天(类的继承、super关键字的使用、方法的重写)...

39.类的继承java描述类的时候&#xff0c;咱们若是发现有几个类有重复的属性和方法&#xff0c;咱们就能够采用继承的方法来设计ide使用extends关键字来继承this语法&#xff1a;设计class 子类 extends 父类{对象子类属性继承子类方法内存}资源特色&#xff1a;(1)子类会把父类…

你们班上的同学现在都怎么样了?

今天跟朋友聊天&#xff0c;聊到这个话题&#xff0c;觉的有点意思&#xff0c;所以想拿出来讨论一下。小学小学的时候&#xff0c;我们读书最厉害的应该是我们班上几个老师的孩子&#xff0c;他们像是得到了老师的武功秘籍&#xff0c;读书对他们来说就是家常便饭&#xff0c;…

java socket oc_Java Socket编程(三) 服务器Sockets

文章来源&#xff1a;aspcn 作者&#xff1a;孙雯服务器Sockets列表9.2是一个服务器应用程序的一部分.列表9.2 一个简单的服务器程序/*** 一个监听端口并提供HTML文档的程序.*/class SimpleWebServer {public static void main(String args[]){ServerSocket serverSocket null…

浅析bootstrap原理及优缺点

网格系统的实现原理&#xff0c;是通过定义容器大小&#xff0c;平分12份(也有平分成24份或32份&#xff0c;但12份是最常见的)&#xff0c;再调整内外边距&#xff0c;最后结合媒体查询&#xff0c;就制作出了强大的响应式网格系统网格系统的实现原理&#xff0c;是通过定义容…

如何把一个float存到一个长度为4的char数组中?

我以前以为它是可以这样的看代码#include "stdio.h"int main(void) {float fa 123.56;char farray[4] {0};farray[0] ((int)fa>> 24)&0xFF;farray[1] ((int)fa>> 16)&0xFF;farray[2] ((int)fa>> 8 )&0xFF;farray[3] ((int)fa>…

OSPF次末节区域配置 201

【实验拓扑】 【实验基本配置】1、按照上图配置相应接口以及OSPF【实验要求】 1、配置Area 1 为NSSA区域2、在R6上配置1条静态路由160.1.60.0/24指向 Null0&#xff0c;并充分发到OSPF中3、将路由器1的ID修改为150.1.100.100【实验分析】次末节区域&#xff08;NSSA&#xff09…

sort和qsort函数

http://blog.csdn.net/morninghapppy/article/details/6703058 http://blog.csdn.net/rns521/article/details/7473558 http://blog.csdn.net/u012209626/article/details/48792049转载于:https://www.cnblogs.com/Emilylice/p/7689099.html