当前位置: 首页 > news >正文

【kernel8】spi协议,验证,模型,设备树处理,spidev,衍生协议

文章目录

  • 1.协议:芯片和芯片间通讯,4个pin,M(master)I(input)
  • 2.spi总线的验证方法:如下测得返回也是1
  • 3.spi控制器驱动:波形是由spi控制器拉出,dev节点进行数据发送和接收
    • 3.1 platform_get_resource:获取pdev resource(probe函数传入pdev,设备树中所有节点被转换为platform_device,设备树中reg和interrupts属性转为resource,reg是索引0,interrupts是1)
  • 4.设备驱动模型:platform_driver和platform_device都需要注册,注册时都会和对方比较(通过platform_bus_type的match函数比较),如果match函数返回成功,则匹配上调用probe
  • 5.spi设备树处理过程:compatible属性找到spi_master驱动(如spi-gpio.c),spi_master驱动probe里会of_register_spi_device(struct spi_device , of_find_property读设备树属性填充spi_device,最后spi_add_device注册spi_device)
  • 6.spidev的使用(spi用户态api):spidev.c访问spi_device进而访问spi_master里传输函数访问硬件
  • 7.使用spidev操作SPI_DAC模块:转为模拟信号
  • 8.衍生协议:Dual/Quad SPI(只针对SPI Flash而言,不是针对所有SPI外设)


1.协议:芯片和芯片间通讯,4个pin,M(master)I(input)

主设备总是生成时钟,其速度可达80Mhz,实际没有速度限制(也远比I2C快),ss线(片选同一时刻只有一个有效,保证数据不干扰)也由主设备管理。
在这里插入图片描述
eeprom有1024位存储空间即128(如下8x8x2)个字节(不是FF十进制255个字节),每个字节都有属于自己的地址,那怎么读取这1024位数据呢?最直接的办法就是给每一位都外接一根线,显然不现实,spi只需4根线就可读写1024bit数据了,一般ss为低电平有效,但是看93c46手册高电平有效。
在这里插入图片描述
如下7位地址码不同的排列组合就有2的7次方=128种,正好访问存储器的128个字节。把高低电平通过mosi引脚发出去,数据就能成功写入?不是,因为spi是串行同步通信数据线要和时钟线配合。
在这里插入图片描述
SS片选信号被拉高后,从设备开始生效。芯片资料上有2个特殊寄存器配置位:CPOL(极性:sck空闲时时钟信号高还是低电平,1高,数据传输从跳变沿开始)。
在这里插入图片描述
CPHA(相位:sck的1个周期2个跳变沿,0从第1个跳变沿采样,1从第2…)。
在这里插入图片描述
如下就是spi的4中模式:
在这里插入图片描述
在这里插入图片描述
如下控制寄存器设置极性和相位,状态寄存器表示数据已经发送完成或使能中断,波特率寄存器是设置时钟频率,数据寄存器是写入数据并一位一位发送出去,同时从DI引脚上采样数据。
在这里插入图片描述

2.spi总线的验证方法:如下测得返回也是1

如下clk空闲时为高且在第二个跳变沿采样即上升沿采样。第三条线上数据如下,10进制为49即数字1。
在这里插入图片描述
在这里插入图片描述
如下三个管脚用的是spi3,所以配置spi3。
在这里插入图片描述
下面dtsi描述的就是spi控制器,控制器也是驱动,pinctrl描述gpio配置。
在这里插入图片描述
如下看手册里Address Mapping:所有的寄存器的基地址如fe640000。
在这里插入图片描述
如下添加设备。
在这里插入图片描述
在这里插入图片描述

3.spi控制器驱动:波形是由spi控制器拉出,dev节点进行数据发送和接收

在这里插入图片描述
如下获取设备树的reg,再做ioremap(因为寄存器地址kernel没法直接访问)。如下rs就是自己定义的结构体,最后会赋值给ctrl。
在这里插入图片描述
如下还是在probe函数中,如下第一行的函数调用platform_get_resource(dev,IORESOURCE_IRQ,num)。
在这里插入图片描述
如下第一行是不是休眠唤醒,pdev->id是3,mode_bit默认0。
在这里插入图片描述
在这里插入图片描述

3.1 platform_get_resource:获取pdev resource(probe函数传入pdev,设备树中所有节点被转换为platform_device,设备树中reg和interrupts属性转为resource,reg是索引0,interrupts是1)

如下源码num_resource就是上面的reg和interrupt的2个资源。
在这里插入图片描述
如下因为从pdev拿出resource(内存区域,中断等)。
在这里插入图片描述

4.设备驱动模型:platform_driver和platform_device都需要注册,注册时都会和对方比较(通过platform_bus_type的match函数比较),如果match函数返回成功,则匹配上调用probe

在这里插入图片描述
在这里插入图片描述

5.spi设备树处理过程:compatible属性找到spi_master驱动(如spi-gpio.c),spi_master驱动probe里会of_register_spi_device(struct spi_device , of_find_property读设备树属性填充spi_device,最后spi_add_device注册spi_device)

在这里插入图片描述
如下是spi_master(不是spi_slave)必须有的属性。
在这里插入图片描述
如下bits_per_word不是来自设备树,应用程序发起传输可设置这个值,表示每次传输的bit数。spi_device结构体里有master父节点,所以可用spi_master的传输函数。
在这里插入图片描述

6.spidev的使用(spi用户态api):spidev.c访问spi_device进而访问spi_master里传输函数访问硬件

minor次设备号来自位图中第一个未被占用的号码,片选chip_select来自设备树,表示是这个spi_master下的第几个设备。device_create去创建/dev/spi…节点。
在这里插入图片描述
open时候如何根据minor…实现在spidev_open函数如下,devt含有主次设备号,要和打开的设备节点的主次设备号(inode->i_rdev)比较,相等的话就是找到了这个设备,找到后分配发送和接收缓冲区,flip->private_data=spidev将spidev即spidev_data存入打开文件的私有数据里,read时候直接取出,就不需要重新找到这spi设备。
在这里插入图片描述
内核提供测试程序:tools/spi/spidev_fdx.c:spidev_fdx -r 100 /dev/spidevB.D。main函数中调用do_read -> read,驱动中.read=spidev_read,spidev_read调用如下spidev_sync_read(同步,等待结果),读完后再copy_to_user拷贝回用户空间,write同理。
在这里插入图片描述
不同上面do_read方式,如下用ioctl实现同时读写,读和写的长度是一样的,注释了xfer[1]。
在这里插入图片描述

7.使用spidev操作SPI_DAC模块:转为模拟信号

在这里插入图片描述
数据可以通过DOUT传给下一个芯片,也可以传给master如下图。
在这里插入图片描述
同时写和读,只能用ioctl,先传输tx_buf[0](存入高字节数据),后传输tx_buf[1](存入低字节数据)。如下dac_test.c。
在这里插入图片描述
如下底板原理图,第四组gpio的第26个引脚。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
pulse duration脉冲持续时间。一个周期包含高低电平。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
insmod spidev.ko,出现/dev/spidev0.0节点。
在这里插入图片描述
将dac_test.c第64行右移2位,如下就是600。
在这里插入图片描述
在这里插入图片描述
如下spi->modalias就是设备树中compatible。
在这里插入图片描述

8.衍生协议:Dual/Quad SPI(只针对SPI Flash而言,不是针对所有SPI外设)

Dual SPI:上面讲的是standard spi全双工(同时发送和接收),对于SPI Flash,全双工并不常用(bmc主设备MOSI发送数据,flash从设备不需要MISO返回数据),因此扩展了mosi和miso的用法,让它们工作在半双工(2根线同时发或收),用以加倍数据传输。发送一个命令字节进入dual mode,这样MOSI复用成SIO0(serial io0),MISO复用成SIO1(serial io1),这样一个时钟周期内就能传输2个bit数据。

Quad SPI:在Dual SPI的基础上增加了两根I/O线(SIO2,SIO3),目的是一个时钟内传输4个bit。
在这里插入图片描述

http://www.dtcms.com/a/264140.html

相关文章:

  • AI人工客服实战指南:基于大模型构建生产级智能对话系统
  • Hadoop、Spark、Flink 三大大数据处理框架的能力与应用场景
  • ESP32-S3开发板深度评测:AI语音识别与图像处理全面解析
  • C++ 第四阶段 STL 容器 - 第九讲:详解 std::map 与 std::unordered_map —— 关联容器的深度解析
  • Springboot整合高德地图
  • NeurIPS-2023《A Definition of Continual Reinforcement Learning》
  • 基于GD32 MCU的IAP差分升级方案
  • 迎战 AI Overviews:SEO 不被淘汰的实战策略
  • SpringBoot全局异常详解
  • Electron 应用打包与分发:从开发到交付的完整指南
  • 多容器应用与编排——AI教你学Docker
  • Java-String类静态成员方法深度解析
  • AR 地产互动沙盘:为地产沙盘带来变革​
  • OpenCV-Python Tutorial : A Candy from Official Main Page(二)
  • 设备管理的重要性:企业数字化浪潮下的核心命题
  • 企业上网行为管理:零信任安全产品的对比分析
  • Linux基本命令篇 —— grep命令
  • 防 XSS和CSRF 过滤器(Filter)
  • go语言安装达梦数据完整教程
  • JVM 中的垃圾回收算法及垃圾回收器详解
  • 【仿muduo库实现并发服务器】Connection模块
  • CentOS 8中 更新或下载时报错:为仓库 ‘appstream‘ 下载元数据失败 : Cannot prepare internal
  • 02.SpringBoot常用Utils工具类详解
  • 从马赛克到色彩错乱:一次前景图像处理异常的全流程踩坑记录
  • Python实例题:基于 Python 的简单爬虫与数据可视化
  • 【IP 潮玩行业深度研究与学习】
  • 【仿muduo库实现并发服务器】eventloop模块
  • 香橙派3B学习笔记14:deb 打包程序_解包前后脚本运行
  • 折线图多数据处理
  • redux基本概念介绍 与 更新方式