SPI overview

来自百问网嵌入式Linux wiki

本文提供有关 Linux® SPI框架和STM32 SPI驱动程序安装的基本信息。 它说明了如何使用SPI,更具体地说:

  • 如何在 Linux® BSP上激活SPI接口
  • 如何从内核空间访问SPI
  • 如何从用户空间访问SPI。

Framework purpose

Linux内核为SPI[1]协议支持提供了特定的框架。 SPI(串行外围接口)是主要用于嵌入式系统中的短距离通信的同步串行通信接口。
该接口由摩托罗拉创建,现在已经变成了行业标准。由于它不是由 I2C之类的联盟定义的,因此存在不同的信号名称和信号极性模式。
SPI器件使用具有单个主机的主从结构,以全双工,半双工或单工(rx / tx)模式进行通信。 Linux内核SPI框架为SPI主站(Linux内核在总线上启动SPI消息传递)提供了完整的支持,最近又为SPI从站(Linux内核对总线主站的请求做出了响应)提供了完整的支持。

有关Linux内核SPI框架的简介,请参见[2]

System overview

用户可以在微处理器设备周围添加许多SPI外部设备,以创建定制板。 可以通过SPI从用户空间或内核空间访问每个外部设备。

Spi-overview-new.png

Component description

Board external SPI devices

从设备“ X”是物理设备(通过SPI总线连接到STM32微处理器),相对于STM32而言,它们是从设备。
STM32是SPI总线主设备。
芯片选择信号允许独立选择每个从设备。

STM32 SPI internal peripheral controller

STM32 SPI控制器可处理连接到同一总线的所有外部SPI设备。
STM32微处理器设备通常嵌入 SPI internal peripheral 的多个实例,以管理多个SPI总线。
有关STM32 SPI内部外设的更多信息,请参考 SPI_internal_peripheral#SPI_main_features

spi-stm32

STM32 SPI控制器驱动程序为spi内核提供了一个ST SPI内部外围抽象层。
它定义了SPI内核库使用的所有SPI传输方法。
STM32 SPI控制器驱动程序仅支持SPI主模式。

spi-core

spi-core 是“交流的大脑”: 它实例化并管理所有总线和外围设备。

  • 顾名思义,这就是SPI引擎。 它还负责解析适配器和设备的设备树条目。 它实现了标准的SPI模式: 0, 1, 2 and 3.

Slave device drivers

该层表示与物理外围设备关联的所有驱动程序。

spidev

"spidev" 是用户和外围设备之间的接口。 这是一个内核驱动程序,它使用此dev接口API提供对用户空间应用程序的统一SPI总线访问。 有关示例,请参见API Description

Application

借助 spidev界面,该应用程序可以控制所有外围设备。

API description

User space application

The user space application 使用内核驱动程序(spidev)通过devfs进行SPI传输。
让我们以通过芯片选择C连接到总线B的SPI设备为例。“spidev” 驱动程序提供以下接口:

  • /dev/spidevB.C: 由“udev”创建的字符特殊设备,用户空间应用程序使用它来控制数据并将其传输到SPI设备。

支持的系统调用: open(), close(), read(), write(), ioctl(), llseek(), release().

Supported ioctls commands
Constant Description
SPI_IOC_RD_MODE, SPI_IOC_WR_MODE Gets/sets SPI transfer mode
SPI_IOC_RD_LSB_FIRST, SPI_IOC_WR_LSB_FIRST Gets/sets bit justification used to transfer SPI words.
SPI_IOC_RD_BITS_PER_WORD, SPI_IOC_WR_BITS_PER_WORD Gets/sets the number of bits in each SPI transfer word.
SPI_IOC_RD_MAX_SPEED_HZ, SPI_IOC_WR_MAX_SPEED_HZ Gets/sets the maximum SPI transfer speed in Hz.

上表仅显示了主要命令。框架中定义了其他命令 (see dev-interface API[3] for a complete list).

Kernel space peripheral driver

内核空间外围设备驱动程序与SPI设备通信,并使用以下 SPI核心API[4]

Configuration

Kernel configuration

通过Linux Menuconfig工具在内核配置中启用SPI支持(SPI框架和STM32 SPI驱动程序):Menuconfig or how to configure kernel.

[x] Device Drivers
    [x] SPI support
        *** SPI Master Controller Drivers *** 
        [x] STMicroelectronics STM32 SPI controller
        *** SPI Protocol Masters *** 
        [x] User mode SPI device driver support

这可以在内核中手动完成:

CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_STM32=y
CONFIG_SPI_SPIDEV=y

驱动程序(控制器和外围设备)可以编译为内核模块(由‘m’ 内核配置文件选择)或直接编译到内核(aka内置)(由 ‘y’ 内核配置文件选择)中。

Info.png 如果从设备参与引导过程,则支持该设备所需的驱动程序将被视为至关重要,并且必须内置在内核中

Device tree configuration

请参考 SPI device tree configuration.

How to use the framework

Linux内核文档中提供了有关如何编写SPI从驱动程序以控制SPI设备的详细信息。[5].

Under construction.png 更多示例即将推出

{{#set:Has under construction messages=true}}

How to trace and debug the framework

How to trace

Activating SPI framework debug messages

要从SPI框架获取详细消息,请通过menuconfig激活Linux内核中的“对SPI驱动程序的调试支持”Menuconfig or how to configure kernel.

[x] Device Drivers
    [x] SPI support
        [x] Debug support for SPI drivers

这是在内核.config文件中手动完成的:

CONFIG_SPI=y
CONFIG_SPI_DEBUG=y
CONFIG_SPI_MASTER=y
...

SPI驱动程序的调试支持(CONFIG_SPI_DEBUG)使用DEBUG标志编译位于Linux内核驱动程序/ spi文件夹中的所有SPI文件。

Info.png 提醒:需要通过控制台使用引导参数或“ dmesg -n 8”命令将“ loglevel”增加到8

Dynamic trace

有关详细的动态跟踪信息,请参阅 How to use the kernel dynamic debug

 Board $> echo  "file spi* +p" > /sys/kernel/debug/dynamic_debug/control

该命令在运行时启用与SPI内核和驱动程序相关的所有跟踪。
通过只选择要跟踪的文件,可以进行更精细的选择。

Info.png 提醒:需要通过控制台使用引导参数或“ dmesg -n 8”命令将“ loglevel”增加到8

How to debug

Detecting SPI configuration

sysfs

实例化外围设备时,spi-core和内核会通过sysfs导出多个文件:

  • /sys/class/spi_master/spix 显示所有实例化的SPI总线, 'x' 是SPI总线编号。
Warning.png 'x'可能与SPI内部外设索引不匹配,因为它取决于器件的探测顺序。
  • /sys/bus/spi/devices 列出了所有实例化的外围设备。例如,名为 spi0.0 的存储库对应于连接到SPI总线0和芯片选择0的外设。 下面是代表“TPM”设备的示例:
  • /sys/bus/spi/drivers 列出所有实例化的驱动程序。tpm_tis_spi/ 存储库是TPM 2.0的驱动程序。 spidev/存储库是SPI用户模式的通用驱动程序。
/sys/bus/spi/devices/spi0.0/
            /
            /drivers/tpm_tis_spi/spi0.0/
            /drivers/spidev/...
/sys/class/spi_master/spi0/spi0.0
                     /spi1/
                     /spi2/

devfs

如果将“spidev”驱动程序编译到内核中,则存储库/ dev将包含所有SPI设备条目。它们被编号为spix.y其中:

  • “ x”是SPI总线号
  • “ y”是总线上的芯片选择索引。

与允许完全访问I2C总线的i2c-dev不同,“ spidev”可直接访问由设备树节点中定义的芯片选择信号标识的SPI设备。

下面的示例显示了SPI总线4(芯片选择2)上的用户模式SPI设备。

/dev/spi4.2

有关更多信息,请参考spidev文档 [3].

Source code location