news 2026/2/28 5:58:11

展锐ums9620e 平台软陀螺调试总结

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
展锐ums9620e 平台软陀螺调试总结

1, 整合软陀螺和地磁驱动

之前提供的驱动软陀螺驱动接口是和地磁驱动接口分开,相当于地磁和驱动完全是独立的。HUB的驱动路径下创建一个virtual_gyro 的驱动,分别又virtual_common.c 和 mag_acc_common.c 和.h 文件构成, mag_acc_common.c实现地磁和加速度enable,disable,get_data 接口,然后在virtual_gyro_common.c中的实现软陀螺接口。下面是软陀螺接口一些实现,例如virtual_gyro_enable()会调用enable_mag,enable_acc接口,virtual_gyro_disable()会调用disable_mag,disable_acc接口,同理virtual_gyro_get_data接口会调用get_mag_data()和get_acc_data() 接口。这种方式不仅浪费了sensorhub 空间还会造成接口冗余。

static int virtual_gyro_sensor_enable() { if (!acc_lsm6dsl_enable()&& !mag_enable()) { SENSORHUB_TRACE("virtual gyro enable"); enable_state[DRV_GYROSCOPE] = 1; return NO_ERROR; } else SENSORHUB_TRACE("virtual gyro enable fail"); } static int virtual_gyro_sensor_disable() { if (!enable_state[DRV_ACCELEROMETER]) // acc_lsm6dsl_disable(); if (!enable_state[DRV_MAGNETIC_FIELD]) mag_disable(); enable_state[DRV_GYROSCOPE] = 0; SENSORHUB_TRACE("virtual gyro disable sensor successed!\n"); return NO_ERROR; } static int virtual_gyro_sensor_get_data(struct sensor_data *sensor_data, uint64_t timestamp) { struct sensor_data acc_sensor_data; struct sensor_data mag_sensor_data; static struct sensor_event sensor_event_data; acc_lsm6dsl_read_data(&acc_sensor_data); memcpy(&sensor_event_data.data[0], &acc_sensor_data.data[0], sizeof(float) * 3); mag_read_data(&mag_sensor_data); memcpy(&sensor_event_data.data[3], &mag_sensor_data.uncali_data[0], sizeof(float) * 3); SENSORHUB_TRACE("virtual gyro raw data = %f, %f, %f, %f, %f, %f", sensor_event_data.data[0], sensor_event_data.data[1], sensor_event_data.data[2], sensor_event_data.data[3], sensor_event_data.data[4], sensor_event_data.data[5]); sensor_event_data.sensor_handle = GYROSCOPE; sensor_event_data.timestamp = timestamp; sensor_process_base_sensor_data(&sensor_event_data); return NO_ERROR; }

ums9620e 平台对接口进行升级,平台给virtual_gyro定义了一个公共的结构体,这个结构体的内容是mag 和acc 的接口和flag, vendor 开发商直接在mag驱动mag_init 和 acc驱动acc_init 分别给mag和acc 接口赋值即可,而在virtual_gyro_common.c 分别回调初始化的接口。

struct virtual_gyro_driver_func { void *mag_enable(), void *mag_disable(), void *mag_read_data(struct sensor_data *sensor_data, uint64_t timestamp), uint8_t mag_init_flag, void *acc_enable(), void *acc_disable(), void *acc_read_data(struct sensor_data *sensor_data, uint64_t timestamp), };

升级后的virtual_gyro_common.c 接口实现

tatic int virtual_gyro_sensor_enable() { if((!virtual_gyro_driver_func.acc_enable) || (!virtual_gyro_driver_func.mag_enable)) { SENSORHUB_TRACE("acc or mag enable is NULL"); return FAIL; } virtual_gyro_driver_func.acc_enable(); virtual_gyro_driver_func.mag_enable(); enable_state[DRV_GYROSCOPE] = 1; SENSORHUB_TRACE("virtual gyro enable"); return NO_ERROR; } static int virtual_gyro_sensor_disable() { if((!virtual_gyro_driver_func.acc_disable) || (!virtual_gyro_driver_func.mag_disable)) { SENSORHUB_TRACE("acc or mag disable is NULL"); return FAIL; } if (!enable_state[DRV_ACCELEROMETER]) virtual_gyro_driver_func.acc_disable(); if (!enable_state[DRV_MAGNETIC_FIELD]) virtual_gyro_driver_func.mag_disable(); enable_state[DRV_GYROSCOPE] = 0; SENSORHUB_TRACE("virtual gyro disable sensor successed!\n"); return NO_ERROR; } static int virtual_gyro_sensor_get_data(struct sensor_data *sensor_data, uint64_t timestamp) { struct sensor_data acc_sensor_data; struct sensor_data mag_sensor_data; static struct sensor_event sensor_event_data; if ((!virtual_gyro_driver_func.acc_read_data) || (!virtual_gyro_driver_func.mag_read_data)) { SENSORHUB_TRACE("acc or mag read data is NULL"); return FAIL; } virtual_gyro_driver_func.acc_read_data(&acc_sensor_data, timestamp); memcpy(&sensor_event_data.data[0], &acc_sensor_data.data[0], sizeof(float) * 3); mag_af6133e_read_data( &mag_sensor_data, timestamp); memcpy(&sensor_event_data.data[3], mag_gyro_data_af6133e, sizeof(float) * 3); if (mag_vendor_och_flag) { mag_och_read_data( &mag_sensor_data, timestamp); memcpy(&sensor_event_data.data[3], mag_gyro_data_och sizeof(float) * 3); } SENSORHUB_TRACE("ja virtual gyro raw data = %f, %f, %f, %f, %f, %f\n", sensor_event_data.data[0], sensor_event_data.data[1], sensor_event_data.data[2], sensor_event_data.data[3], sensor_event_data.data[4], sensor_event_data.data[5]); sensor_event_data.sensor_handle = GYROSCOPE; sensor_event_data.timestamp = timestamp; sensor_process_base_sensor_data(&sensor_event_data); return NO_ERROR; }

2, 算法库移植

主要是软陀螺算法包包括算法库计算软陀螺数据,vendor/sprd/modules/sensors/libsensorhub/路径下,主要是定义一软陀螺算法接口,还有lib 算法库编译相关的andriod.bp 文件。

3, 调试过程遇到的问题

算法库编译完成后,刷机到手机,手机会死机,抓dmesg log 一直报下面的错误:

根据error log 大概意思:sensors.unisoc.so 这个库会关联到libOcsAlgo.so, 但是在odm/lib64 下面没有找到这个库。

后面通过在代码路径out 下面搜索libOcsAlgo .so 是可以搜到路径是vendor/lib64 下面,而其他家的mag 库路径是odm/lib64 下面,这个是出问题的地方

后面通过对比库编译的Andriod.bp 文件发现,友商的是左边,有问题的是右边,进一步查找这个属性,看到这个是一个定义分区的宏所以这个是问题的rootcause。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/27 13:30:05

vivado除法器ip核与其他IP协同工作的项目应用

Vivado除法器IP核实战:如何打造高效数据处理流水线在FPGA设计中,我们常常遇到这样一个问题:ADC采样回来的数据要实时归一化,但CPU做除法太慢,系统响应就跟不上。比如一个工业传感器系统,每秒采集百万级样本…

作者头像 李华
网站建设 2026/2/28 16:57:31

基于STM32单片机的智能窗帘/晾衣架控制系统 红外遥控 雨滴感应 成品套件 DIY设计 实物+源程序+原理图+仿真+其它资料(777)

本人从事毕业论文设计辅导10余载,撰写的毕业论文超2000余篇,为广大的应届毕业生节省了大量的设计和撰写时间。在单片机领域,参与设计51系列、STM32系列、Proteus仿真、JAVA上位机、Android Studio、物联网无线通信等千余套项目,具…

作者头像 李华
网站建设 2026/2/27 12:41:30

抖音无水印下载终极指南:3种完整方法轻松保存高清视频

想要永久保存抖音上的精彩视频,却苦于平台自带的水印影响观看体验?douyin_downloader正是你需要的专业解决方案。这款开源工具支持多种方式获取抖音原始视频,完美避开平台水印,让你的收藏保持最佳画质。 【免费下载链接】douyin_d…

作者头像 李华
网站建设 2026/2/24 11:46:10

JoyCon-Driver终极配置手册:5分钟解锁PC游戏新体验

还在为PC游戏找不到理想手柄而苦恼吗?JoyCon-Driver让你闲置的Switch手柄在PC上重获新生!这款免费开源工具通过vJoy虚拟控制器完美模拟摇杆输入,支持陀螺仪精准控制,彻底解决游戏手柄兼容性问题。 【免费下载链接】JoyCon-Driver …

作者头像 李华
网站建设 2026/2/26 4:39:21

网络资源嗅探利器:从零开始掌握代理配置与资源下载

网络资源嗅探利器:从零开始掌握代理配置与资源下载 【免费下载链接】res-downloader 资源下载器、网络资源嗅探,支持微信视频号下载、网页抖音无水印下载、网页快手无水印视频下载、酷狗音乐下载等网络资源拦截下载! 项目地址: https://gitcode.com/Gi…

作者头像 李华
网站建设 2026/2/24 18:51:25

anything-llm的Docker镜像有多大?部署资源需求说明

Anything LLM 的 Docker 镜像有多大?部署资源需求全解析 在个人知识库和企业级AI助手日益普及的今天,如何快速、稳定地部署一个功能完整的大语言模型(LLM)应用,成为开发者和系统管理员关注的核心问题。市面上不乏各类本…

作者头像 李华