rockchip sensors da215s适配

news2024/12/28 10:20:09
RK3568  da215s适配 ,增加一个新的 sensor 驱动需做一些适配工作。
SOC:RK3568
KERNEL:Android 12
二、 Android sensors 架构
三、 Sensors hal kernel driver 的通信框图
四、 Rockchip sensors hal 介绍
代码路径: hardware/rockchip/sensor/st ,支持最新的 SENSORS_DEVICE_API
_VERSION_1_3 android sensors hal API 接口。其实现的接口包括:
get_sensors_list - 返回所有传感器的列表
activate - 启动或停止传感器
batch - 设置传感器的参数,如采样率和最大报告延迟
setDelay - 仅用于 1.0 版本的 HAL ,设置指定传感器的采样率
flush - 刷写指定传感器的 FIFO ,并在完成后报告刷写完成事件
poll - 返回可用的传感器事件
其中 flush 接口并没有真正实现,因为要具体到硬件的 fifo 支持,由于我们支持的
sensor 型 号 多 , 无 法 做 到 统 一 接 口 实 现 , 所 以 这 里 只 是 绕 过 , 直 接 返 回
META_DATA_FLUSH_COMPLETE 类型数据
五、 Rockchip sensors kernel driver 介绍
代码路径: kernel/drivers/input/sensors ,其中 sensor-dev.c 是核心代码,整合
了不同类型的 sensor ,包括 accel, gyro, lsensor, psensor, compass
六、新增一个 sensor 驱动流程
这里以增加一个最常用的 gsensor 为例,其他类型的 sensor 类似。
Android hal 不需要任何修改, hal 的是按 +-4G Gsensor 量程, adc 14bit 来配
置的,也就是 4 G 对应的数值是 16384*4 ;所以 driver 层增加 gsensor 驱动,上报数值需
要根据量程和 adc 的精度来适配
具体步骤如下,以 da215s acc 为例:
sensor-dev.h  中添加 sensor_id,其中gsensor_da215s_id 的 ”gs_da215s ”字段与 dts 中的 compatible
字段对应。
kernel-5.10\include\linux\sensor-dev.h
6.2 增加 gsensor chip 驱动
driver/input/sensors/accel/目录下增加相应驱动
实现 gsensor_mpu6500_ops 实例:
struct sensor_operate gsensor_da215s_ops= {
.name = "gs_da215s",            //与 gsensor_da215s_id 中定义的名称一致
.type = SENSOR_TYPE_ACCEL,      //sensor 类型是 gsensor
.id_i2c = ACCEL_ID_DA215S,      // 定 义 在 include/linux/sensor-dev.h 中
.read_reg = ACC_X_LSB,          //读取 gsensor 数据的起始 寄存器地址
.read_len = 6,                  //需要读取的 gsensor 数据的字节数
.id_reg = DA215S_CHIP_ID,       //芯片唯一 ID 寄存器
.id_data = DA215S_CHIPID_DATA,  //芯片 ID 值
.precision = DA215S_PRECISION,  //采样 gsensor 数据的adc 位数
.ctrl_reg = DA215S_MODE_BW,     //用于使能 gsensor 的寄 存器地址
.int_status_reg = INT_MAP1,     //中断状态寄存器地址
.range =  {-DA215S_DATA_RANGE, DA215S_DATA_RANGE}, //量程,这里表示上报的量 程为+-1G
.trig =  IRQF_TRIGGER_LOW | IRQF_ONESHOT,  // 中断类型
.active = sensor_active,        //用于开关 gsensor
.init = sensor_init,            //用于初始化 gsensor
.report = sensor_report_value,  //用于上报gsensor数据
};

static const struct i2c_device_id gsensor_da215s_id[] = {
    {"gs_da215s", ACCEL_ID_DA215S},
    {}
};
  //注册 sensor 驱动到 sensor-dev.c  devid 为gsensor_da215s_id地址
static const struct i2c_device_id gsensor_da215s_id[] = {
	{"gs_da215s", ACCEL_ID_DA215S},
	{}
};

static int gsensor_da215s_probe(struct i2c_client *client, const struct i2c_device_id *devid) 
{
    //注册 sensor 驱动到 sensor-dev.c  devid 为gsensor_da215s_id地址

	return sensor_register_device(client, NULL, devid, &gsensor_da215s_ops);
}

static int gsensor_da215s_remove(struct i2c_client *client)
{
	return sensor_unregister_device(client, NULL, &gsensor_da215s_ops);
}

//i2c_driver
static struct i2c_driver gsensor_da215s_driver = {
	.probe = gsensor_da215s_probe,
	.remove = gsensor_da215s_remove,
	.shutdown = sensor_shutdown,
	.id_table = gsensor_da215s_id,
	.driver = {
		.name = "gsensor_da215s",
	#ifdef CONFIG_PM
		.pm = &sensor_pm_ops,
	#endif
	},
};

i2C内核驱动加载:
module_i2c_driver(gsensor_da215s_driver);

6.3 修改 gsensor range 和上报数据转化
不同厂家的 gsensor 在量程和精度上都会有差异,为了兼容不同厂家的 gsensor 芯片,
同时做到不修改 android hal 层代码,只修改驱动,来达到简化客户开发的目的,我们必
须把不同量程,不同精度的 gsensor 转换成统一标准的数据上报给 hal 层代码。
上节提到, HAL 层是以量程为 +-4G adc 14bit 的标准来上报的 gsensor 数据,以
此标准不同的 gsensor 需要做适配。举例如下:
1 )da215s+- 4G 14bit adc
da215s的 adc 位数是 14bit 的,初始化的时候设置的量程是 +-4G ,那么寄存器读
出来的数值范围为:+-16384*4 ,并且与上层 hal 层匹配,所以只要把寄存器读出来的值直
接上报即可;

#define DA215S_PRECISION    14
#define DA215S_DATA_RANGE    (16384*4)

static struct sensor_operate gsensor_da215s_ops = {
    .name        = "gs_da215s",
    .type        = SENSOR_TYPE_ACCEL,
    .id_i2c        = ACCEL_ID_DA215S,
    .read_reg    = ACC_X_LSB,
    .read_len    = 6,
    .id_reg        = DA215S_CHIP_ID,
    .id_data    = DA215S_CHIPID_DATA,
    .precision    = DA215S_PRECISION,
    .ctrl_reg    = DA215S_MODE_BW,
    .int_status_reg    = INT_MAP1,
    .range          = {-DA215S_DATA_RANGE, DA215S_DATA_RANGE},
    .trig        = IRQF_TRIGGER_LOW | IRQF_ONESHOT,
    .active        = sensor_active,
    .init        = sensor_init,
    .report        = sensor_report_value,
    .suspend        = sensor_suspend,
    .resume         = sensor_resume,
};

2 )如果 gsensor 的量程和 adc 精度不是 +-2G 16bit 的话,则需要做相应的转化,
假设量程为 +-XG adc Ybit 的,其转化关系如下:
#define XXX_RANGE  16384*X
#define XXX_PRECISION Y
#define XXX_BOUNDARY
(0x1 << (XXX_PRECISION - 1))
#define XXX_GRAVITY_STEP (XXX_RANGE / XXX_BOUNDARY)
struct sensor_operate gsensor_xxx_ops = {
.name = "xxx_acc",
.type = SENSOR_TYPE_ACCEL,
.id_i2c = ACCEL_ID_XXX,
.read_reg = XXX_ACCEL_XOUT_H,
.read_len = 6,
.id_reg = XXX_WHOAMI,
.id_data = XXX_DEVICE_ID,
.precision = Y,
.ctrl_reg = XXX_PWR_MGMT_2,
.int_status_reg = XXX_INT_STATUS,
.range = {-16384*X, +16384*X},
.trig = (IRQF_TRIGGER_LOW |
IRQF_ONESHOT),
.active = sensor_active,
.init = sensor_init,
.report = sensor_report_value,
};
上报值转化:
report_data = read_data* XXX_GRAVITY_STEP; //read_data 为实际寄存器
读出来的值, report_data 为转换后可以上报给 hal 层的值
6.4 修改 gsensor layout 方向
      Android 系统对坐标轴的定义如下:
Sensor chip 的坐标系定义:
每一颗 sensor 都有自己的坐标系定义,所以需要根据 layout 方向,把 sensor 的坐
标系转换成 android 设备的坐标系,这个可以通过一个矩阵来做转换;
如下矩阵表示:
X = x*0 + y*1 + z*0 = y
Y = x*1 + y*0 + z*0 = x
Z = x*0 + y*0 + z*-1 = -z
Sensor-dev.c 定义了 layout 值,对应不同的矩阵,具体可以查看 sensor-dev.c
码查询,所以,适配方向可以通过修改 dts 里面的 layout 值来选择对应的转换矩阵,达到
方向的变化,以适配 android 的要求。
6.5 dts 中其他值的意义
	gs_da215s: gs_da215s@26 {
        status = "okay"; 
        compatible = "gs_da215s";// 与 sensor-dev.c 中的sensor_id 定义匹配
        reg = <0x26>;//i2c 地址
        irq-gpio = <&gpio1 RK_PA4 IRQ_TYPE_EDGE_RISING>;//中断脚,中断类型
        irq_enable = <0>;//是否使用中断模式,如果要过cts 
		                 // 或者 vts 建议使用轮询,sensor-dev.c 
		                 //的轮询模式已经可以满足 cts 测试要求,如果
                          //使用中断模式,需要 gsensor chip driver 做好采样率的配置;
        poll_delay_ms = <30>;//轮询间隔,最新代码这个值没有意义
        type = <SENSOR_TYPE_ACCEL>;//传感器类型,不能搞错
        layout = <4>;
	};
6.6 Android 中的 sensor 相关宏配置
BoardConfig.mk 中:
# Sensors
BOARD_SENSOR_ST := true //采用 RK 的 sensors Hal,也就是本文介绍的
BOARD_SENSOR_MPU_PAD := false //仅适用 MPU6500、mpu6050 等芯片
支持哪些类型的 sensor,如果没有,要配置成 false,否则 vts 和 cts 测试会失败:
BOARD_GRAVITY_SENSOR_SUPPORT := true
BOARD_COMPASS_SENSOR_SUPPORT := false
BOARD_GYROSCOPE_SENSOR_SUPPORT := false
BOARD_PROXIMITY_SENSOR_SUPPORT := false
BOARD_LIGHT_SENSOR_SUPPORT := true
BOARD_PRESSURE_SENSOR_SUPPORT := false
BOARD_TEMPERATURE_SENSOR_SUPPORT := false
七、 Gsensor gyro 的校准
Gsensor gyro 的校准可通过命令行方式, pcba 测试的时候也可以做校准,具体查
pcba 的配置。
命令行校准方法:保持机器水平静止放置,输入以下命令校准:
Gsensor: echo 1 > /sys/class/sensor_class/accel_calibration
GYRO : echo 1 > /sys/class/sensor_class/gyro_calibration
查看校准值:
cat /sys/class/sensor_class/accel_calibration
如果无法查看校准值,则说明校准失败,可以打印 kernel log 确定失败原因。
校准成功后,校准的值会保存到 nand emmc vendor storage 里面,不会被擦
除,开机自动生效
八、 Sensor 常见问题分析
这里以 gsensor 为例进行介绍,其他类型 sensor 可参考这里。
8.1 Gsensor 功能无法使用
8.1.1 getevent 查看 gsensor 无数据上报
排查思路:
1 )确认驱动是否注册上,可以通过 getevent 查看是否有名为 gsensor input 设备;
没有的话就要看为何没注册上,有可能是 dts 配置问题,驱动问题, i2c 同时失败,
chip id 不匹配等等可能的原因,查看 kernel log ,具体问题具体分析;如果有注
册上,往下。
2 )确认 android 层相关宏是否打开;
3 )确认 hal 层代码是否正常运行;开机打印 logcat ,搜索 sensor 字段查看相关 log
8.1.2 数据值不对
Getevent 有数据上报,屏幕不旋转或者旋转无规律;
除可通过 sensor apk 查看数值是否正确外,还可以通过命令的方式查看 android
上报的 gsensor 数据是否正确:
setprop sensor.debug.level 2
手动灭屏休眠,再唤醒后命令生效,通过 logcat –s SensorsHal 可以查看到 hal 上报
gsensor 数值;
静止水平放置时,理论正确的数值应该是有个轴的值为 +9.8 或者 -9.8 ,另外两个轴的
值为 0
如果数值不对,请确认上面章节介绍的数据上报转换是否正确。
8.2 方向不对
方向不对的话,通过修改 dts layout 值.
目前 RK sensor 驱动,采用轮询的方法,基本可以满足 android 采样率的要求,所
以如果不知道如何动态配置采样率的话,建议采用轮询方法,同时芯片初始化的时候就把采
样率配置成高采样率, 200Hz 就可以;另外, Sensor 芯片驱动中最好不要对数据做过滤,
如果有,可以去掉数据过滤直接上报再测试看看;还有一种情况是芯片本身的采样率实在上
不去,比较 low 的芯片;只能通过软件来绕,当 android 要求的采样率大于 sensor 的采
样率,意味着存在多次读取的数值一样的情况,同样数值在通过 input 上报的时候,会被
框架层丢弃,这样就达不到 android 的测试要求,此时我们可以人为修改数值,通过软件
骗过框架,如下:
/*
 *input dev will ignore report data if data value is the same with 
last_value,
 *sample rate will not enough by this way, so just avoid this case
 */
 if ((sensor->axis.x == axis.x) && (sensor->axis.y == axis.y) && 
(sensor->axis.z == axis.z)) {
 if (flag) {
 flag = 0;
 axis.x += 1;
 axis.y += 1;
 axis.z += 1;
 } else {
 flag = 1;
 axis.x -= 1;
 axis.y -= 1;
 axis.z -= 1;
 }
 }

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

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

相关文章

RapidJSON介绍

1.简介 RapidJSON 是一个 C 的 JSON 解析库&#xff0c;由腾讯开源。 支持 SAX 和 DOM 风格的 API&#xff0c;并且可以解析、生成和查询 JSON 数据。RapidJSON 快。它的性能可与strlen() 相比。可支持 SSE2/SSE4.2 加速。RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至…

上位机图像处理和嵌入式模块部署(树莓派4b镜像烧录经验总结)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 陆陆续续也烧录了好多次树莓派的镜像了&#xff0c;这里面有的时候很快&#xff0c;有的时候很慢。特别是烧录慢的时候&#xff0c;也不知道是自己…

crossover怎么打开软件 mac怎么下载steam crossover下载的软件怎么运行

CrossOver是一款Mac和Linux平台上的类虚拟机软件&#xff0c;通过CrossOver可以运行Windows的可执行文件。如果你是Mac用户且需要使用CrossOver&#xff0c;但是不知道CrossOver怎么打开软件&#xff0c;如果你想在Mac电脑上玩Windows游戏&#xff0c;但不知道怎么下载Steam&am…

大模型改变了哪些工作方式?

大模型的崛起深刻改变了我们的工作方式。如今&#xff0c;许多行业已广泛应用大型机器学习模型&#xff0c;实现了自动化数据处理、智能决策和高效分析。这一变革不仅释放了大量人力资源&#xff0c;使得人们能够专注于更具创造性的任务&#xff0c;还大幅提升了工作效率和准确…

【mobx-入门与思考】

介绍 mobx 是 nodejs生态中的框架&#xff0c; 主要用于做状态管理&#xff0c;可以监控变量状态的变化。 nodejs中除了mobx&#xff0c;还有个redux&#xff0c;也是做状态管理的&#xff0c;都是比较成熟的框架&#xff0c;二者的选择可以参考 【nodejs状态管理: Redux VS M…

录屏软件哪个好用?这4款不容错过!

在现代社会中&#xff0c;信息的传递和分享变得越来越重要。一个好的录屏软件能够帮助我们将想要分享的信息快速直观地展示给他人。 通过下文推荐的4款录屏软件&#xff0c;我们可以轻松地分享自己的知识、经验和见解&#xff0c;让更多的人受益。 方法一&#xff1a;QQ软件进…

服务器2080ti驱动的卸载与安装

服务器2080ti驱动的卸载与安装 前言1、下载驱动2、驱动卸载与安装2.1 卸载原来驱动2.2 安装新驱动 3、查看安装情况 前言 安装transformers库&#xff0c;运行bert模型时出错&#xff0c;显示torch版本太低&#xff0c;要2.0以上的&#xff0c;所以更新显卡驱动&#xff0c;重…

基于FPGA的数字电子钟VHDL代码Quartus仿真

名称&#xff1a;基于FPGA的数字电子钟VHDL代码Quartus仿真&#xff08;文末获取&#xff09; 软件&#xff1a;Quartus 语言&#xff1a;VHDL 代码功能&#xff1a; 数字电子钟 1)设计一个能显示秒、分、时的24小时数字钟 2)用数码管显示出时&#xff0c;分&#xff0c;…

MFC列表控件用ADO添加数据实例

1、本程序基于前期我的博客文章《MFC用ADO连接ACESS数据库实例(免费源码下载)》 程序功能通过编辑框、组合框实时将数据写入ACESS数据库并在列表控件上显示。 2、在主界面资源视图上加上一个按钮控件、两个静态文本、一个编辑框IDC_EDIT1变量名name、一个组合框IDC_COMBO1变量名…

网络机顶盒哪个好?2024畅销网络机顶盒排行榜

因买网络机顶盒踩雷的人不在少数&#xff0c;许多不懂网络机顶盒哪个好的消费者在挑选时会参考网络机顶盒排行榜&#xff0c;这次小编带来了业内最新发布的热销网络机顶盒排行榜&#xff0c;想买网络机顶盒可以看看入围的以下品牌&#xff0c;是目前最受消费者欢迎的品牌。 一&…

参数配置不生效导致海思1151芯片TPC功率超大,引起性能恶化。

• 【Wi-Fi领域】【现网案例4】参数配置不生效导致海思1151芯片TPC功率超大&#xff0c;引起性能恶化。 【问题描述】XXX客户反馈OLT-HG8245W5-6T–Wi-Fi–WA8021V5-LAN-PC组网概率出现近距离测速只有20Mbps 【问题单】DTS2022101410914 【问题分析】 在客户反馈此问题后&#…

面试集中营—JVM篇

一、JVM内存模型 线程独占&#xff1a;栈&#xff0c;本地方法栈&#xff0c;程序计数器; 线程共享&#xff1a;堆&#xff0c;方法区 虚拟机栈&#xff1a;线程私有的&#xff0c;线程执行方法是会创建一个栈阵&#xff0c;用来存储局部变量表&#xff0c;操作栈&#xff0c;…

W801学习笔记二十二:英语背单词学习应用——下

续上篇&#xff1a; W801学习笔记二十一&#xff1a;英语背单词学习应用——上 五、处理用户交互 由于英语也是采用了和唐诗一样的《三分钟限时挑战》《五十题竞速挑战》《零错误闯关挑战》&#xff0c;所以用户交互的逻辑和唐诗是一样的。所以&#xff0c;我们抽一个基类&a…

高级数据结构与算法习题(9)

一、判断题 1、Let S be the set of activities in Activity Selection Problem. Then the earliest finish activity am​ must be included in all the maximum-size subset of mutually compatible activities of S. T F 解析:F。设S是活动选择问题中的一…

Golang Map类型

文章目录 Map介绍Map的定义方式Map的增删查改新增和修改Map元素查找Map元素删除Map元素遍历Map元素 Map元素排序Map切片 Map介绍 Map介绍 在Go中&#xff0c;map是哈希表的引用&#xff0c;是一种key-value数据结构。map类型写作map[K]V&#xff0c;其中K和V分别对应key和value…

深度学习之基于Tensorflow卷积神经网络智能体操健身系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着人们健康意识的提高和数字化技术的快速发展&#xff0c;智能健身系统逐渐成为健身领域的新趋势。…

为什么不建议在 Vue <style> 中使用 scoped?

前言 亲爱的小伙伴&#xff0c;你好&#xff01;我是 嘟老板。我们使用 Vue 开发页面时&#xff0c;经常需要在 <style> 标签下编写样式。不知你是否留意&#xff0c;在 <style> 标签下有一个属性经常出现 - scoped。你知道它起到什么作用吗&#xff1f;原理是怎样…

实现同一份数据的各种镜像

一个数据集通过某个轴&#xff08;通常是垂直或水平轴&#xff09;的镜像对称。这可以通过简单的数学运算来实现。 如果想要通过一块数据生成四份&#xff0c;可以通过以下步骤&#xff1a; 下面是一个简单的示例&#xff0c;展示了如何通过垂直轴&#xff08;左右对称&#…

瑞友天翼应用虚拟化系统SQL注入致远程代码执行漏洞复现

0x01 产品简介 瑞友天翼应用虚拟化系统是西安瑞友信息技术资讯有限公司研发的具有自主知识产权,基于服务器计算架构的应用虚拟化平台。它将用户各种应用软件集中部署在瑞友天翼服务器(群)上,客户端通过WEB即可快速安全的访问经服务器上授权的应用软件,实现集中应用、远程接…

普洱茶泡多少茶叶才算淡茶?

普洱茶淡茶一般放几克茶叶&#xff0c;品深茶官网根据多年专业研究与实践结果&#xff0c;制定了淡茶冲泡标准。在冲泡普洱茶淡茶时&#xff0c;茶叶的投放量是关键因素之一。淡茶冲泡标准旨在保持茶汤的清爽口感&#xff0c;同时充分展现普洱茶的独特风味。 根据《品深淡茶冲…