“SPI overview”的版本间的差异
(未显示2个用户的8个中间版本) | |||
第1行: | 第1行: | ||
− | [[ | + | 本文提供有关 Linux<sup>®</sup> SPI框架和STM32 SPI驱动程序安装的基本信息。 |
− | + | 它说明了如何使用SPI,更具体地说: | |
− | + | * 如何在 Linux<sup>®</sup> BSP上激活SPI接口 | |
+ | * 如何从内核空间访问SPI | ||
+ | * 如何从用户空间访问SPI。 | ||
+ | |||
+ | ==Framework purpose== | ||
+ | |||
+ | Linux内核为SPI<ref name="More about SPI">https://en.wikipedia.org/w/index.php?title=Serial_Peripheral_Interface</ref>协议支持提供了特定的框架。 | ||
+ | SPI(串行外围接口)是主要用于嵌入式系统中的短距离通信的同步串行通信接口。<br /> | ||
+ | 该接口由摩托罗拉创建,现在已经变成了行业标准。由于它不是由 I<sup>2</sup>C之类的联盟定义的,因此存在不同的信号名称和信号极性模式。<br /> | ||
+ | SPI器件使用具有单个主机的主从结构,以全双工,半双工或单工(rx / tx)模式进行通信。 | ||
+ | Linux内核SPI框架为SPI主站(Linux内核在总线上启动SPI消息传递)提供了完整的支持,最近又为SPI从站(Linux内核对总线主站的请求做出了响应)提供了完整的支持。 | ||
+ | |||
+ | 有关Linux内核SPI框架的简介,请参见<ref name="SPI introduction">https://bootlin.com/doc/training/linux-kernel/</ref> 。 | ||
+ | ==System overview== | ||
+ | 用户可以在微处理器设备周围添加许多SPI外部设备,以创建定制板。 可以通过SPI从用户空间或内核空间访问每个外部设备。 | ||
+ | |||
+ | [[File:spi-overview-new.png|center|link=]] | ||
+ | |||
+ | ===Component description=== | ||
+ | ====Board external SPI devices==== | ||
+ | 从设备“ X”是物理设备(通过SPI总线连接到STM32微处理器),相对于STM32而言,它们是从设备。 <br/>STM32是SPI总线主设备。<br/> 芯片选择信号允许独立选择每个从设备。 | ||
+ | ====STM32 SPI internal peripheral controller==== | ||
+ | |||
+ | STM32 SPI控制器可处理连接到同一总线的所有外部SPI设备。 <br/> | ||
+ | STM32微处理器设备通常嵌入 [[SPI internal peripheral]] 的多个实例,以管理多个SPI总线。<br/> | ||
+ | 有关STM32 SPI内部外设的更多信息,请参考 [[SPI_internal_peripheral#SPI_main_features]] | ||
+ | |||
+ | ====spi-stm32==== | ||
+ | STM32 SPI控制器驱动程序为spi内核提供了一个ST SPI内部外围抽象层。<br/> 它定义了SPI内核库使用的所有SPI传输方法。<br/> | ||
+ | STM32 SPI控制器驱动程序仅支持SPI主模式。<br/> | ||
+ | |||
+ | ====spi-core==== | ||
+ | '''{{Highlight|spi-core}}''' 是“交流的大脑”: 它实例化并管理所有总线和外围设备。 | ||
+ | * 顾名思义,这就是SPI引擎。 它还负责解析适配器和设备的设备树条目。 它实现了标准的SPI模式: 0, 1, 2 and 3. | ||
+ | |||
+ | ====Slave device drivers==== | ||
+ | 该层表示与物理外围设备关联的所有驱动程序。<br/> | ||
+ | |||
+ | ====spidev==== | ||
+ | "spidev" 是用户和外围设备之间的接口。 | ||
+ | 这是一个内核驱动程序,它使用此dev接口API提供对用户空间应用程序的统一SPI总线访问。 | ||
+ | 有关示例,请参见[[SPI overview#API_description|API Description]] 。 | ||
+ | |||
+ | ====Application==== | ||
+ | 借助 ''spidev''界面,该应用程序可以控制所有外围设备。 | ||
+ | |||
+ | ===API description=== | ||
+ | ====User space application==== | ||
+ | [[#user_space_application| The user space application]] 使用内核驱动程序(spidev)通过devfs进行SPI传输。<br /> | ||
+ | 让我们以通过芯片选择C连接到总线B的SPI设备为例。“spidev” 驱动程序提供以下接口: | ||
+ | * /dev/spidevB.C: 由“udev”创建的字符特殊设备,用户空间应用程序使用它来控制数据并将其传输到SPI设备。 | ||
+ | |||
+ | '''支持的系统调用: '''open(), close(), read(), write(), ioctl(), llseek(), release().<br /> | ||
+ | {| | ||
+ | |+ 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'''<ref name="dev-interface API">{{CodeSource | Linux kernel | Documentation/spi/spidev}} dev-interface API</ref> for a complete list). | ||
+ | |||
+ | ====Kernel space peripheral driver==== | ||
+ | 内核空间外围设备驱动程序与SPI设备通信,并使用以下 '''SPI核心API''' : <ref name="SPI core API">https://www.kernel.org/doc/html/latest/driver-api/spi.html</ref> | ||
+ | |||
+ | ==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’ 内核配置文件选择)中。<br/> | ||
+ | {{Info| 如果从设备参与引导过程,则支持该设备所需的驱动程序将被视为至关重要,并且必须内置在内核中}} | ||
+ | |||
+ | ===Device tree configuration=== | ||
+ | 请参考 [[SPI device tree configuration]]. | ||
+ | |||
+ | ==How to use the framework== | ||
+ | Linux内核文档中提供了有关如何编写SPI从驱动程序以控制SPI设备的详细信息。<ref name="Linux kernel SPI framework summary">{{CodeSource | Linux kernel | Documentation/spi/spi-summary}} Linux kernel SPI framework summary</ref>.<br/> | ||
+ | {{UnderConstruction | 更多示例即将推出}} | ||
+ | |||
+ | ==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]].<br/> | ||
+ | |||
+ | [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文件。<br/> | ||
+ | |||
+ | {{Info|提醒:需要通过控制台使用引导参数或“ dmesg -n 8”命令将“ loglevel”增加到8}} | ||
+ | |||
+ | ====Dynamic trace==== | ||
+ | 有关详细的动态跟踪信息,请参阅 [[How to use the kernel dynamic debug]]<br/> | ||
+ | {{Board$}} echo "file spi* +p" > /sys/kernel/debug/dynamic_debug/control | ||
+ | 该命令在运行时启用与SPI内核和驱动程序相关的所有跟踪。<br/> | ||
+ | 通过只选择要跟踪的文件,可以进行更精细的选择。<br/> | ||
+ | |||
+ | {{Info|提醒:需要通过控制台使用引导参数或“ dmesg -n 8”命令将“ loglevel”增加到8}} | ||
+ | |||
+ | ===How to debug=== | ||
+ | ====Detecting SPI configuration==== | ||
+ | =====sysfs===== | ||
+ | 实例化外围设备时,spi-core和内核会通过sysfs导出多个文件:<br /> | ||
+ | * '''/sys/class/spi_master/spix''' 显示所有实例化的SPI总线, ''''x'''' 是SPI总线编号。 | ||
+ | {{Warning|'x'可能与SPI内部外设索引不匹配,因为它取决于器件的探测顺序。}} | ||
+ | * '''/sys/bus/spi/devices''' 列出了所有实例化的外围设备。例如,名为 '''spi0.0''' 的存储库对应于连接到SPI总线0和芯片选择0的外设。 下面是代表“TPM”设备的示例:<br /> | ||
+ | * '''/sys/bus/spi/drivers''' 列出所有实例化的驱动程序。'''tpm_tis_spi/''' 存储库是TPM 2.0的驱动程序。 '''spidev/'''存储库是SPI用户模式的通用驱动程序。<br/> | ||
+ | |||
+ | <pre> | ||
+ | /sys/bus/spi/devices/spi0.0/ | ||
+ | / | ||
+ | /drivers/tpm_tis_spi/spi0.0/ | ||
+ | /drivers/spidev/... | ||
+ | </pre> | ||
+ | |||
+ | <pre> | ||
+ | /sys/class/spi_master/spi0/spi0.0 | ||
+ | /spi1/ | ||
+ | /spi2/ | ||
+ | </pre> | ||
+ | |||
+ | ====devfs==== | ||
+ | 如果将“spidev”驱动程序编译到内核中,则存储库'''/ dev'''将包含所有SPI设备条目。它们被编号为spi'''x.y'''其中: | ||
+ | * “ x”是SPI总线号 | ||
+ | * “ y”是总线上的芯片选择索引。 | ||
+ | |||
+ | 与允许完全访问I<sup>2</sup>C总线的i2c-dev不同,“ spidev”可直接访问由设备树节点中定义的芯片选择信号标识的SPI设备。<br/> | ||
+ | |||
+ | 下面的示例显示了SPI总线4(芯片选择2)上的用户模式SPI设备。<br/> | ||
+ | |||
+ | <pre> | ||
+ | /dev/spi4.2 | ||
+ | </pre> | ||
+ | 有关更多信息,请参考spidev文档 <ref name="dev-interface API">{{CodeSource | Linux kernel | Documentation/spi/spidev}} dev-interface API</ref>. | ||
+ | |||
+ | ==Source code location== | ||
+ | * The SPI framework is available under {{CodeSource | Linux kernel | drivers/spi}} | ||
+ | * The STM32 SPI driver is available under {{CodeSource | Linux kernel | drivers/spi/spi-stm32.c}} | ||
+ | * The user API for the SPI bus is available under {{CodeSource | Linux kernel | include/linux/spi/spi.h}} and SPI dev is {{CodeSource | Linux kernel | include/uapi/linux/spi/spidev.h}}. | ||
+ | |||
+ | ==References== | ||
+ | <references /> |
2020年11月8日 (日) 15:06的最新版本
本文提供有关 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从用户空间或内核空间访问每个外部设备。
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().
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’ 内核配置文件选择)中。
如果从设备参与引导过程,则支持该设备所需的驱动程序将被视为至关重要,并且必须内置在内核中 |
Device tree configuration
How to use the framework
Linux内核文档中提供了有关如何编写SPI从驱动程序以控制SPI设备的详细信息。[5].
更多示例即将推出 |
{{#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文件。
提醒:需要通过控制台使用引导参数或“ 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内核和驱动程序相关的所有跟踪。
通过只选择要跟踪的文件,可以进行更精细的选择。
提醒:需要通过控制台使用引导参数或“ dmesg -n 8”命令将“ loglevel”增加到8 |
How to debug
Detecting SPI configuration
sysfs
实例化外围设备时,spi-core和内核会通过sysfs导出多个文件:
- /sys/class/spi_master/spix 显示所有实例化的SPI总线, 'x' 是SPI总线编号。
'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
- The SPI framework is available under drivers/spi| |}} drivers/spi
- The STM32 SPI driver is available under drivers/spi/spi-stm32.c| |}} drivers/spi/spi-stm32.c
- The user API for the SPI bus is available under include/linux/spi/spi.h| |}} include/linux/spi/spi.h and SPI dev is include/uapi/linux/spi/spidev.h| |}} include/uapi/linux/spi/spidev.h .
References
- ↑ https://en.wikipedia.org/w/index.php?title=Serial_Peripheral_Interface
- ↑ https://bootlin.com/doc/training/linux-kernel/
- ↑ 3.03.1 Documentation/spi/spidev| |}} Documentation/spi/spidev dev-interface API
- ↑ https://www.kernel.org/doc/html/latest/driver-api/spi.html
- ↑ Documentation/spi/spi-summary| |}} Documentation/spi/spi-summary Linux kernel SPI framework summary