Sensor 调试流程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sensor 调试流程相关的知识,希望对你有一定的参考价值。
参考技术A “ 日常工作中, 我们拿到一款新 sensor,一般都是先点亮,再接着调试效果。但点亮及调试也是有流程的,需按流程一步步去完成才可以,此文总结一下 ,关于 sensor 从点亮出图到效果调试的一个大致流程 。如觉得文中哪里有问题,或者不清楚的地方,欢迎联系指出。”1)、确认主芯片规格
支持的最大分辨率、mclk、mipi 速率上限、支持的lane数、 支持的raw图像位深、支持的raw图像类型(mono/rgb/rgbir)
2)、硬件原理图
客户主板上调试,则需要客户提供主板原理图;平台公板上调试,则需要提供模组转接板原理图、相应公板的原理图。
3)、Sensor datasheet
确认曝光时间、增益如何设置,帧率如何修改;确认 WDR 输出模式( 是否是dol模式/ dol_virtual channel/ dol_lineinfo)。
4)、Initialize setting
向 sensor 原厂申请所需规格的 sensor setting ,包含信息有:mclk、mipi速率上限、分辨率、mipi_lane数、帧率、输出raw图像位宽、出图模式 (linera/wdr) 。
配置好i2c地址、sensor setting、sensor chip_id;
根据主板原理图,在 dts 中配置 mclk、reset、pwrdn、i2c 的引脚控制,在驱动中配置 sensor pwrdn,reset 的拉高拉低、上电时序;
其他配置,需根据不同平台去具体配置,一般完成上述配置硬件没问题的话,就可以点亮出图了。
步骤 3 完成后,硬件没问题的话,一般就可以出图了
若I2C不通,就要排查下板子的硬件相关问题:
1)、确认AVDD DOVDD DVDD 硬件电压
2)、根据原理图确认reset、pwrdn、i2c、mclk 引脚控制及电压值
3)、确认 mclk 频率
4)、确认 sensor 上电时序
若出图异常(图像分屏、错位、显示不完整 ....);
1)、拍raw图,确认 raw 图是否正常。
2)、若raw 图也异常,输指令排查下mipi 传输是否有报错、示波器量一下mipi 波形,如果都正常的话,那一般就是 sensor setting 有问题,要找sensor 原厂去看了。
3)、但若raw 图正常,那就应该是驱动或者ISP的配置哪里还有问题,要继续排查 。
具体也可参考这篇文章: Sensor bringup 中的一些问题总结
如上图所示,AE分为算法模块和统计模块,算法模块是纯软件模块。所以有很多品牌厂商,虽然用同样的平台,但为了做出差异化的产品,都是用自己开发的 3A 算法。AE 统计模块是和硬件相关的,包含在 ISP pipeline 里。
AE的整个控制流程,如上示意图所示,AE 算法控制一组曝光参数(曝光时间、sensor 模拟增益、sensor 数字增益、isp 数字增益),通过配置的sensor 驱动写入到 sensor 寄存器中(isp dgain 是直接写入相应的 isp 寄存器中的,不通过 sensor 驱动来控制),输出图像数据。
数据经过 AE 统计模块,将亮度统计信息给到 AE 算法模块,再次实时计算得出一组曝光参数,直到曝光正确,循环才结束。首次上电启动时,是从sensor 驱动开始加载的,驱动中包含一组默认的初始化参数,可以点亮出图 。
那sensor 驱动中如何配置 AE ?
1>、首先配置曝光时间
根据 sensor datasheet 配置好最大最小积分时间,然后将 AE 计算出的曝光行,写入到相应控制曝光时间的寄存器就可以了。这里说的是逐行曝光的 sensor,它是按行进行曝光的,积分时间是相对时间,exposure_time = integration_time * line_time(一行时间)。
2>、配置sensor 模拟增益、数字增益
一般我们只需配置 sensor 模拟增益就可以了,不用数字增益,但会用到isp 数字增益,它是 AE 算法控制的,不用在 sensor 驱动中去配置。总结一下,关于sensor 模拟增益的控制,一般分为3种形式。
一种是写入 sensor again 寄存器的值有具体要求,会有一个 again_table,配置好平台与 Sensor 的匹配精度(对应好几倍增益,应该写什么值),通过查 again_table 写入。一般思特威和格科微的 again 配置,都是要查表写入,如下是 sc230ai datasheet 中的 again_table 。
另一种是,写入 sensor again 寄存器的值是连续的,配置好平台与 Sensor 的匹配精度,将平台 AE 计算的 again 值写入sensor 即可。如下是ov08a10的again 配置,0x3503[2]=0 ,real_gain=Gain[12:0]/128,精度是128,[0-7]是配置小数位,[8-12] 是配置整数位;0x3503[2]=1, Gain[12:0],只有整数位1x,2x,4x,8x 。
后一种是如下imx335 所示,写入 sensor again 寄存器的值,是要求转换成dB写入,不是增益倍数的方式写入,它是非线性的,将平台 AE 计算的 gain 值转换成 dB 形式写入 sensor 寄存器;
3>、验证曝光及模拟增益的配置是否正确
最后要通过调试工具手动去控制积分时间、模拟增益的写入,然后通过读 sensor 相应的寄存器的值,来判断写入的数据是否正确,以此来检查驱动中的相关配置是否正确。
拉高增益和曝光,验证是否有电源噪声/FPN:如下图所示,有横条纹则一般和硬件相关,竖条纹是和 sensor 相关,要找硬件和 sensor 原厂的人去看。
确认镜头品质:拍摄 ISO22233 解析力卡的raw 图,若图卡对焦对不清晰,四周模糊,或者单独某一边模糊,则镜头品质有问题,需更换镜头。
可参考此篇文章: ISP调试流程概述
MTK sensor调试日志
注
epl259x的驱动可以用于
epl2590
MN66213
MN26233TKDN - id = 0x91
MN25713EKDN - id = 0x81
8975 // 4个手势方向 - 4颗sensor排列
2219 // 4个手势方向
als 室内光照下应该为700左右
ps 底噪值应该为700左右 - *#*#3646633#*#* *#*#889988#*#* -> Hardware Testing ->Sensor ->Light/Proximity Sensor ->Ps Calibration ->Ps Calibration -> Calibration
阈值如果是(500,800),底噪700
靠近1500
远离1200
epl_sensor.ps.integration_time = EPL_PS_INTT_144; // 272 - qk
dynk_low_offset = 500; // 100 - qk
dynk_high_offset = 800; // 300 - qk
一、新增驱动方法一_适用androidO(示例: msensor mmc5603x)
1.添加kernel-4.4\\drivers\\misc\\mediatek\\sensors-1.0\\magnetometer\\mmc5603x文件夹(mmc5603x.c、mmc5603x.h、Kconfig、Makefile四个文件)
st480.c
st480.h
Kconfig 建宏--MTK_MMC5603X
Makefile
2.kernel-4.4\\drivers\\misc\\mediatek\\sensors-1.0\\magnetometer\\Kconfig 添加:
+ source "drivers/misc/mediatek/sensors-1.0/magnetometer/mmc5603x/Kconfig"
3.kernel-4.4\\drivers\\misc\\mediatek\\sensors-1.0\\magnetometer\\Makefile 添加:
+ obj-$(CONFIG_MTK_MMC5603X) += mmc5603x/
4.kernel-4.4\\arch\\arm\\configs\\k39tv1_bsp_1g_debug_defconfig、k39tv1_bsp_1g_defconfig 修改
+ CONFIG_CUSTOM_KERNEL_MAGNETOMETER=y
+ CONFIG_MTK_MMC5603X=y
5.添加vendor\\microhand\\msensor\\mmc5603x_32bit文件夹(libmemsicd5603x.so一个文件,供应商提供)
6.device\\mediateksample\\k39tv1_bsp_1g\\device.mk 添加,将算法库拷贝到指定目录
+ #add by msensor mmc5603x
+ PRODUCT_COPY_FILES += vendor/microhand/msensor/mmc5603x_32bit/libmemsicd5603x.so:vendor/lib/libmemsicd5603x.so
7.device\\mediateksample\\k39tv1_bsp_1g\\ProjectConfig.mk
+ CUSTOM_KERNEL_MAGNETOMETER=yes
二、新增驱动方法二_适用androidM/N(示例: msensor st480)
1.添加kernel-3.18\\drivers\\misc\\mediatek\\magnetometer\\st480文件夹(包含st480.c、st480.h、Kconfig、Makefile四个文件)
st480.c
st480.h
Kconfig 建宏--MTK_ST480
Makefile
2.kernel-3.18\\drivers\\misc\\mediatek\\magnetometer\\Kconfig 添加:
+ source "drivers/misc/mediatek/magnetometer/st480/Kconfig"
3.kernel-3.18\\drivers\\misc\\mediatek\\magnetometer\\Makefile 添加:
+ obj-$(CONFIG_MTK_ST480) += st480/
4.kernel-3.18\\arch\\arm\\boot\\dts\\len6737m_35_m0.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>;
;
4.1 修改dws: i2c总线数与i2c地址,驱动中会用到
I2C:
MSENSOR I2C_CHANNEL_2 0x30
5.kernel-3.18\\arch\\arm\\configs\\len6737m_35_m0_debug_defconfig、len6737m_35_m0_defconfig 修改
- #CONFIG_CUSTOM_KERNEL_MAGNETOMETER=y
+ CONFIG_CUSTOM_KERNEL_MAGNETOMETER=y
+ CONFIG_MTK_ST480=y
6.添加vendor\\lentek\\libs\\mt6737m\\st480文件夹(包含st480、Android.mk、README、NOTICE)
st480 是一个可执行文件---init.xxx.rc中运行的daemon进程
Android.mk 是干嘛的?
README 解释信息
NOTICE 解释信息
7.device\\lentek\\len6737m_35_m0\\ProjectConfig.mk 修改:
- CUSTOM_KERNEL_MAGNETOMETER = no
+ CUSTOM_KERNEL_MAGNETOMETER = yes
8.device\\mediatek\\mt6735\\init.mt6735.rc 添加:
service st480 /system/bin/st480 // 这是一个服务,服务的路径
disabled
user system
group system
class main // 归属于main这个service,main启动时启动st480
9.device\\lentek\\len6737m_35_m0\\factory_init.project.rc 添加:
service st480 /system/bin/st480 // 这是一个服务,服务的路径--应该是工厂模式用到的
disabled
user system
group system
10.device\\mediatek\\common\\sepolicy\\file_contexts 添加:
+ /system/bin/st480 u:object_r:st480_exec:s0 // 当我们添加跑一个服务的时候就需要对其添加(开放)权限?哪些进程可以访问它
11.添加device\\mediatek\\common\\sepolicy\\st480.te文件
12.device\\mediatek\\mt6735\\device.mk 添加:
+ PRODUCT_PACKAGES += st480 // 复制st480,从…到/system/bin/
三、查看log:
1.查看上报数据
cat /proc/kmsg | grep "***"
2.查看开机串口log
从串口测试点(TXD)接线出来,用usb转串口线,配合xshell抓串口log(波特率:912600)
3.查看sensor型号:
eng 版可以通过 命令查看: cat /sys/bus/platform/drivers/gsensor/chipinfo
user版可以通过 命令查看: dmesg | grep "gsensor" -i // 按power键灭屏or亮屏时,会打开or关闭sensor,会有内核缓冲器会有log打出
[ 1099.329303] (0)[934:android.ui]qma6981_enable_nodata 1964 : Gsensor not in suspend gsensor_SetPowerMode!, enable_status = 1
[ 1102.168146] (0)[946:PowerManagerSer]qma6981_enable_nodata 1964 : Gsensor not in suspend gsensor_SetPowerMode!, enable_status = 0
user版可以通过 命令查看: dmesg | grep "als" -i
user版可以通过 命令查看: dmesg | grep "msensor" -i
user版可以通过 命令查看: dmesg | grep "gyro" -i
四、根据input子系统的调试方法:
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 "liuzhigou"
<4>[ 564.973691]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0xa
<4>[ 564.973725]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status epl_sensor.ps.compare_low = 0x8
<4>[ 565.168562]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0xa
<4>[ 565.168588]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status epl_sensor.ps.compare_low = 0x8
<4>[ 565.368485]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0xa
<4>[ 565.368527]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status epl_sensor.ps.compare_low = 0x8
<4>[ 565.568808]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0xa
<4>[ 565.568851]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status epl_sensor.ps.compare_low = 0x8
<4>[ 565.599273]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0x17
<4>[ 565.599314]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status epl_sensor.ps.compare_low = 0x0
<4>[ 565.599982]<0> (0)[2935:kworker/0:3]liuzhigou [epl_sensor_report_ps_status]: epl_sensor.ps.data.data=18642, ps_status=0 // 靠近
<4>[ 565.630511]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0xf
<4>[ 565.630547]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status epl_sensor.ps.compare_low = 0x8
<4>[ 565.631129]<0> (0)[2935:kworker/0:3]liuzhigou [epl_sensor_report_ps_status]: epl_sensor.ps.data.data=17031, ps_status=1 // 远离
<4>[ 565.735292]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0x17
<4>[ 565.735316]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status epl_sensor.ps.compare_low = 0x0
<4>[ 565.735765]<0> (0)[2935:kworker/0:3]liuzhigou [epl_sensor_report_ps_status]: epl_sensor.ps.data.data=17468, ps_status=0 // 靠近
<4>[ 565.757034]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status gRawData.raw_bytes[0] = 0xf
<4>[ 565.757054]<0> (0)[2935:kworker/0:3]liuzhigou epl_sensor_read_ps_status epl_sensor.ps.compare_low = 0x8
<4>[ 565.757495]<0> (0)[2935:kworker/0:3]liuzhigou [epl_sensor_report_ps_status]: epl_sensor.ps.data.data=16792, ps_status=1 // 远离
五、跟读代码可知:以gsensor(mc3xxx_auto)为例
通过sys文件系统接口调试
1.架构实现 - 两个路径的节点是一样的,cat出来也是相同的,hal层走class
/sys/class/misc/m_acc_misc/*** 有若干属性,可以读写操作
cat /sys/.../accenablenodata -- 不支持 echo 0/1 > 无作用
cat /sys/.../accactive -- 1(使能) echo 0 > /sys/.../accactive -- disable
cat /sys/.../accdelay(不常用)
cat /sys/.../accbatch(不常用)
cat /sys/.../accflush(不常用)
cat /sys/.../accdevnum -- 4(/dev/input/event4)
2.驱动实现
/sys/bus/platform/drivers/gsensor/*** 有若干属性,可以读写操作
* cat /sys/.../chipinfo -- MC3XXX Chip -- 直接打印MC3XXX Chip
* cat /sys/.../sensordata -- 1758 0695 1b88 -- 读地址0x00
cat /sys/.../cali -- 三组校准数据 -- 第二组为校准系数,上层未下发就为0
cat /sys/.../selftest -- 空(未设置)
cat /sys/.../firlen -- 0 -- 滤波长度 - 从dts获得 - 全部为0
cat /sys/.../trace -- 0x0000 -- mc3xxx_i2c_probe()把它设置为0
cat /sys/.../status -- CUST: 2 7 <-1 0> -- i2c_num direction <power_id power_vol> - 从dts获取
cat /sys/.../power -- 亮屏0x0041,灭屏0x0043 -- 读地址0x07
cat /sys/.../version -- 2.1.6 -- 打印驱动的宏
* cat /sys/.../chipid -- 7C-5F-5E-46 -- 读地址0x3C
cat /sys/.../virtualz -- 不支持
* cat /sys/.../regmap -- 打印所有寄存器的值
* cat /sys/.../orientation -- 7 -- 从dts获取 echo 7 > /sys/.../orientation
cat /sys/.../accuracy -- 2(精度 - 宏设置)
cat /sys/.../selfcheck -- 乱码
cat /sys/.../validate -- 0(验证成功) -- 从0x3b读出pcode - 匹配mc3***系列芯片 - 验证成功返回0
cat /sys/.../pdoc -- 0(不支持 - 宏未开)
六、sensor兼容:以gsensor为例:
Mtk的架构已经做了兼容,最多只能兼容5个(gsensor_init_list[5])(tpd_driver_list[20])
android5.1:
七、ps的阈值如何设定
1. androidL/M/N:
kernel-3.10/drivers/misc/mediatek/alsps/epl259x/epl259x.c
dynk_low_offset = 2000; //500; //100 - qk
dynk_high_offset = 2300; //800; //300 - qk
将(500,800)改为(2000,2300),距离约降低三分一,写死在驱动不用dts
八、sensor数据上报有三种接口
1. 轮询上报 --最终使用
2. sys文件系统 -- 调试使用
3. ioctl接口 -- ATA (工厂模式: 同时按住音量减和电源键开机)
mtk原生:
关闭轮询 - 无功能
关闭ioctl - 工厂模式无数据(音量减与电源键同时按住开机)
关闭sysfs - 有功能
bose修改hal层框架后: - 由一个进程主动读取
关闭轮询 - 有功能
关闭ioctl - 工厂模式无数据(音量减与电源键同时按住开机)
关闭sysfs - 无功能
九、调试查看log
1. hal层enable与disable时候会打印:[logcat | grep "..."]
vendor/mediatek/proprietary/hardware/sensor/nusensors.cpp
int sensors_poll_context_t::activate(int handle, int enabled)
ALOGD( "activate handle =%d, enable = %d",handle, enabled );
sensor编号:(kernel/.../hwmsensor.h中定义减1)
accelerometer 0
magnetometer 1
orientation 2
gyroscope 3
ambient light sensor 4
proximity sensor 7
十、*#0*#测试模式调用接口:
codec_37_n_base\\update\\alps\\kstpackages\\apps\\KSTFactoryTest\\src\\com\\kingsentime\\factorytest\\TestSensor.java
accelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
lightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
distanceSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
十一、msensor异常调试步骤:
1. 安装打开APK : zhinanzhen.apk。划八校准后查看是否正常: 不管手机如何转动指针始终指北
==>指南针转动,但并不始终指北 -->修改DTS中msensor的方向
==>指南针不动 -->安装sensorlist.apk 查看指南针msensor是否有数据变化
==>无数据变化 -->查看开机log,查看是否有I2C通讯报错,
==> 如i2c报错 -->用万用表检查: 芯片供电电压、连线(遇到过贴片没贴好,重贴就ok)和i2c地址
2. 如果msensor方向调整对了,当指南针方向还是不对
==>检查gsensor是否正常工作,因为指南针会用到gsensor的数据
3. adb shell
ps 查看指南针的daemon是否正常运行,如未正常运行,可adb push ;cd 到所在目录; daemon名; 手动把daemon跑起来
注:
1.eng版才有运行权限
2.cd /system/bin/; /daemon名; 运行, kill daemon; 停止
3.alps/out/target/product/magc6737m_65_n/system/bin/
4. 如指南针方向大致正确,但上下抖动(正负3度以外),检查msensor摆件位置,
由于msensor检测磁场,旁边不能有:
带磁元件(如马达、camera)【遇到过带磁螺丝导致方向不准,换螺丝】
大电流(cpu/flash/wifi芯片/百毫安的供电电流、需距离5mm以上)【遇到过两次有大电流,改版】
如果有,需要硬件改版,将msensor挪到旁边去
十二、gsensor、msensor、gyroscope的方向调试
1. 由于这些sensor都是三轴sensor,故均有0~7 八个方向。通常写在dts,少数不规范的写死在驱动
2. 先找到小原点即芯片原点坐标(在芯片丝印上有)
gsensor(3433/6981/bmc156)
y
__|__
| o|
| |-->x
|__ __|
gyroscope(bmg160)
x
__|__
| o|
y<--| |
|__ __|
然后根据sensor的摆件位置,计算出sensor的方向,先把手机平方在桌面
2.1 如sensor贴在top层
y轴指向听筒位置(小圆点在右上角),方向为0
y轴指向左侧位置(小圆点在左上角),方向为1
y轴指向home位置(小圆点在左下角),方向为2
y轴指向右侧位置(小圆点在右下角),方向为3
(逆时针旋转90度,方向+1)
2.2 如sensor贴在bottom层,相应的方向:4/5/6/7
3. 由于芯片常在屏蔽罩里面,不便查看,可以由原理图与layout 查看其小原点位置: pin脚1的位置
4. 何种现象显示方向正确:
gsensor : 手机界面会翻转
msensor : 安装打开指南针apk,划八校准后,不管手机如何转动指针始终指北
gyroscope: 安装需要陀螺仪的游戏apk(如打僵尸),运行游戏看是否打得准
5. 何种现象显示方向正确: 用sensorlist查看
5.1 gsensor
手机平放,z轴应为9.8,xy为0
手机竖立,y轴应为9.8,zx为0
手机侧立,x轴应为9.8,yz为0 - 正面朝左
5.2 msensor,先用正常手机如iphone找到北边
x轴指北时,x轴数据达到最大;x轴反方向指北时,x轴数据达到负的最大
y轴指北时,y轴数据达到最大;y轴反方向指北时,y轴数据达到负的最大
z轴指北时,z轴数据达到最大;z轴反方向指北时,z轴数据达到负的最大
5.3 gyroscope,假设手机有长宽高三轴
沿着手机宽轴摆动手机,x轴数据变化比另两轴大(先正后负)
沿着手机长轴摆动手机,y轴数据变化比另两轴大
沿着手机高轴摆动手机,z轴数据变化比另两轴大
6. 还可以通过sensorlist看到的xyz轴数据计算,与原本的方向计算出正确的方向
value swap X with Y reverse sign X reverse sign Y reverse sign Z
0 0 0 0 0
1 0 1 0 1
2 0 1 1 0
3 0 0 1 1
4 1 1 0 0
5 1 0 1 0
6 1 0 0 1
7 1 1 1 1
sensor调试案例:
案例一 : 兼容gsensor(mxc400x与mxc6225)
现象 :
平台 : androidL,MTK6580
步骤 : 1.
2. !!!试验这样是不是i2c地址相同的就可以再次i2c_probe
epl_sensor_i2c_probe()
epl_sensor_i2c_client = client;
exit:
epl_sensor_i2c_client = NULL;
alsps_init_flag = -1;
3.
总结 :
案例二 : gsensor(qma6981)由mtk老架构改mtk新架构
现象 :
平台 : androidL,MTK6580
步骤 : 1. 思路:老的架构在模块入口platform_driver_register()注册一个平台设备,probe中注册i2c设备
新的架构在模块入口acc_driver_add()将结构题注册到list中,local_init中注册i2c设备
2.#include <accel.h>
static int __init qma6981_init(void)
- platform_driver_register(&qma6981_gsensor_driver)
+ acc_driver_add(&qma6981_init_info);
return 0;
3. static struct sensor_init_info qma6981_init_info =
.name = QMA6981_ACC_DEV_NAME,
.init = qma6981_local_init,
.uninit = qma6981_local_uninit,
;
4.static int qma6981_local_init(void)
i2c_add_driver(&qma6981_i2c_driver)
if(-1 == qma6981_init_flag)
return -1;
return 0;
5.static int qma6981_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
- if((err = qma6981_create_attr(&qma6981_gsensor_driver.driver)))
+ if((err = qma6981_create_attr(&(qma6981_init_info.platform_diver_addr->driver))))
exit:
+ qma6981_init_flag = -1;
return err;
总结 :
案例三 : 计步器的实现 - gsensor硬件中断
现象 :
平台 : androidL,MTK6737
步骤 : 1.
2.
3.
总结 :
案例四 : 调试新msensor(mmc3630x),bin文件没有拷贝到out目录 - 修改device.mk
现象 : msensor无功能
平台 : androidN,MTK6737
排查过程: 1.在alps\\vendor\\magcomm\\libs\\mt6737m\\目录创建文件夹: memsicd3630x ,内部有bin文件 : memsicd3630x
修改alps\\device\\mediatek\\mt6735\\device.mk添加:
PRODUCT_PACKAGES += memsicd3416x
+ PRODUCT_PACKAGES += memsicd3630x
2.out目录没有生成对应的bin文件:memsicd3630x
android009@mht-09:~/liuzhigou/code2_37_m_base_v663_xiaoxing_k29d1_user$ find alps/out/ -name memsicd3*
alps/out/target/product/magc6737m_65_c_m0/system/bin/memsicd3416x
3.修改alps\\device\\mediatek\\mt6735\\device.mk添加: (注意要精确到具体文件,而不是文件夹)
+ PRODUCT_COPY_FILES += vendor/magcomm/libs/mt6737m/memsicd3630x/memsicd3630x:system/bin/memsicd3630x
4.out目录成功生成对应的bin文件:memsicd3630x
android009@mht-09:~/liuzhigou/code2_37_m_base_v663_xiaoxing_k29d1_user$ find alps/out/ -name memsicd3*
alps/out/target/product/magc6737m_65_c_m0/system/bin/memsicd3416x
alps/out/target/product/magc6737m_65_c_m0/system/bin/memsicd3630x // 我们要的bin文件
处理方案: 修改device.mk
总结 : 上层的问题,及时请教上层的同事
案例三 : gsensor(qma6981) I2C不通 - 贴片没有贴好
现象 : I2C不通
平台 : androidN,MTK6737
步骤 : 1. gsensor无功能,打log,在串口log中发现
[ 13.465281] .(3)[1:swapper/0][name:qma6981&][QMA-Gsensor] I2C_TxData 271 : I2C_TxData delay!
[ 13.476575] .(3)[1:swapper/0][name:i2c&]ERROR,510: id=2,addr: 12, transfer error
[ 13.477594] .(3)[1:swapper/0][name:i2c&]ERROR,516: I2C_ACKERR
2. 分析:由于sensor电源为常供,无需上电,i2c不通的可能:
(1)i2c地址不对
(2)硬件有问题
3. 询问FAE,确认i2c地址正确,排查硬件问题:将芯片取下,外接小板(小板上有芯片)
结果芯片工作正常
处理方案: -->把芯片重新贴好
总结 : 只有camera在i2c通讯之前要上电,其他都可以直接通讯,i2c不通只有两种可能:
(1)i2c地址不对
(2)硬件有问题
案例四 :
现象 :
平台 : androidN,MTK6737
步骤 : 1.
2.
案例五 : gsensor兼容(3433 & 6981)导致功耗大(70ma)
现象 :
平台 : androidN,MTK6737
步骤 : 1. 休眠时候打log: adb shell dmesg > e:gsensor_3433_6981.log
log显示由于设备(2-004c - mc3433)休眠失败,导致系统休眠失败,重新唤醒,
系统一直处于: 休眠->休眠失败->唤醒 ->休眠的循环中
[ 207.629520] (1)[1066:system_server]qma6981_suspend 2894 : liuzhigou 20171018 qma6981_suspend start
[ 207.635164] (1)[1066:system_server]qma6981_suspend 2914 : liuzhigou 20171018 qma6981_suspend end
[ 207.635254] (1)[1066:system_server]liuzhigou 20171018 mc3xxx_suspend start
[ 207.635291] (1)[1066:system_server]dpm_run_callback(): i2c_device_pm_suspend+0x0/0x38 returns -22
[ 207.635324] (1)[1066:system_server]PM: Device 2-004c failed to suspend: error -22
[ 207.635352] (1)[1066:system_server][name:suspend&]PM: Some devices failed to suspend, or early wake event detected
2. 在mc3433的休眠函数中,添加打印log:
static int mc3xxx_suspend(struct i2c_client *client, pm_message_t msg)
struct mc3xxx_i2c_data *obj = i2c_get_clientdata(client);
int err = 0;
if(msg.event == PM_EVENT_SUSPEND)
if(obj == NULL)
+ GSE_ERR("liuzhigou 20171025 %s obj == NULL\\n",__FUNCTION__);
return -EINVAL;
[ 116.917907] (0)[1150:system_server]liuzhigou 20171018 mc3xxx_suspend start
[ 116.917926] (0)[1150:system_server]liuzhigou 20171018 mc3xxx_suspend msg.event == PM_EVENT_SUSPEND
[ 116.917943] (0)[1150:system_server]liuzhigou 20171018 mc3xxx_suspend obj == NULL
[ 116.917974] (0)[1150:system_server]dpm_run_callback(): i2c_device_pm_suspend+0x0/0x38 returns -22
[ 116.917996] (0)[1150:system_server]PM: Device 2-004c failed to suspend: error -22
[ 116.918016] (0)[1150:system_server]PM: Some devices failed to suspend, or early wake event detected
根据log,obj为空指针,出错判断后返回错误值
3. 根据标志位添加出错判断,如果没加载3433就直接return 0(成功),终止3433的休眠函数
static int mc3xxx_suspend(struct i2c_client *client, pm_message_t msg)
struct mc3xxx_i2c_data *obj = i2c_get_clientdata(client);
int err = 0;
if(msg.event == PM_EVENT_SUSPEND)
if(obj == NULL)
+ if (MC3XXX_INIT_FAIL == s_nInitFlag)
+ GSE_ERR("liuzhigou 20171025 %s obj == NULL MC3XXX_INIT_FAIL == s_nInitFlag \\n",__FUNCTION__);
+ return 0;
+
+ else
+ GSE_ERR("liuzhigou 20171025 %s obj == NULL MC3XXX_INIT_FAIL != s_nInitFlag \\n",__FUNCTION__);
return -EINVAL;
总结 : 此log为正常状态: 0x4000为pmu中断
[ 147.732936] -(0)[1066:system_server][name:mt_spm_internal&][SPM] wake up byEINT, timer_out = 18724959, r13 = 0x10001000, debug_flag = 0x9f
[ 147.732936] -(0)[1066:system_server][name:mt_spm_internal&][SPM] r12 = 0x20, raw_sta = 0x20, idle_sta = 0x9fa, event_reg = 0x90100000, isr = 0x0
[ 147.732936] -(0)[1066:system_server][name:mt_spm_sleep&][SPM] suspend dormant state = 0, md32_flag = 0x0, md32_flag2 = 0
[ 147.732936] -(0)[1066:system_server][name:mt_spm_sleep&][SPM] log_wakesta_index = 5
[ 147.732936] -(0)[1066:system_server][name:irq_mt_eic&]EINT_STA:
[ 147.732936] -(0)[1066:system_server][name:irq_mt_eic&]EINT Module - index:192,EINT_STA = 0x4000
[ 147.732936] -(0)[1066:system_server][name:irq_mt_eic&]EINT 206 is pending
[ 147.732936] -(0)[1066:system_server][name:irq_mt_eic&]
[ 147.732988] -(0)[1066:system_server][name:ccci&][ccci1/mcd]Resume cldma pdn register ...11
[ 147.733070] -(0)[1066:system_server][name:irq_mt_eic&]EINT Module - expires:4294952066, jiffies:4294952065, deb_in_jiffies:1,
[ 147.733091] -(0)[1066:system_server][name:irq_mt_eic&]deb:1000, in mt_eint_set_timer_event
[ 147.733270] (0)[1066:system_server][name:cpu&]Enabling non-boot CPUs ...
[ 147.733571] -(1)[0:swapper/1]CPU1: Booted secondary processor
案例六 : ATA测试中gsensor(qma6981)无数据 - 添加init() - 原因:i2c_probe的时候没有跑init(),而正常开机在别处有init()
现象 : 正常开机有数据,ATA无数据
平台 : androidM,MTK6580
步骤 : 1. 由于ATA 是通过ioctl接口获取数据,在ioctl函数中添加log,显示读到的数据为0
2. 在qma6981_unlocked_ioctl()中获取数据之前进行初始化
switch (cmd)
case GSENSOR_IOCTL_READ_SENSORDATA:
+ qma6981_initialize(client);
==> ok
案例七 : CTS测试报错- 磁力传感器 - 板子上内贴 - 从配置中移除
此法不通!!!案例八 : 打开自动背光,通话贴脸灭屏后,移开无法亮屏 - 没找到死锁的地方,直接更换一份版本较新的驱动
平台 : androidN,MTK6737
步骤 : 1. 对比其他项目667,无此现象,查BOM
663 MN26233TKDN(问题项目)
667 MN25713EKDN
2. 进入"*#0*#"测试模式,交替打开als与ps,出现概率性的als无功能(数值不动)
分析怀疑是als与ps enable或disable的时候出问题
3. FAE现场支持,提供了一份最新的驱动,问题不再出现
FAE说旧驱动中有死锁,但是找不到
4. 尝试注释掉alps\\kernel-3.18\\drivers\\misc\\mediatek\\alsps\\epl259x\\epl259x.c
static int als_enable_nodata(int en)
if(enable_als != en)
+ //epl_sensor_update_mode(obj->client);
==>功能正常
案例九 : als概率性无功能 - 有死锁 - 没找到死锁的地方,直接更换一份版本较新的驱动
案例十 : 强光下,自动背光的亮度变化不明显,弱光下,自动背光的亮度是正常的
平台 : androidN,MTK6737
步骤 : 1. 修改als积分时间: alps/kernel-3.18/drivers/misc/mediatek/alsps/epl259x/epl259x.c
- epl_sensor.als.integration_time = EPL_ALS_INTT_1024;
+ epl_sensor.als.integration_time = EPL_ALS_INTT_64;
案例十一 : 打开自动背光,遮挡光感,屏幕亮度无变化 - tp油墨遮挡
平台 : androidN,MTK6737
步骤 : 1. 打开"*#0*#"测试模式,查看光感上报值,值偏小
对比亮度能够自动调节的其他项目
v618_p300 : 1969 lux
v663_k38 : 328 lux(问题机)
怀疑是结构遮挡,导致进光量偏少
2. 结构同事分析:是tp开孔处油墨有问题,刮开tp油墨亮度2900 lux
案例十二 : gsensor(mxc4005)ATA中z轴数据为0 - 需要factory_init.rc启动一个daemon
平台 : androidM,MTK6580
步骤 : 1. 正常开机三轴均有数据,ATA(音量减+电源键开机)中z轴数据为0
2. 新建文件夹alps/vendor/magcomm/libs/mt6580/memsicp_f_32/
里面新增4个文件: memsicp_f_32、Android.mk、NOTICE、README
其中memsicp_f_32需要供应商提供
3. alps/device/mediatek/mt6580/device.mk
+ PRODUCT_PACKAGES += memsicp_f_32
4. alps/device/mediatek/mt6580/factory_init.rc
+ service memsicp_f_32 /system/bin/memsicp_f_32
+ user system
+ group system
+ class main
总结 :
案例十三 : android8.1 sensor无法获取dts数据 -- 写死在驱动
现象 : 获取不到dts数据
平台 : androidO,MTK6737&MTK6739
步骤 : 1. 由于获取不到dts、dws的数据,无法设置i2c地址、方向,可以写死在驱动
alps\\kernel-4.4\\drivers\\misc\\mediatek\\sensors-1.0\\accelerometer\\mpu6050g\\mpu6050.c
mpu6050_i2c_probe(struct i2c_client *client)
+ client->addr = 0x69;
+ obj->hw.direction = 0;
2. 由于获取不到dts的数据,无法设置中断脚,可以写死在驱动:
alps\\kernel-3.18\\drivers\\misc\\mediatek\\sensors-1.0\\alsps\\epl259x\\epl259x.c
obj->irq = irq_of_parse_and_map(obj->irq_node, 0);
// 通过打印log可以看出GPIO65对应irq 为353
// 通过打印log可以看出GPIO3 对应irq 为291
// 可知GPIO口的中断号是线性的
printk("obj->irq = %d\\n", obj->irq);
+ obj->irq = 291; // GPIO3 - liuzhigou add for v662
request_irq(obj->irq, epl_sensor_eint_func, IRQF_TRIGGER_NONE, "ALS-eint", NULL)
3. 后面有空再好好分析一下如何才能获取到dts数据
总结 :
案例十四 : android8.1 msensor(akm09918)无法打开算法库(libakl.so)
现象 : 指南针不转,打开sensorlist,指南针数据始终为0
平台 : androidO,MTK6739
步骤 : 1. 打印kernel log(导出mtklog或cat /dev/kmsg | grep "liuzhigou")看驱动是否有上报数据
kernel-4.4\\drivers\\misc\\mediatek\\sensors-1.0\\magnetometer\\mag.c
int mag_data_report(struct mag_data *data)
struct sensor_event event;
int err = 0;
+ printk("liuzhigou update!valus: %d, %d, %d, %d\\n" , data->x, data->y, data->z, data->status);
log:
-- 当打开sensorlist时,地磁数据上报正常
Line 1233: <4>[ 113.500580] (3)[67:kworker/3:1]liuzhigou update!valus: 1500, -30400, 6000, 68
Line 1241: <4>[ 113.699990] (3)[67:kworker/3:1]liuzhigou update!valus: 2400, -30000, 7100, 4
Line 1246: <4>[ 113.902548] (3)[67:kworker/3:1]liuzhigou update!valus: 300, -28000, 6000, 116
Line 1248: <4>[ 114.104571] (3)[67:kworker/3:1]liuzhigou update!valus: 1600, -29500, 8100, 100
Line 1249: <4>[ 114.300017] (3)[67:kworker/3:1]liuzhigou update!valus: 200, -28600, 5400, 4
Line 1257: <4>[ 114.500118] (3)[67:kworker/3:1]liuzhigou update!valus: 800, -30600, 7000, 100
Line 1260: <4>[ 114.700351] (3)[67:kworker/3:1]liuzhigou update!valus: 1200, -29800, 4500, 36
Line 1270: <4>[ 114.903466] (3)[67:kworker/3:1]liuzhigou update!valus: 1200, -29100, 6200, 116
Line 1272: <4>[ 115.100006] (3)[67:kworker/3:1]liuzhigou update!valus: 1900, -29100, 6200, 36
Line 1278: <4>[ 115.303492] (3)[67:kworker/3:1]liuzhigou update!valus: 1500, -29200, 4400, 4
Line 1284: <4>[ 115.500014] (3)[67:kworker/3:1]liuzhigou update!valus: 400, -29300, 5200, 68
Line 1298: <4>[ 115.700524] (3)[67:kworker/3:1]liuzhigou update!valus: 600, -29400, 4600, 52
Line 1317: <4>[ 115.899930] (3)[67:kworker/3:1]liuzhigou update!valus: 800, -28700, 5100, 52
2. 查看算法库加载: vendor\\mediatek\\proprietary\\hardware\\sensor\\sensors-1.0\\VendorInterface.cpp
VendorInterface::VendorInterface()
...
strlcpy(buf, "lib", sizeof(buf));
strlcat(buf, libinfo.libname, sizeof(buf));
strlcat(buf, ".so", sizeof(buf));
lib_handle = dlopen(buf, RTLD_NOW);
+ ALOGE("VendorInterface() buf = %s\\n", buf);
if (!lib_handle)
ALOGE("get lib_interface fail dlopen operation.\\n"); // 报此错误
lib_handle = NULL;
return;
供应商提供的算法库打开失败 -> 找供应商重新提供
3. 如果算法库加载没报错,可以查看校准前后数据
int VendorInterface::magCalibration(struct sensorData *inputData,struct sensorData *outputData)
struct magCaliDataInPut magInputData;
struct magCaliDataOutPut magOutputData;
int ret = 0;
memset(&magInputData, 0, sizeof(struct magCaliDataInPut));
memset(&magOutputData, 0, sizeof(struct magCaliDataOutPut));
if (!lib_interface)
return -1;
if (!lib_interface->doCaliApi)
return -1;
magInputData.timeStamp = inputData->timeStamp;
magInputData.x = inputData->data[0];
magInputData.y = inputData->data[1];
magInputData.z = inputData->data[2];
magInputData.status = inputData->status;
+ ALOGE("magCalibration() before Calibration : magInputData.x = %f\\n", magInputData.x);
+ ALOGE("magCalibration() before Calibration : magInputData.y = %f\\n", magInputData.y);
+ ALOGE("magCalibration() before Calibration : magInputData.z = %f\\n", magInputData.z);
ret = lib_interface->doCaliApi(&magInputData, &magOutputData);
+ ALOGE("magCalibration() after Calibration : magInputData.x = %f\\n", magInputData.x);
+ ALOGE("magCalibration() after Calibration : magInputData.y = %f\\n", magInputData.y);
+ ALOGE("magCalibration() after Calibration : magInputData.z = %f\\n", magInputData.z);
outputData->timeStamp = magOutputData.timeStamp;
outputData->data[0] = magOutputData.x;
outputData->data[1] = magOutputData.y;
outputData->data[2] = magOutputData.z;
outputData->data[3] = magOutputData.x_bias;
outputData->data[4] = magOutputData.y_bias;
outputData->data[5] = magOutputData.z_bias;
outputData->status = magOutputData.status;
return ret;
总结 : 最后因为供应商无法提交现场支持,更换物料为mmc5603x,合入一次成功
案例十五 : android8.1 msensor(mmc5603x)算法库(libmemsicd5603x.so)有问题
现象 : 指南针不转,打开sensorlist,指南针数据始终为0
平台 : androidO,MTK6580
步骤 : 1. 打印kernel log(导出mtklog或cat /dev/kmsg | grep "liuzhigou")看驱动是否有上报数据
kernel-3.18\\drivers\\misc\\mediatek\\sensors-1.0\\magnetometer\\mag.c
int mag_data_report(struct mag_data *data)
struct sensor_event event;
int err = 0;
+ printk("liuzhigou update!valus: %d, %d, %d, %d\\n" , data->x, data->y, data->z, data->status);
log:
-- 当打开sensorlist时,地磁数据上报正常
4,69949,1451351242,-; (0)[154:kworker/0:1]liuzhigou update!valus: -90, 126, -878, 3
4,69977,1451551292,-; (0)[154:kworker/0:1]liuzhigou update!valus: -88, 129, -879, 3
4,70042,1451751525,-; (0)[154:kworker/0:1]liuzhigou update!valus: -90, 125, -872, 3
4,70052,1451951410,-; (0)[154:kworker/0:1]liuzhigou update!valus: -87, 126, -878, 3
4,70065,1452151250,-; (0)[154:kworker/0:1]liuzhigou update!valus: -90, 120, -859, 3
4,70075,1452351395,-; (0)[154:kworker/0:1]liuzhigou update!valus: -89, 129, -878, 3
4,70083,1452551445,-; (0)[154:kworker/0:1]liuzhigou update!valus: -88, 133, -882, 3
2. 查看算法库加载: vendor\\mediatek\\proprietary\\hardware\\sensor\\sensors-1.0\\Magnetic.cpp
MagneticSensor::MagneticSensor()
...
TEMP_FAILURE_RETRY(open("/sys/class/sensor/m_mag_misc/maglibinfo", O_RDWR));
TEMP_FAILURE_RETRY(read(fd, &libinfo, sizeof(struct mag_libinfo_t))); // lib算法库的名字是驱动指定的,从节点maglibinfo获取
/*
驱动中指定定算法库的名字
kernel-4.4/drivers/misc/mediatek/sensors-1.0/magnetometer/mag.c
DEVICE_ATTR(maglibinfo, S_IWUSR | S_IRUGO, mag_show_libinfo, NULL);
static ssize_t mag_show_libinfo(struct device *dev, struct device_attribute *attr, char *buf)
struct mag_context *cxt = mag_context_obj;
memcpy(buf, &cxt->mag_ctl.libinfo, sizeof(struct mag_libinfo_t));
return sizeof(struct mag_libinfo_t);
kernel-4.4/drivers/misc/mediatek/sensors-1.0/magnetometer/mmc5603x/mmc5603x.c
static int mmc5603x_i2c_probe()
strlcpy(ctl.libinfo.libname, "memsicd5603x", sizeof(ctl.libinfo.libname)); // 库的名字:libmemsicd5603x.so
kernel-4.4/drivers/misc/mediatek/sensors-1.0/magnetometer/akm09911/akm09911.c
static int akm09911_i2c_probe()
strlcpy(ctl.libinfo.libname, "akl", sizeof(ctl.libinfo.libname)); // 库的名字:libakl.so
*/
strlcpy(buf, "lib", sizeof(buf));
strlcat(buf, libinfo.libname, sizeof(buf));
strlcat(buf, ".so", sizeof(buf));
+ ALOGE("liuzhigou MagneticSensor() buf = %s\\n", buf); // 添加的log
lib_handle = dlopen(buf, RTLD_NOW);
if (!lib_handle)
ALOGE("dlopen fail\\n");
return;
+ ALOGE("liuzhigou dlopen ok\\n"); // 添加的log
查看log(mtklog中的main_log.boot):
01-01 07:03:28.286359 337 337 E Magnetic: liuzhigou MagneticSensor() buf = libmemsicd5603x.so
01-01 07:03:28.419057 337 337 E Magnetic: liuzhigou dlopen ok
3. 如果算法库加载没报错,可以查看校准前后数据
void MagneticSensor::processEvent(struct sensor_event const *event)
float magBias[3] = 0;
struct magCaliDataInPut inputData;
struct magCaliDataOutPut outputData;
static int32_t lastStatus = 0;
memset(&inputData, 0, sizeof(struct magCaliDataInPut));
memset(&outputData, 0, sizeof(struct magCaliDataOutPut));
if (event->flush_action == DATA_ACTION)
mPendingEvent.version = sizeof(sensors_event_t);
mPendingEvent.sensor = ID_MAGNETIC;
mPendingEvent.type = SENSOR_TYPE_MAGNETIC_FIELD;
mPendingEvent.timestamp = event->time_stamp;
mPendingEvent.magnetic.status = event->status;
mPendingEvent.magnetic.x = (float)event->word[0] / (float)mDataDiv;
mPendingEvent.magnetic.y = (float)event->word[1] / (float)mDataDiv;
mPendingEvent.magnetic.z = (float)event->word[2] / (float)mDataDiv;
inputData.x = mPendingEvent.magnetic.x ;
inputData.y = mPendingEvent.magnetic.y ;
inputData.z = mPendingEvent.magnetic.z ;
+ ALOGE("processEvent() before Calibration : inputData.x = %f\\n", inputData.x);
+ ALOGE("processEvent() before Calibration : inputData.y = %f\\n", inputData.y);
+ ALOGE("processEvent() before Calibration : inputData.z = %f\\n", inputData.z);
inputData.status = mPendingEvent.magnetic.status;
inputData.timeStamp = mPendingEvent.timestamp;
if (lib_interface != NULL)
lib_interface->doCaliApi(&inputData,&outputData);
+ ALOGE("processEvent() after Calibration : outputData.x = %f\\n", outputData.x);
+ ALOGE("processEvent() after Calibration : outputData.y = %f\\n", outputData.y);
+ ALOGE("processEvent() after Calibration : outputData.z = %f\\n", outputData.z);
mPendingEvent.magnetic.x = outputData.x;
mPendingEvent.magnetic.y = outputData.y;
mPendingEvent.magnetic.z = outputData.z;
mPendingEvent.magnetic.status = outputData.status;
magBias[0] = outputData.x_bias;
magBias[1] = outputData.y_bias;
magBias[2] = outputData.z_bias;
if (mPendingEvent.magnetic.status != lastStatus)
mSensorCali.saveCalibrationFloat(MAG_BIAS_SAVED_DIR, MAG_TAG_BIAS, magBias, 3);
ALOGE("write bias: [%f, %f, %f]\\n", magBias[0], magBias[1], magBias[2]);
lastStatus = mPendingEvent.magnetic.status;
else
ALOGE("unknow action\\n");
查看log(mtklog中的main_log):
Line 9864: 01-01 07:27:42.910853 339 339 E Magnetic: processEvent() before Calibration : inputData.x = -0.437500
Line 9865: 01-01 07:27:42.911000 339 339 E Magnetic: processEvent() before Calibration : inputData.y = -0.211914
Line 9866: 01-01 07:27:42.911080 339 339 E Magnetic: processEvent() before Calibration : inputData.z = -0.598633
Line 9867: 01-01 07:27:42.911156 339 339 E Magnetic: processEvent() after Calibration : outputData.x = 0.000000
Line 9868: 01-01 07:27:42.911228 339 339 E Magnetic: processEvent() after Calibration : outputData.y = 0.000000
Line 9869: 01-01 07:27:42.911300 339 339 E Magnetic: processEvent() after Calibration : outputData.z = 0.000000
Line 9887: 01-01 07:27:43.108972 339 731 E Magnetic: processEvent() before Calibration : inputData.x = -0.444336
以上是关于Sensor 调试流程的主要内容,如果未能解决你的问题,请参考以下文章