Linux SPI总线和设备驱动架构之一:系统概述【转】

news/2024/7/6 6:31:26
 

目录(?)[-]

  1. 硬件结构
    1. 工作时序
  2. 软件架构
    1. SPI控制器驱动程序
    2. SPI通用接口封装层
    3. SPI协议驱动程序
    4. SPI通用设备驱动程序
 

SPI是"Serial Peripheral Interface" 的缩写,是一种四线制的同步串行通信接口,用来连接微控制器、传感器、存储设备,SPI设备分为主设备和从设备两种,用于通信和控制的四根线分别是:

 

  • CS    片选信号
  • SCK  时钟信号
  • MISO  主设备的数据输入、从设备的数据输出脚
  • MOSI  主设备的数据输出、从设备的数据输入脚
因为在大多数情况下,CPU或SOC一侧通常都是工作在主设备模式,所以,目前的Linux内核版本中,只实现了主模式的驱动框架。

 

/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/droidphone原创,转载请注明出处,谢谢!
/*****************************************************************************************************/

硬件结构


通常,负责发出时钟信号的设备我们称之为主设备,另一方则作为从设备,下图是一个SPI系统的硬件连接示例:
                                            图1.1    SPI硬件结构图
如上图所示,主设备对应SOC芯片中的SPI控制器,通常,一个SOC中可能存在多个SPI控制器,像上面的例子所示,SOC芯片中有3个SPI控制器。每个控制器下可以连接多个SPI从设备,每个从设备有各自独立的CS引脚。每个从设备共享另外3个信号引脚:SCK、MISO、MOSI。任何时刻,只有一个CS引脚处于有效状态,与该有效CS引脚连接的设备此时可以与主设备(SPI控制器)通信,其它的从设备处于等待状态,并且它们的3个引脚必须处于高阻状态。

工作时序


按照时钟信号和数据信号之间的相位关系,SPI有4种工作时序模式:
我们用CPOL表示时钟信号的初始电平的状态,CPOL为0表示时钟信号初始状态为低电平,为1表示时钟信号的初始电平是高电平。另外,我们用CPHA来表示在那个时钟沿采样数据,CPHA为0表示在首个时钟变化沿采样数据,而CPHA为1则表示要在第二个时钟变化沿来采样数据。内核用CPOL和CPHA的组合来表示当前SPI需要的工作模式:
  • CPOL=0,CPHA=1        模式0
  • CPOL=0,CPHA=1        模式1
  • CPOL=1,CPHA=0        模式2
  • CPOL=1,CPHA=1        模式3

软件架构


在内核的SPI驱动的软件架构中,进行了合理的分层和抽象,如下图所示:
                                 图2.1    SPI驱动的软件架构

SPI控制器驱动程序


SPI控制器不用关心设备的具体功能,它只负责把上层协议驱动准备好的数据按SPI总线的时序要求发送给SPI设备,同时把从设备收到的数据返回给上层的协议驱动,因此,内核把SPI控制器的驱动程序独立出来。SPI控制器驱动负责控制具体的控制器硬件,诸如DMA和中断操作等等,因为多个上层的协议驱动可能会通过控制器请求数据传输操作,所以,SPI控制器驱动同时也要负责对这些请求进行队列管理,保证先进先出的原则。

SPI通用接口封装层


为了简化SPI驱动程序的编程工作,同时也为了降低协议驱动程序和控制器驱动程序的耦合程度,内核把控制器驱动和协议驱动的一些通用操作封装成标准的接口,加上一些通用的逻辑处理操作,组成了SPI通用接口封装层。这样的好处是,对于控制器驱动程序,只要实现标准的接口回调API,并把它注册到通用接口层即可,无需直接和协议层驱动程序进行交互。而对于协议层驱动来说,只需通过通用接口层提供的API即可完成设备和驱动的注册,并通过通用接口层的API完成数据的传输,无需关注SPI控制器驱动的实现细节。

SPI协议驱动程序


上面我们提到,控制器驱动程序并不清楚和关注设备的具体功能,SPI设备的具体功能是由SPI协议驱动程序完成的,SPI协议驱动程序了解设备的功能和通信数据的协议格式。向下,协议驱动通过通用接口层和控制器交换数据,向上,协议驱动通常会根据设备具体的功能和内核的其它子系统进行交互,例如,和MTD层交互以便把SPI接口的存储设备实现为某个文件系统,和TTY子系统交互把SPI设备实现为一个TTY设备,和网络子系统交互以便把一个SPI设备实现为一个网络设备,等等。当然,如果是一个专有的SPI设备,我们也可以按设备的协议要求,实现自己的专有协议驱动。

SPI通用设备驱动程序


有时候,考虑到连接在SPI控制器上的设备的可变性,在内核没有配备相应的协议驱动程序,对于这种情况,内核为我们准备了通用的SPI设备驱动程序,该通用设备驱动程序向用户空间提供了控制SPI控制的控制接口,具体的协议控制和数据传输工作交由用户空间根据具体的设备来完成,在这种方式中,只能采用同步的方式和SPI设备进行通信,所以通常用于一些数据量较少的简单SPI设备。
【作者】 张昺华
【出处】 http://www.cnblogs.com/sky-heaven/
【博客园】 http://www.cnblogs.com/sky-heaven/
【新浪博客】 http://blog.sina.com.cn/u/2049150530
【知乎】 http://www.zhihu.com/people/zhang-bing-hua
【我的作品---旋转倒立摆】 http://v.youku.com/v_show/id_XODM5NDAzNjQw.html?spm=a2hzp.8253869.0.0&from=y1.7-2
【我的作品---自平衡自动循迹车】 http://v.youku.com/v_show/id_XODM5MzYyNTIw.html?spm=a2hzp.8253869.0.0&from=y1.7-2
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

http://www.niftyadmin.cn/n/4394992.html

相关文章

删除一个目录和其各级子目录下的.svn文件

两种方法[1]用find命令和其action来实现[2]用rm直接实现$ cd /tmp/xxx$ rm -rf find . -name .svn就可以实现了。删除SVN目录及从服务器端删除SVN版本库文件方法详解 在学习SVN的过程中,你可能会遇到这样的问题,如何删除SVN目录?如何从服务器端彻底删除…

Hive SQL 迁移 Flink SQL 在快手的实践

摘要:本文整理自快手数据架构工程师张芒,阿里云工程师刘大龙,在 Flink Forward Asia 2022 生产实践专场的分享。本篇内容主要分为四个部分: Flink 流批一体引擎 Flink Batch 生产实践 核心优化解读 未来规划 点击查看原文视频…

Yii2的深入学习--自动加载机制(转)

Yii2 的自动加载分两部分,一部分是 Composer 的自动加载机制,另一部分是 Yii2 框架自身的自动加载机制。 Composer自动加载 对于库的自动加载信息,Composer 生成了一个 vendor/autoload.php 文件。你可以简单的引入这个文件,你会得…

binlog复制的灾备设计

2019独角兽企业重金招聘Python工程师标准>>> [导读]本文主要介绍Booking网站在业务发展过程中碰到MySQL主库挂载几十甚至上百个从库时探索的解决方案:使用Binlog Server。Binlog Server可以解决五十个以上从库时主库网络带宽限制问…

Apache TraceEnable关闭与测试方法

系统环境:OS: RHEL5.6_x64Apache: httpd-2.2.11关闭方法:在主配置文件httpd.conf中添加配置:TraceEnable off可以直接配置在ServerRoot参数下面。测试方法:通过telnet到HTTP的某个服务端口,进行测试,如下描…

VNC Viewer的问题

VNC Viewer远程登录服务器时点了logout 标签: 远程登录服务器图形windowskillssh2012-08-02 15:55 3746人阅读 评论(1) 收藏 举报分类:Linux(16) 版权声明:本文为博主原创文章,未经博主允许不得转载。 问题…

解决高速物体碰撞不精确的问题

只要在碰撞属性中勾选Use CCD,当然代价就是耗费更多的CPU 转载于:https://www.cnblogs.com/blueroses/p/5624838.html

编译 linux 0.01

编译 linux 0.011.下载linux-0.11-devel-060625(这个有gar,编译时要用),bochs 2.52.建新硬盘img 用bochs自带的bxp_w_picpath建&#xff0c;按<linux-0.11内核完全解析>里的说明进行&#xff0c;也是256M. 然后fdisk,mkfs,然后把mkdir root, 然后把/bin,/dev,/usr复制过…