1. 学习目标

  1. 理解 SPI 总线工作原理

理解 SPI 通信结构:

Master
Slave
MOSI
MISO
CS

  • 理解 Linux SPI 子系统架构

理解 Linux SPI 驱动结构:

spi_controller
spi_device
spi_drive

  • 理解 SPI 驱动匹配机制

理解 Linux 如何匹配:

spi_device <-> spi_driver

并触发:

probe()

  • 能编写简单 SPI 驱动

掌握核心 API:

spi_register_driver
spi_sync
spi_write
spi_read

  • 能调试 SPI 设备

理解 SPI 数据传输:

spi_message
spi_transfer

2. SPI 总线简介

SPI 是一种:

高速同步串行通信总线

信号线:

SCLK   时钟
MOSI   Master Out Slave In
MISO   Master In Slave Out
CS     Chip Select

结构:

        Master
           
           
   ┌───────┼────────┐
                  
Slave1   Slave2   Slave3

特点:

全双工
高速
主从结构

3. Linux SPI 子系统架构

Linux SPI 子系统结构:

SPI Device Driver
        
        
      spi_core
        
        
   SPI Controller Driver
        
        
       Hardware

核心对象:

spi_controller
spi_device
spi_driver

4. spi_controller

spi_controller 表示:

SPI 控制器

例如:

SoC SPI Controller

结构:

struct spi_controller
{
    struct device dev;
    int (*transfer)(struct spi_controller *, struct spi_message *);
};

作用:

实现 SPI 硬件控制

例如:

发送时钟
读写数据
控制 cs

5. spi_device

spi_device 表示:

SPI 设备

例如:

SPI FLash
ADC
DAC
LCD 控制器

结构:

struct spi_device
{
    struct spi_controller *controller;
    u32 max_speed_hz;
    u8 chip_select;
};

关键成员:

chip_select

表示:

SPI 设备片选

6. spi_driver

spi_driver 表示:

SPI 设备驱动

结构:

struct spi_driver
{
    int (*probe)(struct spi_device *);
    int (*remove)(struct spi_device *);

    struct device_driver driver;
};

核心函数:

probe
remove

7. SPI 驱动匹配机制

Linux 会匹配:

spi_device
spi_driver

匹配成功后:

probe()

被调用。

流程:

spi_device register
        
spi_driver register
        
match
        
probe()

匹配方式 通常通过:

device tree compatible

例如:

compatible = "my-spi-device";

驱动:

static const struct of_device_id my_spi_match[] =
{
    { .compatible = "my-spi-device" },
    { }
};

8. SPI 驱动注册

驱动注册:

spi_register_driver()

示例:

static struct spi_driver my_driver =
{
    .probe = my_probe,
    .remove = my_remove,
};

注册:

module_spi_driver(my_driver);

9. SPI 数据传输

SPI 传输使用:

spi_message
spi_transfer

结构:

spi_message
    
    └── spi_transfer

spi_transfer

表示一次 SPI 传输:

struct spi_transfer
{
    const void *tx_buf;
    void *rx_buf;
    unsigned int len;
};

spi_message

表示一组 SPI 传输:

struct spi_message
{
    struct list_head transfers;
};

10. SPI 传输示例

发送数据

spi_write(spi, buf, len);

读取数据:

spi_read(spi, buf, len);

全双工:

spi_sync(spi, &message);

11. 驱动示例

简单 SPI 驱动:

static int my_spi_probe(struct spi_device *spi)
{
    printk("spi device detected\n");

    spi_write(spi, "hello", 5);

    return 0;
}

static struct spi_driver my_driver =
{
    .driver =
    {
        .name = "my_spi",
    },
    .probe = my_spi_probe,
};

module_spi_driver(my_driver);

12. Device Tree 描述 SPI 设备

SPI 设备通常通过 Device Tree 描述。

示例:

&spi1
{
    mydevice@0
    {
        compatible = "my-spi-device";
        reg = <0>;
        spi-max-frequency = <1000000>;
    };
};

解释:

spi bus = spi1
chip select = 0
max speed = 1MHz

13. SPI 子系统结构总结

SPI 子系统结构:

SPI Device Driver
        
        
      spi_core
        
        
   spi_controller
        
        
      Hardware

设备关系:

spi_controller
      
      ├── spi_device
      
      └── spi_driver

14. 驱动常见问题

probe 没有调用 原因:

compatible 不匹配

SPI 数据错误

原因:

SPI mode 不一致

例如:

CPOL
CPHA

SPI 设备无法通信

原因:

CS 配置错误

15. 总结

Linux SPI 子系统核心结构:

spi_controller
spi_device
spi_driver

关系:

spi_controller
      
      ├── spi_device
      
      └── spi_driver

匹配成功:

probe()

最重要原则:

SPI 驱动 = Device Model + SPI Bus

16. Q&A

16.1 总线理解

  1. SPI 和 I2C 的区别是什么?

  2. SPI 为什么更快?


16.2 Linux 架构

  • spi_controller 表示什么?

  • spi_device 表示什么?


16.3 驱动流程

  • spi_driver 的 probe 为什么会被调用?

  • spi_message 和 spi_transfer 的区别?