【Android驱动08】Sensor传感器框架以及驱动移植和调试方法(Kernel层部分)

news2024/9/20 8:15:46

接续上一节,本文主要介绍驱动部分的客制化

1, hardware层
通过系统调用open,read,write对sys/class/sensor/m_acc_misc读写操作
路径:vendor/mediatek/proprietary/hardware/sensor/sensors-1.0/Acceleration.cpp
直接操作/sys/class/sensor/m_acc_misc节点,发命令。

2,kernel 层Sensor Driver 的客制化

2.1 驱动参数配置
Accelerometer 参数配置:
在这里插入图片描述
注意传感器的方向
在这里插入图片描述

2.2 创建传感器节点属性(所以传感器都需要通过次方法创建sys节点)
路径:drivers/misc/mediatek/sensors-1.0/hwmon/sensor_attributes/sensor_attr.c

static int __init sensor_attr_init(void)
sensor_attr_class = class_create(THIS_MODULE, “sensor”); //sys/class/sensor
sensor_attr_major = register_chrdev(0, “sensor”, &sensor_attr_fops);//注册sensor主设备号

int sensor_attr_register(struct sensor_attr_t *misc)
dev = MKDEV(sensor_attr_major, misc->minor);//对于每个sensor生成主次设备号
misc->this_device = device_create(sensor_attr_class, misc->parent, dev,misc,%s”, misc->name); //创建节点/dev/m_acc_misc
err = sensor_event_register(misc->minor);//向hwmon注册设备
obj->client[handle].head = 0;
obj->client[handle].tail = 0;
obj->client[handle].bufsize = CONTINUE_SENSOR_BUF_SIZE;

缓存各种传感器上报的数据存入buffer(所有传感器的数据都会通过一个buffer数组存储起来)
路径:drivers/misc/mediatek/sensors-1.0/hwmon/sensor_event/sensor_event.c

int sensor_input_event(unsigned char handle, const struct sensor_event *event)
client->buffer[client->head++] = *event; //将event存储用数组实现的队列中
client->head &= client->bufsize - 1;//0 1 2 3 … 2047 0 1 2 3… 2047 0 1 2 3…

unsigned int sensor_event_register(unsigned char handle)
obj->client[handle].head = 0;
obj->client[handle].tail = 0;
obj->client[handle].bufsize = BIO_SENSOR_BUF_SIZE;
obj->client[handle].buffull = false;

管理所有加速度传感器,并且注册的大量sys节点属性提供给上层访问,将所有加速度传感器接口通过节点属性给上层调用
路径:kernel-4.14/drivers/misc/mediatek/sensors-1.0/accelerometer/accel.c

static int acc_probe(void)
acc_context_obj = acc_context_alloc_object();
struct acc_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
INIT_WORK(&obj->report, acc_work_func);//初始化report工作队列绑定acc_work_func函数
cxt = acc_context_obj;
cxt->acc_data.get_data(&x, &y, &z, &status);//从mc3433驱动中通过get_data获取xyz数据
acc_data_report(&cxt->drv_data);//数据上报
event.word[0] = data->x;
event.word[1] = data->y;
event.word[2] = data->z;
sensor_input_event() //hwmon/sensor_event/sensor_event.c
initTimer(&obj->hrTimer, acc_poll);//初始化定时器,绑定acc_poll函数
hrtimer_init(timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
timer->function = callback;
acc_real_driver_init();//调用所有加速度传感器驱动的init函数
gsensor_init_list[i]->init(); //调用具体驱动的init函数,比如mc3433

DEVICE_ATTR(accenablenodata, 0644, acc_show_enable_nodata,acc_store_enable_nodata); //上电
DEVICE_ATTR(accactive, 0644, acc_show_active, acc_store_active); //使能
DEVICE_ATTR(accbatch, 0644, acc_show_batch, acc_store_batch);
DEVICE_ATTR(accflush, 0644, acc_show_flush, acc_store_flush); //FLUSH_ACTION
DEVICE_ATTR(acccali, 0644, acc_show_cali, acc_store_cali);
DEVICE_ATTR(accdevnum, 0644, acc_show_sensordevnum, NULL);

提供给具体加速度传感器使用的通用接口

int acc_register_control_path(struct acc_control_path *ctl) //用于注册控制相关操作函数
acc_misc_init(struct acc_context *cxt)
cxt->mdev.fops = &accel_fops;//open,read(sensor_event_read),poll
err = sensor_attr_register(&cxt->mdev);//生成m_acc_misc节点
sysfs_create_group(&acc_context_obj->mdev.this_device->kobj,&acc_attribute_group);
kobject_uevent(&acc_context_obj->mdev.this_device->kobj, KOBJ_ADD);

int acc_register_data_path(struct acc_data_path *data) //用于注册获取数据相关操作函数
cxt = acc_context_obj;
cxt->acc_data.get_data = data->get_data;
cxt->acc_data.get_raw_data = data->get_raw_data;

int acc_driver_add(struct acc_init_info *obj) //将驱动注册到gsensor_init_list[i]中
obj->platform_diver_addr = &gsensor_driver;
gsensor_init_list[i] = obj;

加速度传感器芯片mc3433驱动,i2c驱动
路径:drivers/misc/mediatek/sensors-1.0/accelerometer/mc3433/mc3433.c

static int __init mc3xxx_init(void)
acc_driver_add(&mc3xxx_init_info);
static struct acc_init_info mc3xxx_init_info = {
.name = MC3XXX_DEV_NAME,
.init = mc3xxx_local_init,
.uninit = mc3xxx_remove,
};
static int mc3xxx_local_init(void)
i2c_add_driver(&mc3xxx_i2c_driver)
static struct i2c_driver mc3xxx_i2c_driver = {
.driver = {
.name = MC3XXX_DEV_NAME,
.pm = &mc3xxx_pm_ops,
.of_match_table = accel_of_match,
},
.probe = mc3xxx_i2c_probe,
.remove = mc3xxx_i2c_remove,
.id_table = mc3xxx_i2c_id,
};

static int mc3xxx_i2c_probe
get_accel_dts_func(client->dev.of_node, hw); //从设备树解析i2c_num,i2c_addr,direction,power_vol等信息初始化hw
hwmsen_get_convert(obj->hw->direction, &obj->cvt);
MC3XXX_Init(new_client, 1);//i2c 硬件初始化
accel_factory_device_register(&mc3xxx_factory_device); //工厂模式
mc3xxx_create_attr(&(mc3xxx_init_info.platform_diver_addr->driver)); //sys创建mc3xxx节点属性
for (idx = 0; idx < num; idx++)
err = driver_create_file(driver, mc3xxx_attr_list[idx]);
ctl.open_report_data = mc3xxx_open_report_data; //一些函数赋值
ctl.enable_nodata = mc3xxx_enable_nodata;
ctl.batch = mc3xxx_batch;
ctl.flush = mc3xxx_flush;
ctl.set_delay = mc3xxx_set_delay;
acc_register_control_path(&ctl);
acc_register_data_path(&data);

3,驱动移植实例
3.1.添加kernel-3.18\drivers\misc\mediatek\magnetometer\st480文件夹(包含st480.c、st480.h、Kconfig、Makefile四个

        st480.c  
        st480.h  
        Kconfig     建宏--MTK_ST480  
        Makefile      

3.2.kernel-3.18\drivers\misc\mediatek\magnetometer\Kconfig 添加:

source "drivers/misc/mediatek/magnetometer/st480/Kconfig

3.3.kernel-3.18\drivers\misc\mediatek\magnetometer\Makefile 添加:

obj-$(CONFIG_MTK_ST480)   +=  st480/
  1. 4.kernel-3.18\arch\arm\boot\dts\len6797_6m_n.dts 添加:
    注:这一段没有的话(或名字不对应),会导致开机重启
cust_mag@0 {  
                compatible              = "mediatek,st480";  
                i2c_num                 = <2>;                    // i2c控制器2(即i2c总线2),sensor都接在控制器2上--即i2c总线2  
                i2c_addr                = <0x0C 0 0 0>;           // dws也写了一个i2c地址,到底用哪个看驱动,通常写在dws  
                direction               = <1>;                    // 方向 –> 唯一用到的  
                power_id                = <0xffff>;  
                power_vol               = <0>;  
                is_batch_supported  = <0>;  
            };

3.5.kernel-3.18\arch\arm\configs\len6797_6m_n_debug_defconfig、len6797_6m_n_defconfig 修改

        CONFIG_CUSTOM_KERNEL_MAGNETOMETER=y  
        CONFIG_MTK_ST480=y  

4,调试方法

	getevent -i                         查看所有的input设备  
    getevent -t /dev/input/event4       获取gsensor往上层上报的包(封装过,加入time等信息,16进制方式打印) 
    1. ps  
        靠近:  
        [    2208.288534] 0002 0002 00000001  
        [    2208.288534] 0002 0001 00000003  
        [    2208.288534] 0000 0000 00000000  
        远离: 
        [    2212.838044] 0002 0002 00000002  
        [    2212.838044] 0002 0001 00000003  
        [    2212.838044] 0000 0000 00000000  
2. cat /proc/kmsg | grep "dgsensor"  
        <4>[  564.973691]<0> (0)[2935:kworker/0:3]dgsensor epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0xa  
        <4>[  564.973725]<0> (0)[2935:kworker/0:3]dgsensor epl_sensor_read_ps_status epl_sensor.ps.compare_low =  0x8  
        <4>[  565.168562]<0> (0)[2935:kworker/0:3]dgsensor epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0xa  
        <4>[  565.168588]<0> (0)[2935:kworker/0:3]dgsensor epl_sensor_read_ps_status epl_sensor.ps.compare_low =  0x8  
        <4>[  565.368485]<0> (0)[2935:kworker/0:3]dgsensor epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0xa  

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

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

相关文章

pytorch基础模块:Tensorboard、Dataset、Transforms、Dataloader

Tensorboard、Dataset、Transforms、Dataloader 该文档主要参考【土堆】的视频教程&#xff1a;pytorch入门教程–土堆 一、Tensorboard 安装tensorboard&#xff1a;pip install tensorboard 使用步骤&#xff1a; 引入相关库&#xff1a;from torch.utils.tensorboard i…

DDL、DML、DQL、DCL具体实例与关系

一、DDL、DCL、DML、DQL 通过二维表的形式&#xff0c;更加清晰直观的学习、对比其关系。 DDL DCL DML DQL 英文释义 Data Defination Language 数据库定义语言 Data Control Language 数据库控制语言 Data Manipulation Language 数据操作语言 Data Query Language 数…

PyMuPDF-Guide

本文翻译整理自&#xff1a; https://pymupdf.readthedocs.io/en/latest/how-to-open-a-file.html 文章目录 一、打开文件1、支持的文件类型2、如何打开文件打开一个错误的文件扩展名 3、打开远程文件从云服务打开文件 4、以文本形式打开文件例子打开一个C#文件打开一个XML文件…

按摩行业的革新者:从挑战到辉煌的转型之路

在时代浪潮的推动下&#xff0c;一个勇于创新的团队于2018年毅然踏入按摩服务市场&#xff0c;创立了一家颠覆传统的按摩店。面对行业内的激烈竞争与瞬息万变的市场环境&#xff0c;他们凭借独树一帜的经营模式和不懈的努力&#xff0c;不仅稳固了市场地位&#xff0c;更在去年…

使用Greenhills生成Lib并使用Lib的两种方法

文章目录 前言GHS工程生成libmake方式生成liblib的使用总结 前言 在软件交付过程&#xff0c;如果不交付源代码&#xff0c;可以将源码编译之后生成lib文件提供给客户。本文介绍GHS中生成lib的两种方法&#xff0c;一种基于GHS工程&#xff0c;一种基于make文件。生成完lib后的…

uniapp自定义网格布局用于选择金额、输入框焦点事件以及点击逻辑实战

样式 <view class="withdraw-section"><text class="section-title">提现金额</text><view class="amount-options"><view v-for="(item, index) in list" :key="index" class="amount-opt…

使用Leaflet进行船舶航行警告区域绘制实战

目录 前言 一、坐标格式转换 1、数据初认识 2、将区域分割成多个点 3、数据转换 4、数据转换调用 二、WebGIS展示空间位置信息 1、定义底图 2、Polygon的可视化 3、实际效果 三、总结 前言 通常而言&#xff0c;海事部门如海事局&#xff0c;通常会在所述的管辖区域内…

Java从入门到精通(十五) ~ IO流

晚上好&#xff0c;愿这深深的夜色给你带来安宁&#xff0c;让温馨的夜晚抚平你一天的疲惫&#xff0c;美好的梦想在这个寂静的夜晚悄悄成长。 目录 前言 什么是IO流&#xff1f; IO流的作用&#xff1a; 一、基础流 1. 字节流 1.1 字节输入流 FileInputStream 1.2 字节…

找到第一个满足条件的格值

表格第1列是科目&#xff0c;之后几列是每次的考试成绩&#xff0c;顺序排列。 ABCDE1Art03.676.27.82History3.786.217.29.83Maths5.66.36.68.9 要求根据指定的科目和成绩&#xff0c;找到该科目中大于等于该成绩的第1个格值&#xff0c;比如参数是Maths、6.5时&#xff0c;…

element-ui简单入门1.0.0

第一篇&#xff1a;table标签速用 总结&#xff1a;建楼前&#xff0c;先打地基<el-table></el-table>&#xff0c;打完地基看高度&#xff0c;一层楼4米&#xff0c;80米20个<el-table-column></el-table-column>&#xff0c;每次楼的名字是label 第…

[翻译] Asset Administration Shells

关于资产管理外壳 (AAS) 资产管理外壳 (AAS) 是工业4.0中的关键概念&#xff0c;为产品、资源&#xff08;如设备&#xff09;和过程提供信息隐藏和更高层次的抽象。AAS 是技术和设备无关的机器可读描述&#xff0c;提供访问资产属性和功能的统一接口。与现有解决方案不同&…

C# 下的限定符运算详解(全部,任意,包含)与示例

文章目录 1.限定符概述2. 全部限定符运算&#xff08;All&#xff09;3. 任意限定符运算&#xff08;Any&#xff09;4. 包含限定符运算&#xff08;Contains&#xff09;总结 当我们在C#编程中需要进行条件判断或集合操作时&#xff0c;限定符&#xff08;qualifiers&#xff…

Vue项目启动ESLint报错no-unused-vars解决办法

目录 原因分析解决方法 Vue项目启动时报错如下 ✘ http://eslint.org/docs/rules/no-unused-vars index is assigned a value but never usedsrc\views\friend\list.vue:206:17const index this.tableList.indexOf(v)^原因分析 ESLint是一个在JavaScript代码中识别和报告问…

【传知代码】辅助任务改进社交帖子多模态分类(论文复现)

在当今数字化社交时代&#xff0c;社交媒体平台如同人们生活的一部分&#xff0c;每天数以亿计的帖子在网络上涌现。这些帖子不仅仅是信息的载体&#xff0c;更是人们思想、情感和行为的折射。然而&#xff0c;要准确理解和分析这些多样化的社交帖子&#xff0c;仅依靠文本内容…

请问如何做好软件测试工作呢?

一、明确测试目标和范围 理解测试目的&#xff1a;在开始测试之前&#xff0c;首先要明确测试的目标和范围&#xff0c;确保测试计划 与需求相匹配。这有助于测试人员聚焦在关键功能上&#xff0c;避免浪费时间和资源。制定详细的测试计划&#xff1a;根据项目需求&#xff0…

【Python】爬取网易新闻今日热点列表数据并导出

1. 需求 从网易新闻的科技模块爬取今日热点的列表数据&#xff0c;其中包括标题、图片、标签、发表时间、路径、详细文本内容&#xff0c;最后导出这些列表数据到Excel中。 网易科技新闻网址&#xff1a;https://tech.163.com 2. 解决步骤 2.1 前期准备 爬虫脚本中需要引用…

Visio新手安装及超全快捷指令合集

Microsoft Visio是一款专业的流程图和图表绘制软件&#xff0c;是微软旗下的一款图表和矢量图形应用程序&#xff0c;属于Microsoft 365系列的一部分。但Visio需要单独安装&#xff0c;安装完成之后可与Word联用。 一、Visio软件介绍 Visio 是一款用途多样的绘图工具&#xff…

全球氢钎焊市场规划预测:未来六年CAGR为3.4%

随着全球制造业的持续发展和消费者对高质量产品的需求增加&#xff0c;氢钎焊作为一种高效的焊接技术&#xff0c;正逐渐受到市场的广泛关注。本文旨在通过深度分析氢钎焊行业的各个维度&#xff0c;揭示行业发展趋势和潜在机会。 【市场趋势的演变】 1. 市场规模与增长&#…

【uniapp】集成第三方插件示例

文章目录 uniapp芯套Android壳app目录下/libs目录导入全部aar工程目录下导入rewriter文件夹 uniapp芯套Android壳 https://blog.csdn.net/xzzteach/article/details/140800350 app目录下/libs目录导入全部aar工程目录下导入rewriter文件夹 本地引入包内容 在 project 级别的…

解决com.alibaba.csp.sentinel.slots.block.flow.FlowException: null

springboot项目配置sentinel&#xff0c;能限流成功但是不能限流方法 原因 名字没对应上