目录
1. 陀螺仪驱动移植
1.1 AP侧移植
1.1.1 AP侧全编
为了保证AP侧源码的正确性,建议先进行一次AP侧的全编
- 进入AP侧根目录sm8250_android_q_aosp/
- 执行编译脚本./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)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执行步骤相同,本次全编为了将sns_lsm6dso.proto文件生成sns_lsm6dso.pb.h,否则后面模块化编译see_lsm6dso_reg_0可执行文件时报错找不到头文件
-
生成文件sns_lsm6dso.pb.h路径:两个路径下文件相同
out/target/product/kona/gen/SHARED_LIBRARIES/libssc_intermediates/proto
out/target/product/kona/gen/SHARED_LIBRARIES/libsnsapi_intermediates/proto
-
如果未编译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 测试程序移植
-
移植测试程序源码
路径:vendor/qcom/proprietary/sensors-see/test/see_lsm6dso_reg/
文件:Android.mk、see_lsm6dso_reg.cpp -
进入AP侧根目录 sm8250_android_q_aosp/
-
执行模块化编译脚本./mmm
#!/bin/bash
source build/envsetup.sh
lunch kona-userdebug
mmm vendor/qcom/proprietary/sensors-see/test/see_lsm6dso_reg/
- 测试程序生成路径
out/target/product/kona/vendor/bin/see_lsm6dso_reg
1.1.5 测试程序使用方法
当BP侧驱动移植完成之后,可以通过测试程序进行测试,该测试程序目前仅实现读写功能,其他功能类似编写即可。
- 将测试程序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)进入目录/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环境下
- 在sdm710/adsp_proc/ssc/sensors目录下创建ois_algo_lib_src
- 在ois_algo_lib_src目录下创建build、hexagon目录
文件夹 | 作用 |
---|---|
build | 算法库编译文件 |
hexagon | 算法库源文件 |
1.3.2 添加算法编译文件
- 在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)
- 在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)在目录/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文件 -
查看算法库内部接口是否可用:
(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 查看编译是否成功
- 查看编译log是否报错
- 查看镜像文件是否更新,如果时间更新,说明编译成功,并生成镜像文件
路径:slpi_proc/build/ms/bin/8250.slpi.prod/splitbins/signed
文件:slpi.b00~slpi.21、slpi.mdt
1.4.3 编译生成的相关文件
-
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文件不会更新
-
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 查看平台信息
- 查看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 刷机验证
-
push相关json文件,用于解析配置数据
-
push驱动镜像文件
-
重启手机
-
通过命令查看是否成功注册lsm6dso,如果能找到对应lsm6dso信息,说明BP侧已经正常注册。
adb shell "ssc_sensor_info"
-
查看当前加载的sensor服务
adb shell "dumpsys sensorservice"
-
通过高通Qtest软件查看是否正常启动和上报AP侧
使用高通自带APK测试,必须修改libssc.so
和sensors.ssc.so
两个库文件,详细修改方式后续再更新。。。