转载:
SPI总线上有两类设备:一类是主控端,通常作为SOC系统的一个子模块出现,比如很多嵌入式MPU中都常常包含SPI模块。一类是受控 端,例如一些SPI接口的Flash、传感器等等。主控端是SPI总线的控制者,通过使用SPI协议主动发起SPI总线上的会话。而受控端则被动接受 SPI主控端的指令,并作出响应的响应。
Linux目前只支持SPI主控端,不能支持SPI受控端设备。
Linux中的SPI是依靠SPI子系统实现的。这个子系统向下直接和SPI主控设备硬件交互,读取SPI总线上的数据。向上则和FS子系统、MTD子系统、字符设备子系统等等交互,给用户空间提供访问接口。
在SPI子系统中,包含两类设备驱动。一类称之为Controller driver,用于驱动SPI主控设备,以和SPI总线交互,读写通信数据。另一类称之为Protocol driver,用于解析Controller driver读取的数据,形成有意义的协议数据。举例来说,将AT25芯片通过SPI总线和LPC3250的SPI控制器联接在一起,构成一个SPI总线 通信系统。Protocol driver的作用,就是根据用户空间或者上层子系统的请求,(比如读写Flash指定地址出的数据),找到对应的SPI指令,并生成一个SPI会话帧 (指令+地址+数据)数据。Controller driver的作用,就是将这个会话帧的数据通过SPI控制器的硬件,发到SPI总线上去。
由此可见,SPI子系统中有两种设备,一种是Controller driver驱动的,称之为spi_master。另一种是由Protocol driver驱动的,称之为spi_device(个人觉得这种称法不太准确,这个设备只是协议解析设备,而非真正的spi设备)。
内核之所以把SPI子系统这么划分,是因为SPI主控器功能单一,只负责和SPI总线交互,读写数据。但数据的具体含义,根据SPI总线上的设备不同,而千差万别。
内核一方面把SPI通信系统分成上面两个部分,另一方面创建了一个spi核心系统,用于联接这两部分。
根据上面的分析我们知道,SPI通信的数据流大致是:
1、用户请求=>Protocol driver分析请求,生成SPI通信帧=>Controller driver将通信帧发送到SPI总线上;
2、SPI设备传回数据=>Controller driver从SPI总线上读回=>Protocol解析通信数据并上报;
其中Protocol和Controller之间的交互中,SPI帧是一个比较关键的数据结构。Protocol通过分析上层请求生成这种帧,并且 解析这种帧得到SPI设备的响应的结果。Controller通过和SPI总线交互,收发这样的帧。在Linux内核中,这个帧通过一个叫做 spi_message的结构来实现。
在有数据请求时,Protocol解析请求生成这个帧,并发送到SPI核心子系统。SPI核心子系统通过Protocol设备的信息,找到对应的 Controller设备,并将这个帧发送给Controller。Controller接受到这个帧后发送到SPI总线上。返程类似。
关于SPI Controller和Protocol这两种设备以及SPI核心子系统相互之间是如何工作的,请参考下一篇《Linux内核SPI子系统实现分析》。