转载地址http://blog.csdn.net/droidphone

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设备。

[转载]Linux驱动-SPI驱动-概述的更多相关文章

  1. [转载]Linux驱动-SPI驱动 之二:SPI通用接口层

    通过上一篇文章的介绍,我们知道,SPI通用接口层用于把具体SPI设备的协议驱动和SPI控制器驱动联接在一起,通用接口层除了为协议驱动和控制器驱动提供一系列的标准接口API,同时还为这些接口API定义了 ...

  2. Linux驱动 - SPI驱动 之三 SPI控制器驱动

    通过第一篇文章,我们已经知道,整个SPI驱动架构可以分为协议驱动.通用接口层和控制器驱动三大部分.其中,控制器驱动负责最底层的数据收发工作,为了完成数据的收发工作,控制器驱动需要完成以下这些功能:1. ...

  3. Linux内核SPI支持概述

    1. 什么是SPI? Serial Peripheral Interface是一种同步4线串口链路,用于连接传感器.内存和外设到微控制器.他是一种简单的事实标准,还不足以复杂到需要一份正式的规范.SP ...

  4. Linux驱动 - SPI驱动 之四 SPI数据传输的队列化

    我们知道,SPI数据传输可以有两种方式:同步方式和异步方式.所谓同步方式是指数据传输的发起者必须等待本次传输的结束,期间不能做其它事情,用代码来解释就是,调用传输的函数后,直到数据传输完成,函数才会返 ...

  5. [DM8168]Linux下SPI驱动测试

    1.内核自带的SPI相关的驱动文件 项目中有CPU与FPGA进行通信,用到SPI接口: SPI头文件在: linux-kernel/include/linux/spi.h SPI实现在: linux- ...

  6. linux内核SPI总线驱动分析(一)(转)

    linux内核SPI总线驱动分析(一)(转) 下面有两个大的模块: 一个是SPI总线驱动的分析            (研究了具体实现的过程) 另一个是SPI总线驱动的编写(不用研究具体的实现过程) ...

  7. Linux Spi驱动移植小结

    2012-01-07 22:21:29 效果图: 理论学习后,主要是linux中spi子系统设备框架的了解后,主控制器与设备分离的思想,那么我要开始动手了. 1,  make menuconfig添加 ...

  8. linux驱动基础系列--linux spi驱动框架分析

    前言 主要是想对Linux 下spi驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型等也不进行详细说明原理.如果有任何错误地方,请指出,谢谢! spi ...

  9. 4412 SPI驱动

    1.Linux主机驱动和外设驱动分离思想(I2C驱动里有) SPI驱动总线架构:SPI核心层(x),SPI控制器驱动层(x),SPI设备驱动层(√).前面两个设备驱动搞明白了可以去看 2.教程中介绍: ...

随机推荐

  1. [Python]基于CNN的MNIST手写数字识别

    目录 一.背景介绍 1.1 卷积神经网络 1.2 深度学习框架 1.3 MNIST 数据集 二.方法和原理 2.1 部署网络模型 (1)权重初始化 (2)卷积和池化 (3)搭建卷积层1 (4)搭建卷积 ...

  2. Introduction to vSphere Integrated Containers

    vSphere Integrated Containers enables IT teams to seamlessly run traditional workloads and container ...

  3. Go 语言为Fibonacci函数实现Read方法

    Go语言非常灵活,只要为对象实现了相应的方法就可以把他看成实现了某个接口,类似于Durk Type, 为Fibonacci实现Read方法,就可以像读取文件一样,去读取下一个Fibonacci值. 示 ...

  4. Servlet和Filter的url匹配以及url-pattern详解

    Servlet和filter是J2EE开发中常用的技术,使用方便,配置简单,老少皆宜.估计大多数朋友都是直接配置用,也没有关心过具体的细节,今天遇到一个问题,上网查了servlet的规范才发现,ser ...

  5. dedecms 织梦列表页标题增加显示页数

    判断是否为第一页,为第一页则不显示页数的代码: {dede:pagelist listsize='0' listitem='pageno' function='html2text(@me)' runp ...

  6. EF Code-First 学习之旅 Fluent API

    Mappings To Database Model-wide Mapping Set default Schema Set Custom Convetions Entity Mapping To S ...

  7. HRBUST 2072 树上求最大异或路径值

    一个很经典的套路 思想是 F [u,v] = F[1,u] ^ F[1,v] 这样就转化成了n个数两两异或 求最大值 可以用字典树来做 每次用当前数去树中寻求最大xor值 然后把这个数字插进去 就相当 ...

  8. 使用log4j2打印Log,log4j不能打印日志信息,log4j2不能打印日志信息,log4j和logj2,idea控制台信息乱码(文末)

    说来惭愧,今天就写了个"hello world",了解了一下log4j的日志. 本来是想在控制台打印个log信息,也是遇到坎坷重重,开始也没去了解log4j就来使用,log4j配置 ...

  9. python常见的PEP8规范

    1. 括号中使用垂直隐式缩进或使用悬挂缩进 缩进 每级缩进用4个空格 示例: (垂直隐式缩进)对准左括号 def function_name(var_one,var_two, var_three,va ...

  10. ZC_注意点

    1. domain类 里面的 属性的类型,一般都是用 包装类 2. 使用 "Hibernate Reverse Engineering ..." 来进行自动生成domain类和?? ...