Openharmony - HDF平台驱动之I2C驱动和测试程序

news/2024/9/8 12:01:02

By: fulinux
E-mail: fulinux@sina.com
Blog: https://blog.csdn.net/fulinus
喜欢的盆友欢迎点赞和订阅!
你的喜欢就是我写作的动力!

在这里插入图片描述

目录

  • 概述
  • I2C平台驱动
  • I2C平台驱动HDF框架
  • I2C平台驱动的使用
    • I2C应用开发
      • 接口说明
      • 代码目录
      • i2ctest.c
      • BUILD.gn
      • bundle.json
      • 修改config.json文件
      • 测试程序导入设备
      • 运行测试

概述

我们鸿蒙3.2设备上连接了sensor,如accel和gyro,是通过i2c总线连接的,在鸿蒙HDF的设备私有信息配置文件如下描述:

vendor/sprd/uis7885/hdf_config/khdf/sensor/accel/qmi8658_config.hcs
sensorBusConfig :: sensorBusInfo {busType = 0; // 0:i2c 1:spibusNum = 2;busAddr = 0x6b;regWidth = 1; // 1byte
}
sensorIdAttr :: sensorIdInfo {chipName = "qmi8658";chipIdRegister = 0x00;chipIdValue = 0x05;
}

即总线是i2c2,从设备的sensor地址是0x6b,chip id的寄存器地址是0x00。chip id值是0x5。
我们先研究下如何通过测试程序来操作I2C,读取这个chip id值。

I2C平台驱动

鸿蒙标准系统中,使用的是Linux内核,这个没有官网上的I2C平台驱动中描述的这样需要编写I2C平台驱动。
使用这个I2C平台驱动文件:drivers/hdf_core/adapter/khdf/linux/platform/i2c/i2c_adapter.c
比如获取对应的I2C adapter:

static int LinuxI2cProbe(struct device *dev, void *data)
{int32_t ret;struct I2cCntlr *cntlr = NULL;struct i2c_adapter *adapter = NULL;(void)data;if (dev == NULL) {HDF_LOGE("%s: dev is null", __func__);return HDF_ERR_INVALID_OBJECT;}   if (dev->type != &i2c_adapter_type) {return HDF_SUCCESS; // continue probe}   HDF_LOGI("%s: Enter", __func__);adapter = to_i2c_adapter(dev); //获取i2c adaptercntlr = (struct I2cCntlr *)OsalMemCalloc(sizeof(*cntlr));if (cntlr == NULL) {HDF_LOGE("%s: malloc cntlr fail!", __func__);i2c_put_adapter(adapter);return HDF_ERR_MALLOC_FAIL;}   cntlr->busId = adapter->nr;cntlr->priv = adapter;cntlr->ops = &g_method;ret = I2cCntlrAdd(cntlr); //这个I2C控制器添加到HDF框架中,后面会在I2cOpen函数中调用I2cCntlrGet函数查找到对应的控制器if (ret != HDF_SUCCESS) {i2c_put_adapter(adapter);OsalMemFree(cntlr);cntlr = NULL;HDF_LOGE("%s: add controller fail:%d", __func__, ret);return ret;}   HDF_LOGI("%s: i2c adapter %d add success", __func__, cntlr->busId);return HDF_SUCCESS;
}

参考:http://docs.openharmony.cn/pages/v3.2/zh-cn/device-dev/guide/device-driver-demo.md/
上面我们提及to_i2c_adapter添加i2c 适配器,然后又将总线ID、适配器和操作方法等通过I2cCntlrAdd添加到HDF驱动框架中,后面在UHDF或KHDF中通过调用I2cOpen函数,间接调用了I2cCntlrGet函数,在HDF框架中找到对应的总线ID、适配器和操作方法等,然后就可以操作I2C总线了。
I2cCntlrAdd函数:

//drivers/hdf_core/framework/support/platform/src/i2c/i2c_core.c
int32_t I2cCntlrAdd(struct I2cCntlr *cntlr)
{int32_t ret;if (cntlr == NULL) {return HDF_ERR_INVALID_OBJECT;}   if (cntlr->ops == NULL) {HDF_LOGE("I2cCntlrAdd: no ops supplied!");return HDF_ERR_INVALID_OBJECT;}   if (cntlr->lockOps == NULL) {HDF_LOGI("I2cCntlrAdd: use default lock methods!");cntlr->lockOps = &g_i2cLockOpsDefault;}   if (OsalMutexInit(&cntlr->lock) != HDF_SUCCESS) {HDF_LOGE("I2cCntlrAdd: init lock fail!");return HDF_FAILURE;}   ret = I2cManagerAddCntlr(cntlr);if (ret != HDF_SUCCESS) {(void)OsalMutexDestroy(&cntlr->lock);return ret;}   return HDF_SUCCESS;
}

I2cOpen函数:

DevHandle I2cOpen(int16_t number)
{return (DevHandle)I2cCntlrGet(number);
}

I2cCntlrGet函数:

/** Find an i2c controller by bus number, without ref count*/
static struct I2cCntlr *I2cManagerFindCntlr(int16_t number)
{struct I2cCntlr *cntlr = NULL;struct I2cManager *manager = g_i2cManager;if (number < 0 || number >= I2C_BUS_MAX) {HDF_LOGE("I2cManagerFindCntlr: invalid busId:%hd!", number);return NULL;}if (manager == NULL) {HDF_LOGE("I2cManagerFindCntlr: get i2c manager fail!");return NULL;}if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {HDF_LOGE("I2cManagerFindCntlr: lock i2c manager fail!");return NULL;}cntlr = manager->cntlrs[number];(void)OsalMutexUnlock(&manager->lock);return cntlr;
}/** Find and return an i2c controller by number, with ref count*/
struct I2cCntlr *I2cCntlrGet(int16_t number)
{return I2cManagerFindCntlr(number);
}

在drivers/hdf_core/framework/support/platform/src/i2c/i2c_core.c文件中,主要就是实现这个上述这些功能

I2C平台驱动HDF框架

I2C平台驱动既可以为其他HDF驱动提供接口,比如挂接在I2C总线上的sensor驱动,也可以为用户空间提供通用的操作接口。这些接口都是这些:I2cOpen(),I2cClose(),I2cTransfer()。所以可以在drivers/hdf_core/framework/support/platform/src/i2c/中看到有这两个文件:

drivers/hdf_core/framework/support/platform/src/i2c/i2c_if.c
drivers/hdf_core/framework/support/platform/src/i2c/i2c_if_u.c

其中i2c_if.c就是对其他HDF驱动提供接口的:

#include "i2c_if.h"
#include "devsvc_manager_clnt.h"
#include "hdf_base.h"
#include "hdf_log.h"
#include "i2c_core.h"
#include "osal_mem.h"
#include "securec.h"#define HDF_LOG_TAG i2c_if#define I2C_SERVICE_NAME "HDF_PLATFORM_I2C_MANAGER"DevHandle I2cOpen(int16_t number)
{return (DevHandle)I2cCntlrGet(number);
}void I2cClose(DevHandle handle)
{if (handle != NULL) {I2cCntlrPut((struct I2cCntlr *)handle);}
}int32_t I2cTransfer(DevHandle handle, struct I2cMsg *msgs, int16_t count)
{if (handle == NULL) {return HDF_ERR_INVALID_OBJECT;}if (msgs == NULL || count <= 0) {HDF_LOGE("I2cTransfer: err params! msgs:%s, count:%hd",(msgs == NULL) ? "0" : "x", count);return HDF_ERR_INVALID_PARAM;}return I2cCntlrTransfer((struct I2cCntlr *)handle, msgs, count);
}

其中i2c_if_u.c就是对用户空间提供通用的操作接口:

#include "hdf_base.h"
#include "hdf_io_service_if.h"
#include "hdf_log.h"
#include "i2c_if.h"
#include "i2c_service.h"

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

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

相关文章

住宅IP的优势和选择指南:为何跨境卖家需要静态住宅IP?

大家都知道代理IP这个概念&#xff0c;但其实代理IP有很多种类型&#xff0c;而住宅IP便是其中一种应用广泛的类型。在当今数字化商业环境中&#xff0c;尤其是在跨境电商行业&#xff0c;住宅IP的作用日益凸显&#xff0c;今天&#xff0c;我们要重点讲解的是住宅IP&#xff0…

【Flink数据传输(一)】NetworkStack架构概述:实现tm之间的数据交换

文章目录 1. NetworkStack整体架构2. StreamTask内数据流转过程 NetworkStack提供了高效的网络I/O和反压控制 除了各个组件之间进行RPC通信之外&#xff0c;在Flink集群中TaskManager和TaskManager节点之间也会发生数据交换&#xff0c;尤其当用户提交的作业涉及Task实例运行在…

《高质量的C/C++编程规范》学习

目录 一、编程规范基础知识 1、头文件 2、程序的板式风格 3、命名规则 二、表达式和基本语句 1、运算符的优先级 2、复合表达式 3、if语句 4、循环语句的效率 5、for循环语句 6、switch语句 三、常量 1、#define和const比较 2、常量定义规则 四、函数设计 1、参…

SpringBoot项目实现文件上传,MINIO+OSS阿里云

MINIO 安装以及部署 官网&#xff1a;MinIO | Code and downloads to create high performance object storage 下载后是一个minio.exe的文件&#xff0c;可以先创一个文件夹来存放数据以及文件 在文件的目录下cmd进入控制台 minio.exe server data 启动成功后控制台会打印账…

【Android】坐标系

Android 系统中有两种坐标系&#xff0c;分别为 Android 坐标系和 View 坐标系。了解这两种坐标系能够帮助我们实现 View 的各种操作&#xff0c;比如我们要实现 View 的滑动&#xff0c;你连这个 View 的位置都不知道&#xff0c;那如何去操作呢&#xff1f; 一、Android 坐标…

机器学习——线性代数中矩阵和向量的基本介绍

矩阵和向量的基本概念 矩阵的基本概念&#xff08;这里不多说&#xff0c;应该都知道&#xff09; 而向量就是一个特殊的矩阵&#xff0c;即向量只有一列&#xff0c;是个n*1的矩阵 注&#xff1a;一般矩阵用大写字母表示&#xff0c;向量用小写字母表示 矩阵的加减运算 两个…