高通sensorhub实现OIS防抖

1. 陀螺仪驱动移植

1.1 AP侧移植

1.1.1 AP侧全编

为了保证AP侧源码的正确性,建议先进行一次AP侧的全编

  1. 进入AP侧根目录sm8250_android_q_aosp/
  2. 执行编译脚本./build_all.sh
#!/bin/bash -e

UNDER='\e[4m'
RED='\e[31;1m'
GREEN='\e[32;1m'
YELLOW='\e[33;1m'
BLUE='\e[34;1m'
MAGENTA='\e[35;1m'
CYAN='\e[36;1m'
WHITE='\e[37;1m'
ENDCOLOR='\e[0m'
ITCVER="Q_v1.1"
WORKDIR=`pwd`
CAFTAG="LA.UM.8.12.r1-11900-sm8250.0"
BUILDROOT="${WORKDIR}/SM8250_HDK_865_Android-${ITCVER}"
PATCH_DIR="${WORKDIR}/patches"
DB_PRODUCT_STRING="HDK865 Development Kit"

#Main Script starts here
#Note: Check necessary program for installation
echo
echo -e "$CYAN Product                   : $DB_PRODUCT_STRING $ENDCOLOR"
echo -e "$MAGENTA Intrinsyc Release Version : $ITCVER $ENDCOLOR"
echo -e "$MAGENTA WorkDir                   : $WORKDIR $ENDCOLOR"
echo -e "$MAGENTA Build Root                : $BUILDROOT $ENDCOLOR"
echo -e "$MAGENTA Patch Dir                 : $PATCH_DIR $ENDCOLOR"
echo -e "$MAGENTA CodeAurora TAG            : $CAFTAG $ENDCOLOR"
echo -n "Checking necessary program for installation......"

#rm ./build_all.log
echo -e "$YELLOW   Building Source code from $BUILDROOT ... $ENDCOLOR"
. build/envsetup.sh
lunch kona-${BV:="userdebug"}
BUILD_NUMBER=HDK865_${ITCVER} ./build.sh dist -j $(nproc) $@ 2>&1 | tee build_all.log
  1. 查看全编是否通过
    (1)vim buld_all.log /* 打开log */
    (2)搜索关键字successfully
    (3)搜索到如下图所示信息,表明编译成功
[ 99% 1546/1548] Package: out/target/product/qssi/qssi-img-HDK865_Q_v1.1.zip
[ 99% 1547/1548] Dist: out/dist/qssi-target_files-HDK865_Q_v1.1.zip
[100% 1548/1548] Dist: out/dist/qssi-img-HDK865_Q_v1.1.zip

^[[0;32m#### build completed successfully (04:50 (mm:ss)) ####^[[00m

1.1.2 添加AP/BP通信协议文件

AP/BP之间的通信属于进程间通信,高通平台采用QMI通信,是一种基于消息的机制。为了能够正常通信,必须在AP/BP之间指定某种通信协议,改协议使用proto文件规定。

路径:vendor/qcom/proprietary/commonsys-intf/sensors-see/ssc/proto/
文件: sns_lsm6dso.proto

说明:BP侧有相同的proto文件,用于定义AP/BP的通信协议

syntax = "proto2";
import "nanopb.proto";
// lsm6dso sensor register read and write data encoding
enum sns_ois_lsm6dso_msgid { //注意名字不能与其他文件中重复
	option (nanopb_enumopt).long_names = false;
	// message id只要在系统中没有被重复使用即可
	SNS_OIS_LSM6DSO_MSGID_READ_EVENT = 716; //AP侧向BP侧发送读取请求时的message id,BP侧匹配后启动服务
	SNS_OIS_LSM6DSO_MSGID_WRITE_EVENT = 717; //AP侧向BP侧发送写入请求时的message id
}
message sns_ois_lsm6dso_event { //注意名字不能与其他文件中重复
	required bytes ois_lsm6dso_buf =1; //用于BP侧上报时的字段标记(用于手动编码/解码)
}

1.1.3 AP侧再次全编

  1. 与1.1.1执行步骤相同,本次全编为了将sns_lsm6dso.proto文件生成sns_lsm6dso.pb.h,否则后面模块化编译see_lsm6dso_reg_0可执行文件时报错找不到头文件

  2. 生成文件sns_lsm6dso.pb.h路径:两个路径下文件相同
    out/target/product/kona/gen/SHARED_LIBRARIES/libssc_intermediates/proto
    out/target/product/kona/gen/SHARED_LIBRARIES/libsnsapi_intermediates/proto

  3. 如果未编译proto文件,直接进行1.1.3的测试程序编译,会报错,此时必须清除掉生成的相关文件,否则一直编译报错:
    make[3]: * No rule to make target ‘/home/sun/Project/Android10_Project/prebuilts/clang/host/linux-x86/clang-r353983c1/lib64/clang/9.0.3/include/stdint.h’, needed by ‘BasePeCoff.o’. Stop.

    解决方案可参考博客,亲测有效
    https://blog.csdn.net/In_engineer/article/details/120813386

1.1.4 测试程序移植

  1. 移植测试程序源码
    路径:vendor/qcom/proprietary/sensors-see/test/see_lsm6dso_reg/
    文件:Android.mk、see_lsm6dso_reg.cpp

  2. 进入AP侧根目录 sm8250_android_q_aosp/

  3. 执行模块化编译脚本./mmm

#!/bin/bash
source build/envsetup.sh
lunch kona-userdebug
mmm vendor/qcom/proprietary/sensors-see/test/see_lsm6dso_reg/
  1. 测试程序生成路径out/target/product/kona/vendor/bin/see_lsm6dso_reg

1.1.5 测试程序使用方法

当BP侧驱动移植完成之后,可以通过测试程序进行测试,该测试程序目前仅实现读写功能,其他功能类似编写即可。

  1. 将测试程序push进手机
adb root
adb remount
adb push see_lsm6dso_reg ./vendor/bin
adb shell chmod 777 vendor/bin/see_lsm6dso_reg
adb shell ls -al ./vendor/bin/*lsm6dso_reg
pause
  1. 测试程序使用方法
    (1)进入目录/vendor/bin
    (2)执行命令:./see_lsm6dso_reg 0x01 0x22 0x0c回车
    格式说明:
    读取:see_lsm6dso_reg [0x01] [reg_addr] [data_bytes]
    写入:see_lsm6dso_reg [0x00] [reg_addr] [data_bytes] [data_1]…[data_n]

具体功能实现请参考测试程序源码

1.2 BP侧移植

1.2.1 将驱动添加进编译列表

路径: sxr2130_slpi/slpi_proc/ssc/chipset/sm8250/
文件: por.py

#POR sensors list
#将lsm6dso加入编译列表
include_sensor_vendor_libs.extend(['lsm6dso']) 
# 是否需要注册多个sensor,即一套驱动注册多个sensor,如果硬件只连接一个sensor, 必须把该标志注册,
# 否则驱动会加载失败,导致死机
#env.AddUsesFlags(['LSM6DSO_ENABLE_DUAL_SENSOR'])
include_sensor_vendor_libs.extend(['sns_lps22hx', 'sns_sx932x', 'sns_ak0991x','sns_bu52053nvx'])

1.2.2 创建文件目录

(1)在目录slpi_proc/ssc/sensor/下创建文件夹lsm6dso
(2)目录lsm6dso下创建四个文件夹build、hexagon、pb、ois_algo_lib四个文件夹

文件夹作用
build驱动编译文件
pb定义与AP侧通信的协议
hexagon驱动文件
ois_algo_lib用于被编进镜像的算法库

1.2.3 build目录下添加编译文件

路径: slpi_proc/ssc/sensors/lsm6dso/build
文件: sns_lsm6dso.scons

Import('env')
import inspect
env.AddBinaryLibrary(env['SSC_BUILD_TAGS'],
			'${BUILDPATH}/ois_algo_lib/sns_ois_algo_lib', []) //添加二进制lib库
lsm6dso_island_enable = False //默认低功耗模式不使能

if 'SNS_ISLAND_INCLUDE_LSM6DSO' in env:
	lsm6dso_island_enable = True

if 'LSM6DSO_ENABLE_MUL_SENSOR' in env:
	env.Append( CPPDEFINES = ['LSM6DSO_ENABLE_MUL_SENSOR']) //判断是否为双sensor
	lsm6dso_sensor_cnt = 2
else:
	lsm6dso_sensor_cnt = 1
if 'SSC_TARGET_HEXAGON' in env['CPPDEFINES']: //SSC_TARGET_HEXAGON: ssc/build/ssc.scons
	env.AddSSCSU(inspect.getfile(inspect.currentframe()),
		flavor = ["hexagon"],
		register_func_name = "sns_register_lsm6dso", //驱动注册接口,定义在sns_lsm6dso.c中
		binary_lib = False,
		add_island_files = lsm6dso_island_enable,
		registration_cnt = lsm6dso_sensor_cnt)
		//是否启动轮询模式,默认中断模式
		//on-change:中断模式;streaming:轮询模式
		#env.Append(CPPDEFINES = ['CONFIG_SNS_STD_SENSOR_OIS_STREAMING']) 
		#choice on-change or streaming mode

1.2.4 pb目录下添加协议文件

路径: slpi_proc/ssc/sensors/lsm6dso/pb
文件: sns_lsm6dso.proto
说明:AP侧有相同的proto文件,用于定义AP/BP的通信协议

syntax = "proto2";
import "nanopb.proto";
// lsm6dso sensor register read and write data encoding
enum sns_ois_lsm6dso_msgid { //注意名字不能与其他文件中重复
	option (nanopb_enumopt).long_names = false;
	// message id只要在系统中没有被重复使用即可
	SNS_OIS_LSM6DSO_MSGID_READ_EVENT = 716; //AP侧向BP侧发送读取请求时的message id,BP侧匹配后启动服务
	SNS_OIS_LSM6DSO_MSGID_WRITE_EVENT = 717; //AP侧向BP侧发送写入请求时的message id
}
message sns_ois_lsm6dso_event { //注意名字不能与其他文件中重复
	required bytes ois_lsm6dso_buf =1; //用于BP侧上报时的字段标记(用于手动编码/解码)
}

BP侧编译后生成的sns_lsm6dso.pb.h文件,请查看《1.4.3 编译生成的相关文件

1.2.5 hexagon目录下添加驱动文件

路径: slpi_proc/ssc/sensors/lsm6dso/hexagon
文件如下图所示:
在这里插入图片描述

说明:如果需要调用算法库,需要将算法库中设计外部调用接口的头文件加入改目录

1.2.6 ois_algo_lib目录下添加算法库

路径: slpi_proc/ssc/sensors/lsm6dso/ois_algo_lib
文件: sns_ois_algo_lib.lib

将下面《1.3.4 算法库检查》中编译的算法库文件sns_ois_algo_lib.lib放在目录中即可,算法库库的编译请看下面《1.3 算法库移植和编译》详细介绍

1.3 算法库移植和编译

1.3.1 创建算法目录

由于暂时仅仅搭建成功了sdm710中的算法编译环境,因为算法库编译部分在sdm710环境下

  1. 在sdm710/adsp_proc/ssc/sensors目录下创建ois_algo_lib_src
  2. 在ois_algo_lib_src目录下创建build、hexagon目录
文件夹作用
build算法库编译文件
hexagon算法库源文件

1.3.2 添加算法编译文件

  1. 在build目录下添加文件sns_ois_algo_lib.scons文件,内容如下:
// path: sdm710/adsp_proc/ssc/sensors/ois_algo_lib_src/build/sns_ois_algo_lib.scons
Import('env')
import inspect

if 'USES_SSC_STATIC_LIB_BUILDER' in env:
    if 'SSC_TARGET_HEXAGON' in env['CPPDEFINES']:
        env.AddSSCSU(inspect.getfile(inspect.currentframe()),
                flavor = ["hexagon"],
                binary_lib = False,
                add_island_files = True)
  1. 在hexagon目录下添加算法库源文件,在算法中添加log时,需要添加驱动中的头文件

1.3.3 编译算法库

路径: sdm710/adsp_proc/
文件: build.sh

RED='\e[31;1m'
GREEN='\e[32;1m'
YELLOW='\e[33;1m'
BLUE='\e[34;1m'
MAGENTA='\e[35;1m'
CYAN='\e[36;1m'
WHITE='\e[37;1m'
ENDCOLOR='\e[0m'

echo -e "$CYAN ------------- export HEXAGON ------------ $ENDCOLOR"
export HEXAGON_ROOT=$HOME/Qualcomm/HEXAGON_Tools

echo -e "$BLUE ----------- clear generate files -------- $ENDCOLOR"
python build/build.py -c sdm670 -o clean -f aDSP 2>&1 | tee clear_other.log
echo -e "$GREEN ------clear generate files complete ---- $ENDCOLOR"

echo -e "$GREEN ------------- building ADSP ------------ $ENDCOLOR"
python build/build.py -c sdm670 -o all -f aDSP 2>&1 | tee build_adsp.log
echo -e "$GREEN --------- building ADSP complete ------ $ENDCOLOR"

1.3.4 算法库检查

  1. 如果算法库文件生成或者更新,说明编译成功:
    (1)在目录/sdm710/adsp_proc/ssc/sensors/ois_algo_lib_src/build下生成文件sensor_img文件夹
    (2)sensor_img/qdsp6/670.adsp.prod/目录下生成lib库文件sns_ois_algo_lib_island.lib、sns_ois_algo_lib.lib、sns_ois_algo_lib_PROTO.lib
    (3)sensor_img/qdsp6/670.adsp.prod/hexagon目录下为.c文件编译生成的.o文件

  2. 查看算法库内部接口是否可用:
    (1)在算法库同目录下执行命令:nm -sD sns_ois_algo_lib.lib能够显示可被调用的接口

1.4 编译BP侧驱动

1.4.1 编译命令

路径: sxr2130_slpi/slpi_proc/build/ms
脚本: build.sh
命令: ./build.sh

//sxr2130_slpi/slpi_proc/build/ms/build.sh
export HEXAGON_ROOT=/pkg/qct/software/Qualcomm/HEXAGON_Tools
rm build.log
cd `dirname $0`
echo "----- start source ----------"
sleep 5s
echo "-------------------  "
# Call script to setup build environment, if it exists.
if [ -e setenv.sh ]; then
source ./setenv.sh
fi
# Call the main build command
#python build_variant.py $*
python build_variant.py 8250.slpi.prod
build_result=$?
if [ "${build_result}" != "0" ] ; then
    exit ${build_result}
fi

1.4.2 查看编译是否成功

  1. 查看编译log是否报错
  2. 查看镜像文件是否更新,如果时间更新,说明编译成功,并生成镜像文件
    路径:slpi_proc/build/ms/bin/8250.slpi.prod/splitbins/signed
    文件: slpi.b00~slpi.21、slpi.mdt

1.4.3 编译生成的相关文件

  1. AP/BP通信协议文件
    上面《1.2.4 pb目录下添加协议文件》中添加通信协议文件sns_lsm6dso.proto,在BP侧编译完成之后,会生成头文件sns_lsm6dso.pb.h
    路径: /slpi_proc/ssc_api/build/ssc_slpi_user/qdsp6/8250.slpi.prod/pb

    说明: 如果sns_lsm6dso.proto文件未修改,sns_lsm6dso.pb.h文件不会更新

  2. sensor列表文件
    路径: sxr2130_slpi/slpi_proc/ssc/framework/src/
    文件: sns_static_sensors.c
    该文件是slpi_proc/ssc/build/ ssc_static_lib_builder.py文件中
    generate_static_sensor_list()函数根据xxx.scons生成的一个新文件

//驱动注册接口的声明
sns_rc sns_register_suid_sensor(sns_register_cb const *register_api);
sns_rc sns_register_cm(sns_register_cb const *register_api);
sns_rc sns_register_diag_sensor(sns_register_cb const *register_api);
sns_rc sns_register_lsm6dso(sns_register_cb const *register_api);
sns_rc sns_amd_register(sns_register_cb const *register_api);

//sensor 列表
const sns_register_entry sns_register_sensor_list[] =
{
 { sns_register_suid_sensor, 1},
 { sns_register_cm, 1},
 { sns_register_diag_sensor, 1},
 { sns_register_lsm6dso, 1},
 { sns_amd_register, 2}, //2表示注册双sensor
};
const uint32_t sns_register_sensor_list_len = ARR_SIZE(sns_register_sensor_list);

1.5 json文件修改

开机过程中,驱动根据定义json文件名找到对应的json文件,解析数据并赋值对应的变量,进一步完成初始化的相关配置。json文件配置及其重要,配置错误可能会导致无法正常开机。

1.5.1 查看平台信息

  1. 查看hw_platform和soc_id
adb shell "cat /sys/devices/soc0/hw_platform"
adb shell "cat /sys/devices/soc0/soc_id"

1.5.1 json文件重点介绍

再次仅介绍重点配置内容,其他配置可保持不变,详细说明请参考文档《80-p9301-35_b_sensors_execution_environment_(see)_sensors_deep_dive.pdf

//xxx_lsm6dso_0.json
{
	"config":{
		"hw_platform": ["HDK"], //硬件平台代号
		"soc_id": ["356"] //通过adb命令查询
	},
	"lsm6dso_0_platform":{ //项目信息,可修改,与驱动保持一致即可
		"owner": "sns_lsm6dso", //可修改,与驱动保持一致即可
		".config":{
			"owner": "sns_lsm6dso",
			"bus_type":{ "type": "int", "ver": "0",
				"data": "0"
			}, //总线类型,0:i2c;1: spi; 2: i3c
			"bus_instance":{ "type": "int", "ver": "0",
				"data": "4"
			}, //i2c编号,4:i2c_3 + 1
			"slave_config":{ "type": "int", "ver": "0",
				"data": "0x6a"
			}, //i2c 从机地址
			"min_bus_speed_khz":{ "type": "int", "ver": "0",
				"data": "1000"
			}, // i2c 通信速率1M
			"max_bus_speed_khz":{ "type": "int", "ver": "0",
				"data": "1000"
			},// i2c 通信速率1M
			"reg_addr_type":{ "type": "int", "ver": "0",
				"data": "0"
			}, //寄存器地址类型0: 8bit;1: 16bit; 2: 32bit
			"dri_irq_num":{ "type": "int", "ver": "0",
				"data": "64"
			},//中断GPIO口编号
			"irq_pull_type":{ "type": "int", "ver": "0",
				"data": "3"
			},
			"irq_is_chip_pin":{ "type": "int", "ver": "0",
				"data": "1"
			},
			"irq_drive_strength":{ "type": "int", "ver": "0",
				"data": "2"
			},
			"irq_trigger_type":{ "type": "int", "ver": "0",
				"data": "1"
			},
			"num_rail":{ "type": "int", "ver": "0",
				"data": "1"
			},
			"rail_on_state":{ "type": "int", "ver": "0",
				"data": "2"
			},
			"vdd_rail":{ "type": "str", "ver": "0",
				"data": "/pmic/client/sensor_vdd"
			},
			"vddio_rail":{ "type": "str", "ver": "0",
				"data": "/pmic/client/sensor_vddio"
			},
			"rigid_body_type":{ "type": "int", "ver": "0",
				"data": "0"
			}
		},
		".placement":{
			"owner": "sns_lsm6dso",
			"0":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"1":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"2":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"3":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"4":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"5":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"6":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"7":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"8":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"9":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"10":{ "type": "flt", "ver": "0",
				"data": "0.0"
			},
			"11":{ "type": "flt", "ver": "0",
				"data": "0.0"
			}
		}
	},
	"lsm6dso_0_ois":{
		"owner": "sns_lsm6dso",
		".config":{
			"owner": "sns_lsm6dso",
			"is_dri":{ "type": "int", "ver": "0",
			"data": "1"
			},
			"hw_id":{ "type": "int", "ver": "0",
			"data": "0"
			},
			"res_idx":{ "type": "int", "ver": "0",
			"data": "0"
			},
			"sync_stream":{ "type": "int", "ver": "0",
			"data": "0"
			}
		}
	}
}

1.5.2 json文件push进手机

adb wait-for-device
adb root
adb wait-for-device
adb remount
adb wait-for-device

adb shell rm /mnt/vendor/persist/sensors/registry/registry/*
adb shell rm /vendor/etc/sensors/config/xxx_*
adb push xxx_lsm6dso_0.json ./vendor/etc/sensors/config/

adb shell ls /vendor/etc/sensors/config/xxx_*

pause

1.6 刷机验证

  1. push相关json文件,用于解析配置数据

  2. push驱动镜像文件

  3. 重启手机

  4. 通过命令查看是否成功注册lsm6dso,如果能找到对应lsm6dso信息,说明BP侧已经正常注册。
    adb shell "ssc_sensor_info"

  5. 查看当前加载的sensor服务
    adb shell "dumpsys sensorservice"

  6. 通过高通Qtest软件查看是否正常启动和上报AP侧
    使用高通自带APK测试,必须修改libssc.sosensors.ssc.so两个库文件,详细修改方式后续再更新。。。

2. 抖动检测驱动移植

3. OIS防抖功能实现

4. 附录

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值