当前位置:首页>Linux>Linux SPI子系统与驱动开发实战指南(建议收藏)

Linux SPI子系统与驱动开发实战指南(建议收藏)

  • 2026-10-12 08:18:04
Linux SPI子系统与驱动开发实战指南(建议收藏)

SPI是嵌入式开发中最常见的高速通信协议,广泛应用于Flash存储、显示屏、传感器等外设。本文系统讲解SPI协议基础、子系统架构、驱动开发实战和调试技巧,帮你快速掌握SPI驱动开发。

一、SPI协议基础

🖥️ SPI四线制

SCLKMOSIMISOCS/SS
时钟信号
(主机产生)
主机输出
从机输入
主机输入
从机输出
片选信号
(低电平有效)

💡 全双工 vs I2C:SPI支持全双工通信(同时发送和接收),而I2C是半双工。这是SPI速度更高的原因之一。

🔄 SPI四种模式

模式
CPOL
CPHA
说明
Mode 0
0
0
空闲低,第一边沿采样
Mode 1
0
1
空闲低,第二边沿采样
Mode 2
1
0
空闲高,第一边沿采样
Mode 3
1
1
空闲高,第二边沿采样

二、SPI子系统架构

🏗️ 核心架构

🟢 spi_master
主机控制器
→
🔵 SPI核心层
管理调度
→
🟠 spi_device
spi_driver
从设备+驱动

📦 核心数据结构

// SPI主机
struct spi_master {
struct device dev;
u16 bus_num;              // 总线编号
u16 num_chipselect;       // 片选数量
u32 max_speed_hz;         // 最大时钟
int (*transfer_one)(struct spi_master*, struct spi_device*, struct spi_transfer*);
};

// SPI设备
struct spi_device {
struct spi_master *master;
u32 max_speed_hz;
u8 chip_select;
u16 mode;
};

// SPI传输
struct spi_transfer {
const void *tx_buf;    // 发送缓冲
void *rx_buf;    // 接收缓冲
unsigned len;
u32 speed_hz;
};

三、设备树配置

&spi0 {
    status = 
"okay";

/* SPI Flash */
spi_flash:flash@0 {
        compatible = 
"jedec,spi-nor";
        reg = <
0>;                    // 片选0
        spi-max-frequency = <50000000>; // 50MHz
    };

/* OLED显示屏 */
oled@1 {
        compatible = 
"solomon,ssd1306";
        reg = <
1>;
        spi-max-frequency = <
10000000>;
    };
};

四、SPI传输API

⚡ 常用API速查

API函数
说明
spi_write(spi, buf, len)
单次发送
spi_read(spi, buf, len)
单次接收
spi_sync(spi, message)
同步传输消息
spi_async(spi, message)
异步传输消息

五、SPI驱动开发实战

🔧 SPI Flash驱动框架

/* 读取Flash ID */
static int spi_flash_read_id(struct spi_device *spi)
{
u8 tx_buf[1] = { 0x9F };
u8 rx_buf[3];
return spi_write_then_read(spi, tx_buf, 1, rx_buf, 3);
}

/* probe函数 */
static int spi_flash_probe(struct spi_device *spi)
{
    data = devm_kzalloc(&spi->dev, 
sizeof(*data), GFP_KERNEL);
    data->spi = spi;
    spi_set_drvdata(spi, data);
    spi_flash_read_id(data);
return0;
}

/* 驱动注册 */
static struct spi_driver spi_flash_driver = {
    .probe  = spi_flash_probe,
    .remove = spi_flash_remove,
    .driver = {
        .name = 
"spi_flash",
        .of_match_table = spi_flash_of_match,
    },
};
module_spi_driver(spi_flash_driver);

六、调试技巧

🛠️ 用户空间调试

# 安装工具
apt install spidev-tools

# 查看SPI设备
ls /dev/spidev*

# 传输测试
spidev_test -D /dev/spidev0.0 -v

🔍 内核调试

# 查看SPI设备
ls /sys/bus/spi/devices/

# 查看SPI驱动
ls /sys/bus/spi/drivers/

# 查看内核日志
dmesg | grep -i spi

七、SPI vs I2C对比

特性
SPI
I2C
通信方式
全双工
半双工
速度
高(MHz级)
低(KHz级)
线数
4线
2线
多从机
需要多个CS
地址寻址
适用场景
Flash、显示屏
传感器、EEPROM

八、核心要点总结

📌 SPI核心要点:

  • 四线制:SCLK、MOSI、MISO、CS
  • 四种模式:CPOL+CPHA组合决定采样边沿
  • 核心API:spi_write/spi_read/spi_sync/spi_async
  • 设备树:spi-max-frequency设置时钟频率

最新文章

随机文章