SPI驱动框架
SPI驱动属于总线-设备-驱动模型的,与I2C总线设备驱动模型相比,大体框架是一样,他们都是实际的总线。总体框架如下图所示:
从上到下,分为三层,用户空间,内核空间,和硬件层。
用户空间
在用户空间,/dev/spi0
和/dev/spi1
是SPI总线的设备节点,它们在用户空间提供了对SPI总线设备的访问接口。
/dev/spi0
和/dev/spi1
分别对应于SPI总线上的两个片选信号(Chip Select)。SPI总线上的每个设备都需要通过一个唯一的片选信号来选择与之通信的设备。因此,对于每个片选信号,都会创建一个对应的设备节点。
通过打开这些设备节点,用户可以使用标准的读写操作来与SPI设备进行数据传输。例如,可以通过向设备节点写入数据来发送数据到SPI设备,或者通过从设备节点读取数据来接收SPI设备发送的数据。
内核空间
SPI设备驱动
SPI设备驱动用于支持连接到总线上的具体设备。对于SPI总线来说,SPI设备驱动就是设备驱动的一种实现,负责与SPI外设进行通信。
SPI设备驱动相比于I2C设备驱动,需要提供更多的硬件信息,设备名称、片选信号、最大传输速率、模式、中断号等,在driver里则使用spi_read
、spi_writer
等函数,最终也会调用到 master->transfer
函数进行发送接收。
跟"平台总线设备驱动模型"类似,Linux中也有一个"SPI总线设备驱动模型":
spi_driver
使用C文件实现,里面有id_table
表示能支持哪些SPI设备,有probe函数spi_device
用来描述SPI设备,比如它的片选引脚、频率- 可以来自设备树:比如由SPI控制器驱动程序解析设备树后创建、注册
spi_device
- 可以来自C文件:比如使用
spi_register_board_info
创建、注册spi_device
- 可以来自设备树:比如由SPI控制器驱动程序解析设备树后创建、注册
SPI控制器驱动
SPI控制器驱动是总线设备驱动模型中的一种具体实现,控制器驱动负责与硬件控制器进行通信,并提供控制器的初始化、配置和控制等操作。
- 在设备树里描述SPI控制器的硬件信息,在设备树子节点里描述挂在下面的SPI设备的信息
- 在
platform_driver
中提供一个probe函数- 它会注册一个
spi_master
- 还会解析设备树子节点,创建
spi_device
结构体
- 它会注册一个
SPI控制器驱动程序叫做spi_master(spi_controller)
,主要提供transfer函数,进行SPI协议的数据传输。spi_master
驱动也是基于platform模型的,注册spi_master
时也会扫描一个链表进行SPI从设备的注册,这和I2C适配器驱动基本一致。
SPI Core
SPI核心是Linux内核中的核心模块,提供了SPI子系统的基本功能和接口。它包含了SPI总线设备的注册、注销、传输管理以及与SPI控制器和设备驱动的交互。SPI核心还提供了一组API供设备驱动程序使用,如spi_register_driver()
和spi_setup()
等。
硬件层
SPI Host Controller
SPI Host Controller
驱动是用于支持特定硬件平台上SPI控制器的驱动程序。
通过SPI Host Controller
驱动,用户空间程序可以通过标准的SPI设备节点(如/dev/spi0
、/dev/spi1
)来与SPI总线进行交互。 SPI Host Controller
驱动提供了对SPI总线的底层硬件控制和传输操作的支持,使得用户空间程序能够方便地与连接到SPI总线上的外设进行通信和控制。
SPI从设备
SPI从设备是连接到SPI总线上的外设。每个SPI从设备都有一个唯一的片选信号(Chip Select),用于选择与之通信的具体设备。从设备通常由设备驱动程序来管理,它们可以是各种外设,如传感器、存储器、显示器等。
小结
-
在一个SoC上可能有多条SPI总线,一条总线对应一个SPI总线驱动,每一条总线上又可以接多个SPI设备。
-
SPI-Core管理SOC上的所有
platform_device
和platform_driver
,spi_device
,spi_driver
。