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

A detailed dynamic trace is available in How to use the kernel dynamic debug

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

This command enables all the traces related to the SPI core and drivers at runtime.
A finer selection can be made by choosing only the files to trace.

Info.png Reminder: loglevel needs to be increased to 8 by using either boot arguments or the dmesg -n 8 command through the console

How to debug

Detecting SPI configuration

sysfs

When a peripheral is instantiated, the spi-core and the kernel export several files through the sysfs :

  • /sys/class/spi_master/spix shows all the instantiated SPI buses, 'x' being the SPI bus number.
Warning.png 'x' may not match the SPI internal peripheral index as it depends on device probing order.
  • /sys/bus/spi/devices lists all the instantiated peripherals. For example, the repository named spi0.0 corresponds to the peripheral connected to SPI bus 0 and chip select 0. Below an example representing the "TPM" device:
  • /sys/bus/spi/drivers lists all the instantiated drivers. The tpm_tis_spi/ repository is the driver of TPM 2.0. The spidev/ repository is the generic driver of SPI user mode.
/sys/bus/spi/devices/spi0.0/
            /
            /drivers/tpm_tis_spi/spi0.0/
            /drivers/spidev/...
/sys/class/spi_master/spi0/spi0.0
                     /spi1/
                     /spi2/

devfs

If the spidev driver is compiled into the kernel, the repository /dev contains all SPI device entries. They are numbered spix.y where:

  • 'x' is the SPI bus number
  • 'y' is the chip select index on the bus.

Unlike i2c-dev which allows full access to the I2C bus, the spidev offers direct access to the SPI device identified by its chip select signal defined in the device tree node.

Below example shows user mode SPI device on SPI bus 4, chipselect 2.

/dev/spi4.2

For more information, please refer to the spidev documentation [3].

Source code location

References

<securetransclude src="ProtectedTemplate:PublicationRequestId" params="10615 | 2019-02-04 | AnneJ"></securetransclude> <securetransclude src="ProtectedTemplate:ArticleBasedOnModel" params="Framework overview article model"></securetransclude>