rtt设备驱动框架学习-spi总线和设备

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

rtt就是这么干的,共同点是什么?方法——都得有spi配置方法和数据传输方法等,于是抽象出了rt_spi_bus类。
struct rt_spi_bus
{ struct rt_device parent; rt_uint8_t mode; const struct rt_spi_ops *ops; struct rt_mutex lock; struct rt_spi_device *owner;};

对于硬件spi子类,则负责实现rt_spi_bus的ops操作方法。

对于软件spi,差异点就是要用gpio模拟硬件spi的4线或3线通信,那么软件gpio除了实现上面共同点ops操作方法外,还得抽象软件spi通信。
于是抽象出spi软总线基类——rt_spi_bit_obj。
struct rt_spi_bit_obj
{ struct rt_spi_bus bus; struct rt_spi_bit_ops *ops; struct rt_spi_configuration config;};

因为有共同点所以得继承rt_spi_bus基类,它的差异点抽象出了rt_spi_bit_ops操作方法实现gpio模拟spi通信。

struct rt_spi_bit_ops
{ void data; / private data for lowlevel routines */ void (*const tog_sclk)(void *data); void (*const set_sclk)(void *data, rt_int32_t state); void (*const set_mosi)(void *data, rt_int32_t state); void (*const set_miso)(void *data, rt_int32_t state); rt_int32_t (*const get_sclk)(void *data); rt_int32_t (*const get_mosi)(void *data); rt_int32_t (*const get_miso)(void *data); void (*const dir_mosi)(void *data, rt_int32_t state); void (*const dir_miso)(void *data, rt_int32_t state); void (const udelay)(rt_uint32_t us); rt_uint32_t delay_us; / sclk, mosi and miso line delay */};

这个抽象出的方法作为软件spi总线类rt_spi_bit_obj的成员,为何还要抽象出来?因为下面还有个子类——具体硬件厂家的软件spi总线——因为各个硬件操作gpio具体实现是不同的,但是这些方法是都一样,所以抽象出来——跨硬件平台,这个框架才叫框架,这个框架才有意义。
接着就是硬件spi软总线层次了,各个厂家bsp创建各自的软spi总线子类对象,实现软件spi基类的ops方法。

2.spi设备
上面spi总线基类里有个“struct rt_spi_device *owner”,这是spi设备对象指针,为何在spi总线里加个spi设备的指针成员,且还叫owner(字面意思:spi总线持有者或霸占者或拥有者)?
用面向对象的思想来分析下,spi总线和spi设备是啥关系?可以搜下面向对象思想中对象关系有哪些,有包含(拥有)关系,聚合关系,关联关系等等。而spi总线和spi设备就是关联关系吧。谁关联谁?我觉得是互相关联吧。你看,它们的关系特点:一个spi总线上可以挂载很多个spi设备,同一时刻,一个spi总线只能和一个spi设备通信,这样看来同一个spi总线上的spi设备是分时共享这个spi总线的,spi设备之间是有竞争关系的,spi总线就相当于共享资源,同一时刻只能有一个spi设备霸占。所以上面抽象出的spi总线基类里有一个owner标志,表示当前是哪个spi设备在使用/霸占/持有spi总线。
那么同样的,spi设备里肯定也有一个指针指向它挂载到那个spi总线上了——因为它们是关联关系。
于是看下rtt抽象出的spi设备类rt_spi_device定义:
struct rt_spi_device
{ struct rt_device parent; struct rt_spi_bus *bus; struct rt_spi_configuration config; rt_base_t cs_pin; void *user_data;};

果然不出所料,有个spi总线基类指针来表明该spi设备挂载到哪个spi总线上了。

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

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

相关文章

理解new BigDecimal(double)和BingDecinal.valueOf(double)的区别

在Java中,BigDecimal类常用于精确的小数运算,尤其是在需要高精度计算的金融领域。使用BigDecimal时,创建其实例的方式对最终结果的准确性有重要影响。new BigDecimal(double)和BigDecimal.valueOf(double)是创建BigDecimal对象的两种常用方法…

【2024.2.5练习】砍竹子(25分)

题目描述 题目分析 考虑题目是否满足贪心。每次施展魔法会使一段连续的竹子高度变为一半左右的平方根。根据样例,似乎每次让最高的竹子变短就能得到最优解。 假设魔法一次只能对一根竹子使用,永远不出现连续相同高度的竹子,那么显然无论使用…

电商开放API商品采集接口、关键字搜索接口,获取商品ID、商品主图接口

API是application programming interface(应用程序接口)的简称,是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。…

笔记---贪心---哈夫曼Huffman树

AcWing.148.合并果子 在一个果园里,达达已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。 达达决定把所有的果子合成一堆。 每一次合并,达达可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。 可以…

Parse Error: Invalid header token 的可能性及解决情况

项目场景: 背景: 使用接口测试工具时,请求失败,出现以下错误信息: Parse Error: Invalid header token 问题描述 问题: 使用接口测试工具时,请求失败,出现以下错误信息&#xff…

Oracle Vagrant Box 扩展根文件系统

需求 默认的Oracle Database 19c Vagrant Box的磁盘为34GB。 最近在做数据库升级实验,加之导入AWR dump数据,导致空间不够。 因此需要对磁盘进行扩容。 扩容方法1:预先扩容 此方法参考文档Vagrant, how to specify the disk size?。 指…

Linux Shell编程系列--变量的定义与使用

一、目的 上一篇我们简单介绍了shell脚本的组成以及如何运行一个shell脚本,本篇将详解讲解shell中的变量。在Shell脚本中,变量是用来存储和处理数据的基本结构。 二、介绍 1、定义变量 变量名与等号()后跟值来定义一个变量&#…

Matlab之操作CSV表格

一、读取csv文件 参数1:csv路径; 参数2:从第几行开始读取,行数从0开始; 参数3:从第几列开始读取,列数从0开始。 ConfigData csvread(ConfigFile,0,1);%读取配置文件 disp(读取CSV文件成功&…

考研数据结构笔记(1)

数据结构(1) 数据结构在学什么?数据结构的基本概念基本概念三要素逻辑结构集合线性结构树形结构图结构 物理结构(存储结构)顺序存储链式存储索引存储散列存储重点 数据的运算 算法的基本概念什么是算法算法的五个特性有…

VXLAN:虚拟化网络的强大引擎

1.什么是VXLAN VXLAN(Virtual eXtensible Local Area Network,虚拟扩展局域网),是由IETF定义的NVO3(Network Virtualization over Layer 3)标准技术之一,是对传统VLAN协议的一种扩展。VXLAN的特…

【Spring】Spring事务和事务传播机制

文章目录 什么是事务事务的操作Spring 中事务的实现Spring编程式事务Spring 声明式事务 TransactionalTransactional作用Transactional 详解rollbackFor事务隔离级别Spring 事务隔离级别Spring 事务传播机制 什么是事务 事务(Transaction)是一个程序中一…

【vue-baidu-map】百度地图组件,实现精准搜索,当前定位功能

实现效果&#xff1a; 代码如下&#xff1a; //引入地图组件 <bmap ref"bmap" map-confirm"confirmPosition" />confirmPosition() {const _this this.$refs.bmapconst center _this.centervar point center.lng , center.latconsole.log(阀控…

JavaEE作业-实验一

目录 1 实验内容 2 思路 3 核心代码 &#xff08;1&#xff09;前端核心代码&#xff1a; &#xff08;2&#xff09;后端核心代码&#xff1a; 4 实验结果 1 实验内容 用Servlet JSP JavaBean实现登录功能 2 思路 ①建好web项目,创建数据库 ②建立两个简单的前端页…

HarmonyOS Next开发----k线图滑动问题

前言 最近做股票软件鸿蒙版本的适配&#xff0c;K线趋势图的手势交互上遇到了问题&#xff0c;这里记录下~ 功能需求&#xff1a; 实现k线趋势图滑动及fling的效果 思路&#xff1a; 1. 借鉴Flutter版本的思路&#xff0c;在K线趋势图上面叠加一个Scroll布局&#xff0c;使…

parted命令进行磁盘分区

1.使用lsblk 查看可用的磁盘 可以看到有sdb sdc两个物理盘还未挂载 2.使用parted命令分区(以sdb为例) 按需要把sdb分成4个逻辑分区 新建磁盘标签类型为gpt 出现提示,输入yes 开始分区: (1)输入mkpart回车,提示输入分区名称,按习惯可命名为sdb1(后面依次sdb2、sdb3)…

LeetCode每日一题 | 1696. 跳跃游戏 VI

文章目录 题目描述问题分析程序代码 题目描述 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 一开始你在下标 0 处。每一步&#xff0c;你最多可以往前跳 k 步&#xff0c;但你不能跳出数组的边界。也就是说&#xff0c;你可以从下标 i 跳到 [i 1&#xff0c; min(…

部署篇 | MatrixOne与MySQL全面对比

MatrixOne是一款高度兼容MySQL语法的HTAP数据库&#xff0c;在大部分场景下可以直接实现对MySQL的替换。 作为一款开源数据库&#xff0c;MatrixOne 选用对开发者友好的 Apache-2.0 License&#xff0c;支持在主流的 Linux 和 MacOS 系统中直接进行物理部署。在部署方式上&…

JVM 性能调优 - 参数基础(2)

查看 JDK 版本 $ java -version java version "1.8.0_151" Java(TM) SE Runtime Environment (build 1.8.0_151-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode) 查看 Java 帮助文档 $ java -help 用法: java [-options] class [args...] …

Python中的for循环用法详解,一文搞定它

文章目录 for循环1.for循环的基本语法&#xff08;1&#xff09;遍历不等长多级容器&#xff08;2&#xff09;遍历不等长多级容器&#xff08;3&#xff09;遍历等长的容器 2.变量的解包3.for...else【详细讲解】4.range对象5.总结6.打印 1 ~ 10 跳过57.打印菱形小星星 for循环…

【Linux】select、poll、epoll代码

将fd设置成非阻塞 void setNonBlock(int fd) {int res fcntl(fd, F_GETFL);if (res < 0){std::cerr << "错误" << strerror(errno) << std::endl;return;}fcntl(fd, F_SETFL, res | O_NONBLOCK); } select 1.select系统调用是用来让我们的程…