写在前言:

致敬对这篇文档感兴趣的所有读者,关于对spi通信的解读,目前花费大概几个星期进行相关验证和调试,在这个过程中发生了很多奇怪的现象,一般来说spi控制形式多种多样,对于spi的全双工、半双工通信形式也会有所不同,这篇文档主要是帮助大家解读spi不同机制通信和相关问题分析,以供后期方便类似问题及时参考。本文档重点解读spi下相关控制机制,其中包括spi的控制器形式和spi的gpio通信形式多方位解读。

  • 解读spi.c文件

想必大家对spi基本原理有所了解,如还有不怎么了解的可参考我发布的写文章-CSDN创作中心这篇文档,可以帮助大家熟悉spi是什么,做什么,怎么做的!

接下来就是浓墨重彩部分啦,在这个文件中主要看spi_sync、spi_async两个函数逻辑,首先解读一下spi_sync函数:

1.1 spi_sync函数解读

从上图中分析,单一指令进入就上锁(这里会产生不可避免的阻塞),此时其他指令无法进入,必须当前指令释放控制权方可操作,重点看看_spi_sync函数,也是在这个函数里面是最容易有问题的部分:

1.2 _spi_sync函数解读

对于这个全双工函数首先看spi_validate函数,这个函数是对status状态进行合法性校验,同时这个状态也会传给上层的iotcl逻辑中(return status),再看trace_spi_submit函数,这个函数进行spi消息的提交,上报给应用层控制,而这个消息是通过_spi_queued_transfer消息队列函数进行存储的,每次存储就返回这个状态,通过返回的这个状态来进行_spi_pump_messages函数进行push out。通过wait_for_completion函数进行等待全双工通信字节传输完成,这里的一个坑就是阻塞问题,没有解决会一直通过这个状态等待,这个状态我的想法是在wait函数中进行改变,阻塞等待造成cpu其他事件无法继续处理,所以在这里我添加了status=message->status = 0进行置位,并通过message->complete函数进行消息内容写入完成信息的状态告知,这样cpu才会继续处理其他指令事件。

1.3 spi_async函数解读:

对异步通信形式这里我不做太多说明,其和同步通信有点类似。重点需要关注_spi_async这个函数逻辑是如何执行的。

1.4 _spi_async函数解读:

对于异步通信这里不像同步通信那么复杂,通过spi->controller控制器进行数据传输并通过submit函数进行消息提交,直接返回提交状态即可。

  • 解读spidev.c文件:

2.1 file_operations驱动内核与应用空间交互结构体:

通过这个结构体知晓,重点关注spidev_write、spidev_read、spidev_ioctl、spidev_open这几个函数逻辑,用户空间也是通过结构体中这几个函数进行spi的相关操控。(对这个结构体不熟悉可参考我的这篇文档:展锐平台led灯调试总结 - ODMSWA-BSP - Confluence (ikotek.com)四、解析led-class文件中)。

2.2 spidev_open函数解读:

对spi的open函数也是通过status的状态进行判别的,所以就其根源,当前状态没有及时改变就会造成阻塞,阻塞导致延时的一个原因。

2.3 spi_ioctl函数解读:

应用层便是通过相应的cmd到达驱动相关判断逻辑进行spi的读写、模式、频率等进行控制,这里不太细讲,重点关注在spidev_get_ioc_message函数和spidev_message函数。

2.4 spidev_get_ioc_message函数解读:

这个函数才是咱们全双工通信最关键的地方,应用层通过spi_ioc_transfer结构体内context的赋值会通过这个函数进入驱动逻辑,并且这个结构体内的delay也是导致驱动通信延时的一个存在。重点看一下_IOC_NR(SPI_IOC_MESSAGE(n)),这个逻辑其实跟应用层设置相关,具体如下:

这个n代表的就是spi每次发送过去的时钟和数据的包数量。其具体实际通过这个函数里面的命令进行判断控制。在这里多说一句,就是在这个spi_ioc_transfer结构体中的延时delay,

其实际是通过这个delay微秒级别延时去进行每条指令从传输到完成之间的延时,这个延时会影响实际通信的速率,同时消耗cpu资源等待,肯定有人会问,这是为何,还记得上面说的wait等待函数吧,这里的延时会造成wait一直处于等待接收状态直到这个动作执行完成才会释放cpu资源。再看下一句,memdup_user函数,其和set_user、get_user、copy_to_user函数作用相似,可节省时钟周期。

2.5 spidev_message函数解读:

对于spidev_message函数,主要的工作是负责通信传输的工作,来实际看一下驱动逻辑吧。

看这里,首先明白一个点就是消息,在开始时候就是消息队列的初始化工作,并申请相应的内存空间,咱们关注的是copy_from_user函数和copy_to_user函数,这两个函数是关键,copy_from_user函数,实际从应用层空间赋值数据到位移寄存器然后传输到从机,copy_to_user函数实际从位移寄存器获取数据通过驱动到应用层操作。细看copy_from_user函数之后还有一个动作就是spi_message_add_tail函数,这个是在队列添加通信消息,我是这么理解的,就比如我通信多少次这个message就会有多少个,而每个message都会有一个status状态,通过状态进行入队和出队操作,向下面的spidev_sync全双工通信处理。

到这里spi控制器部分的讲解过程大致就明白了,对于spi实际大家只要把控住主线分析起来就比较可以找到问题原因(通信过程中产生阻塞导致延时的现象)所在。

  • 解读spi-gpio.c文件

思考一下,如果没有spi控制器操作的话,那么怎么进行spi通信呢?,那么接下来就讲到重点啦,没有spi控制器,还可以用gpio火速救援。接下来就解读一下spi-gpio文件都干了什么吧。

3.1 spi_gpio_probe函数解读:

对于probe函数一般都是申请一些操作的实际初始化函数,在这个函数中重点关注spi_gpio_probe_dt、spi_gpio_request、spi_bitbang_setup_transfer函数的操作逻辑。因为这三个函数是spi控制的关键。

3.2 spi_gpio_probe_dt函数解读:

这个动作并不陌生,就是对设备树中spi的相关gpio的匹配控制,这里可以多说一点就是设备树怎么配置,看下图:

如果我想在这个基础上继续增加其他gpio口进行封装也是可以的,那么对应需要在这个函数中增加相应gpio匹配逻辑判断。或者说,我不需要sck、miso、mosi、cs这些gpio口那么这些口就注释掉,增加自己需要的口进行匹配。

3.2 spi_gpio_request函数解读:

这个函数主要是申请相应gpio端口方向和电平状态值相关信息,端口方向是通过spi_gpio_alloc函数调用gpio_direction_input函数进行判断方向和电平值。因此咱们通过gpio的spi形式可以增加其他gpio口进行一起通过相应节点控制,当然也可以在cat >/sys/class/kernel/debug/gpio查看所有gpio口并进行相应操作。

3.3 spi_bitbang_setup_transfer函数解读:

这里就是transfer进行通信的入口函数逻辑,有点类似于spidev_iotcl函数逻辑,这里清楚spi_bitbang_start函数就是类似于spi_sync的函数。有这个概念,那么就清楚gpio通信的大概啦。

这里多说一点,对于spi的gpio形式通信,在编译宏中需要注意一点:

CONFIG_SPI_BITBANG=y

CONFIG_SPI_GPIO=y

同时编译,这是因为spi-gpio文件在gpio_transfer时需要使用bitbang文件。

这废话不用多少,只要有解读价值,帮助到大家就是值得的,大家有什么其他问题也可以在评论区留言,我会及时回复相应问题,编写不易,感谢大家一键三连关注、点赞支持走一波,大家的关注是小易持续投笔下去的动力~

SPI全双工通信解读和调试问题分析汇总相关推荐

  1. STM32双机SPI全双工通信

    (基于STM32F407的SPI全双工通信时序不同步问题!!) 首先吐槽一波,调一个星期的SPI,始终没有很好的效果. 网上有很多SPI主从通信的例子,但是两片STM32单片机进行通信,基本很少,就算 ...

  2. USART串口全双工与SPI全双工通信的区别!

    目录 1.背景知识 2.SPI的全双工同通信 3.串口USART的全双工通信 背景知识 首先我们先来区分一下单工.半双工.全双工模式. 单工:数据传输只支持数据在一个方向上传输 半双工:允许数据传输在 ...

  3. SPI全双工通信--看懂这篇就够

    对于生活中大家普遍常用到的一些基本通信总线协议,也是成为大家关注的焦点,那么今天小易就同大家在知识海洋中进行一次比较深入的探讨,同时也希望小易的这篇文章能给大家带来一定的帮助.  SPI通信原理: S ...

  4. android spi串口调试,PIC入门3,SPI通信和串口调试实验

    原标题:PIC入门3,SPI通信和串口调试实验 MSSP模块工作于SPI主控方式,这个可以直接在实验板上执行. 程序: //适合3EPIC实验板,配置PIC的MSSP模块工作于SPI主控方式下, // ...

  5. FPGA学习之路—接口(3)—SPI详解及Verilog源码分析

    FPGA学习之路--SPI详解及Verilog源码分析 概述 SPI = Serial Peripheral Interface,是串行外围设备接口,是一种高速,全双工,同步的通信总线. 优点 支持全 ...

  6. Chrome 远程调试协议分析与实战

    背景 某一天,A 君想获取 Chrome 页面中的性能数据,诸如时间.白屏和首屏等,因为需要和竞品进行对比分析,无法注入代码,该怎么办? 此时,你也许能想到开发者工具(DevTools),也许知道Ti ...

  7. SPI总线通信——基于STM32MP157A

    SPI总线概念 SPI总线是Motorola首先提出的全双工三线/四线同步串行总线,采用主从模式(Master Slave)架构:支持多从机(slave)模式应用,一般仅支持单主机,多从机. 时钟由主 ...

  8. STM32串口通信详解以及通信异常或者卡死常见问题分析

    STM32串口通信详解以及通信异常或者卡死常见问题分析 目录 STM32串口通信详解以及通信异常或者卡死常见问题分析 一.常见的异常问题 二.STM32的串口简介 1.串口的通讯方式 ①按数据传输方向 ...

  9. 基于STM32F1与NRF24L01模块的SPI简单通信

    一.前言 1.简介: 本文是基于STM32F1,将数据发送至NRF模块的寄存器,并将数据重新读取,通过串口发送出来的简单SPI单通信. 2.SPI简介: 调过STM8的都已经对SPI有所了解,调法都一 ...

最新文章

  1. 这两年:我的数据竞赛之路
  2. 用HOOK禁用鼠标与键盘点击
  3. LetCode-MSSQL查找重复的电子邮箱
  4. linux 终端 朗读,使Linux终端朗读文字的小技巧分享
  5. 49 FI配置-财务会计-固定资产-与总账集成-分配总帐科目
  6. vc6 设置静态文本框透明_微信还能这么玩?半透明的微信背景主题用起来!
  7. (转)RabbitMQ学习之spring整合发送同步消息
  8. Fiddler基本介绍
  9. Commit Message 规范
  10. 韩开发新技术 用纸代替硅制造电路芯片
  11. java分页计算_java分页算法
  12. 阿里开发规约之编程规约(4)
  13. 鸽巢排序Pigeonhole Sort----(排序算法八)
  14. python实现Content-Type:application/octet-stream
  15. 【今日CV 计算机视觉论文速览 第118期】Tue, 21 May 2019
  16. 耀世升级发布,阿里新出第三版Java多线程核心技术手册PDF全彩版
  17. 2016亚洲城市GDP50强出炉
  18. 大数据处理的关键技术(一)
  19. (python)生产者消费者模型
  20. MySQL基础(非常全)

热门文章

  1. java游戏——华容道
  2. Unity3d发布webplayer 部署到IIS
  3. linux下电信拨号器
  4. 北京邮电大学 信通院 计算机原理与应用笔记(一)
  5. Java Swing 利用 JToggleButton 实现 UI 常见的按钮的特效
  6. 深度学习训练营之海贼王人物识别
  7. activiti挂接角色和用户
  8. 一个研究生毕业后的职业规划
  9. 给PPT设计初学者的一些建议
  10. 【微信易信公众平台开发】开启开发者模式