rtt设备驱动框架面向对象学习-i2c总线

本来想着i2c和spi是一样的,标题都想抄袭成《rtt设备驱动框架学习-i2c总线和设备》,然后看过源码发现,i2c没有分开总线和设备,我想着正常它和spi一样有总线和设备,设备存在竞争。估计是因为i2c设备可以通过i2c地址区分,所以不需要来个i2c设备了吧。

1.i2c总线

i2c总线分为硬件i2c总线和软件模拟i2c总线。
按照面向对象的思想,要抽象出硬件i2c总线和软件i2c总线的相同点和不同点。相同点就变成了i2c总线基类,不同点就是各个子类的私有特性。

rtt就是这么干的,共同点是什么?方法——都得有配置方法和数据传输方法等,于是抽象出了i2c的方法:
struct rt_i2c_bus_device_ops
{
rt_ssize_t (*master_xfer)(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num);
rt_ssize_t (*slave_xfer)(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num);
rt_err_t (*i2c_bus_control)(struct rt_i2c_bus_device *bus, int cmd, void *args);};

抽象出3个公共方法,主设备通信接口,从设备通信接口和控制方法。

然后作为成员组成rt_i2c_bus_device类:
i2c.h中
struct rt_i2c_bus_device
{
struct rt_device parent;
const struct rt_i2c_bus_device_ops *ops; rt_uint16_t flags;
struct rt_mutex lock;
rt_uint32_t timeout;
rt_uint32_t retries;
void *priv;
};

缺图对象图,ops展开方法用纯虚方法表示或者指针,但ops展开后成为一个个纯虚方法更为贴切。

1.1硬件i2c

对于硬件i2c子类,则通过调用硬件sdk来实现rt_spi_bus的ops操作方法,实现完美闭环。

缺图对象图,ops展开的一个个方法用虚方法表示或者普通方法即可,意味着重写父类方法。

1.2 软件i2c总线

对于软件i2c总线,共同点就是软件gpio也要实现上面3个公共方法,差异点就是要用gpio模拟硬件i2c的2线通信接口——抽象出软件i2c通信接口。因为i2c通信时序是共同的,如果放到驱动层,每个bsp都要实现一样逻辑的通信函数——重复造轮子——对于这种“重复”性的,就抽象出来放到上层最合理。——就此我也知道了在c++中什么时候需要虚函数/纯虚函数那要看下层有没有共性的东西。

至于i2c软总线通信接口的实现需要哪些信息,rtt抽象出来的如下:
i2c-bit-ops.h 中
struct rt_i2c_bit_ops
{
void data; / private data for lowlevel routines */
void (*set_sda)(void *data, rt_int32_t state); void (*set_scl)(void *data, rt_int32_t state); rt_int32_t (*get_sda)(void *data);
rt_int32_t (*get_scl)(void *data);
void (udelay)(rt_uint32_t us);
rt_uint32_t delay_us; /
scl and sda line delay / rt_uint32_t timeout; / in tick */
};

为何如此抽象?i2c通信就用到2线,所以只要提供操作2线的高低电平接口即可控制通信了,其时序是共通的,再加上延时即可完成硬件无关的i2c通信时序,所以差异点在于操作硬件高低电平的函数,延时函数等的实现不同,于是把它们抽象出来。

模拟通信接口的方法在i2c-bit-ops.c中,从该c中可以看到它只提供了i2c主设备通信,其他两个i2c公共方法(从设备通信和控制方法)均没有支持。待开发。另外在i2c-bit-ops.c中可以看到i2c通信硬件无关的时序接口,要真正驱动引脚还得实现struct rt_i2c_bit_ops的接口。

为何还要抽象出来?同样的下面还有个子类——具体硬件厂家的软件i2c总线——因为各个硬件操作gpio具体实现是不同的,但是这些方法是都一样,所以抽象出来——跨硬件平台,这个框架才叫框架,这个框架才有意义。

rtt的h文件中没有关于抽象出的i2c软总线类,不过可以参考它的soft_i2c.c中抽象出i2c软总线类:

struct rt_soft_i2c
{
struct rt_i2c_bus_device i2c_bus;
struct rt_i2c_bit_ops ops;
};
就是继承i2c总线类后+软件i2c通信接口方法。

soft_i2c.c中的实现自洽的,啥叫自洽?就是它用到了pin设备,如果该bsp实现了pin框架对接,那么soft_i2c.c就完成了整个的软件i2c配置,只需要开启宏和定义下软件i2c引脚就行了,不需要bsp再进行创建软件i2c总线设备了。不过也可以,只要名字不一样也可以,不过结果一样,以我看来有pin对接就不要在bsp层重复实现了。

如果没有实现pin设备框架对接,那么就需要bsp驱动层实现软总线,各个厂家bsp创建各自的软i2c总线子类对象,实现软件i2c的ops方法即可。

缺图对象图,
(1)bus—>ops展开的一个个方法用虚方法表示或者普通方法即可,意味着重写父类i2c总线基类的方法。
(2)软i2c总线子类的ops展开的一个个方法用纯虚方法表示或者指针,但ops展开后成为一个个纯虚方法更为贴切。

/ components / drivers / i2c下有4个文件:
i2c-bit-ops.c
i2c_core.c
i2c_dev.c
soft_i2c.c
这4个文件的关系:
i2c_dev.c是重写/实现rt_device基类的方法的文件,也是初始化i2c基类的接口所在rt_i2c_bus_device_device_init。

i2c_core.c是中转站/中间人,因为i2c_dev.c中重写设备基类的方法,这些方法里调用了i2c_core.c提供的方法如rt_i2c_transfer,而i2c_core.c中这些方法比如 rt_i2c_transfer,实现内部是调用的i2c的3个公共方法比如bus->ops->master_xfer,而这3个公共方法对于硬件i2c总线则走硬件总线的实现,对于软件模拟i2c总线则走i2c-bit-ops.c中的方法比如i2c_bit_xfer,前面知道i2c-bit-ops.c中只实现了主设备通信即只有i2c_bit_xfer。以此来看,i2c_core.c可不就是中间人/岔路口/分发站/跳转点么?!
而i2c_bit_xfer函数里使用到i2c软总线抽象的那些延时2线高低电平接口,而这些接口可以是bsp的驱动层实现的,也可以是soft_i2c.c里实现的——通过pin设备框架控制2线高低电平(当然还需要实现us延时函数)。

而soft_i2c.c是对于支持pin设备的bsp的软总线实现实例,它已自洽的,不需要bsp再重复造轮子了。而它则可以作为参照对于没有支持pin和延时函数的bsp实现软总线的参考例子。它通过pin设备实现了软i2c总线的模拟接口,这样i2c-bit-ops.c中通信方法调用2线控制电平和延迟函数就有了落脚点。而pin设备就需要驱动层的gpio驱动支持的,gpio驱动就调用了硬件sdk,自然能驱动硬件引脚。这样屏蔽了硬件差异,实现跨硬件平台。

2.i2c设备

无。通过i2c从机地址就能区分i2c设备,就没有必要专门搞个设备累了,多余了。

3.使用

官方文档说的就是如何使用的i2c总线,而上面学的是注册/初始化/构造流程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java玩转《啊哈算法》解密回文之栈

菩萨清凉月,常游毕竟空,众生心垢净,菩提影现中。 这目录 这开头这代码地址栈案例代码优化建议类似扩展 这开头 各位女士们,先生们好!本人最近在看《啊哈算法》,这本书写的确实还可以,很有趣味性…

IEC 104电力规约详细解读(三) - 遥信

1.功能简述 遥信,、即状态量,是为了将断路器、隔离开关、中央信号等位置信号上送到监控后台的信息。遥信信息包括:反应电网运行拓扑方式的位置信息。如断路器状态、隔离开关状态;反应一次二次设备工作状况的运行信息,如…

containerd中文翻译系列(九)主机

注册表配置 - 简介 containerd v1.5 为 ctr 客户端(用于管理员/开发人员的 containerd 工具)、containerd 镜像服务客户端和 CRI 客户端如kubectl和 crictl,提供了新的额外注册表主机配置支持。 为这些客户端配置注册表的方法是&#xff0c…

Leetcode刷题-(11~15)-Java+Python+JavaScript

算法是程序员的基本功,也是各个大厂必考察的重点,让我们一起坚持写算法题吧 遇事不决,可问春风,春风不语,即是本心。 我们在我们能力范围内,做好我们该做的事,然后相信一切都事最好的安排就可…

jvm内存分区的变化

随着 JDK 版本的变化,JVM 内存分区方面有一些变化和调整。以下是主要的一些变化: JDK 8 之前: 在 JDK 8 之前,HotSpot 虚拟机主要使用的是永久代(Permanent Generation)和堆内存(Heap Memory&…

考研数据结构笔记(3)

顺序表存储结构 存储结构顺序结构定义基本操作的实现静态分配问题 动态分配代码功能 顺序表的特点: 顺序表小结顺序表的插入删除插入删除小结 顺序表的查找按位查找按值查找小结 存储结构 顺序结构 定义 线性表是具有相同数据类型的n(n>0)个数据元素的有限序列(每个数据元素…

JavaScript流程控制详解之循环结构(倒三角、九九乘法表)

循环结构 在JavaScript中,循环语句指的是在满足某个条件下重复执行 指定的一段代码。若条件结果为true,则重复执行,则进入循环,否则结束循环。 在JavaScript中,循环语句如下: while语句do…while语句for语句 while…

shell脚本基础语法(.sh ./ sh bash source shell)

Linux 之 Shell 脚本基础语法 0. 学习一门语言的顺序 1. Shell 编程概述 1.1 Shell 名词解释 在 Linux 操作系统中,Shell 是一个命令行解释器,它为用户提供了一个与操作系统内核交互的界面。用户可以通过 Shell 输入命令,然后 Shell 将这些…

SpringBoot+Slf4j+Logback日志记录方案

目录 依赖 配置 实现 简单介绍下几大日志框架之间的关系 Log4j:这是最早的日志框架之一。 Logback:这是log4j的升级版。 Log4j2:最新推出的日志框架。 Slf4j:日志门面,为各种日志框架提供统一的记录日志的接口。…

ONLYOFFICE 文档开发者版 8.0:API和文档生成器更新

随着 8.0 版新功能的发布,我们更新了编辑器、文档生成器和插件的 API。请阅读本文了解详情。 PDF 支持 我们在 documentType 参数中添加了 pdf 文档这一类型。现在完全支持PDF文件*,包括含有可填写字段的文件,并且可以在ONLYOFFICE PDF 编辑…

编程笔记 html5cssjs 080 JavaScript 跳转语句

编程笔记 html5&css&js 080 JavaScript 跳转语句 1. break 语句2. continue 语句3. return 语句注意 在JavaScript中,跳转语句用于改变程序执行流程的顺序. 1. break 语句 break 语句用来强制退出当前循环(如 for、while 或 do...while 循环&am…

深入了解Spring Expression Language(SpEL)

深入了解Spring Expression Language(SpEL) Spring Expression Language(SpEL)是Spring框架中强大的表达式语言,它在运行时提供了一种灵活的方式来评估字符串表达式。SpEL的设计目标是在各种Spring配置和编程场景中提供…

亚马逊AWS考试认证系列 - Retake是考试的坚强后盾

为什么说Retake是考试的坚强后盾? 在AWS的认证考试体系里面,Retake 是一次重考的机会,允许考生在第一次未通过考试的情况下,再次免费参加考试,注意是免费的。这为考生提供了一个机会来重新准备并且免费再次进行考试。…

C++ “万能血“ void*指针

本篇文章我们来介绍一下C “万能血” void指针 为什么说他万能呢? 原因:C void* 是一种特殊的指针类型,可用于存放任意对象的地址。在函数传参中也可以作为任何实参的形参 void型详细介绍 void* 是C中的一种特殊的指针类型,被称为"无类…

【数据库】Unlogged 表使用

【数据库】Unlogged 表使用 前言普通表和Unlogged 表的写性能比较普通表创建和数据插入Unlogged 表创建和数据插入比较结果 Unlogged 表崩溃和正常关闭测试Unlogged 表特点总结 前言 大神偶像在开会上提及了Unlogged 表,它的特点很不错,很适合实时数据保…

关于域名递归解析服务的问题

域名递归解析服务是互联网基础设施的重要组成部分,它允许用户通过域名来访问网站或应用程序。然而,在某些情况下,域名递归解析服务可能会出现问题,导致用户无法正常访问网站或应用程序。本文将探讨域名递归解析服务可能面临的问题…

elementPlus实现动态表格单元格合并span-method方法总结

最近在做PC端需求的时候,需要把首列中相邻的同名称单元格合并。 我看了一下elementPlus官网中的table表格,span-method可以实现单元格合并。 我们先看一下官网的例子: 合并行或列 多行或多列共用一个数据时,可以合并行或列。 …

【附代码】NumPy加速库NumExpr(大数据)

文章目录 相关文献测试电脑配置数组加减乘除数组乘方Pandas加减乘除总结 作者:小猪快跑 基础数学&计算数学,从事优化领域5年,主要研究方向:MIP求解器、整数规划、随机规划、智能优化算法 如有错误,欢迎指正。如有…

Java 学习和实践笔记(2)

今天的学习进度: 注册并下载安装好了Java 8,之后进行以下配置。 1)path 是一个常见的环境变量,它告诉系统除了在当前的目标下妹寻找此程序外,还可以到path指定的目录下找。 2)Java Home 为以后其他的软…

C程序设计(第5版)谭浩强习题解答 第8章 善于利用指针

C程序设计(第5版)谭浩强习题解答 第8章 善于利用指针 1. 输入3个整数&#xff0c;要求按由小到大的顺序输出。 #include <stdio.h> int main() {void swap(int *p1, int *p2);int n1, n2, n3;int *p1, *p2, *p3;printf("input three integer n1,n2,n3:");sc…