SPI驱动模型框架及spidev.c分析---学习记录

目录

SPI设备如何使用

SPI驱动模型框架

[SPI 控制器/SPI Master分析](#SPI 控制器/SPI Master分析)

[SPI 设备端/SPI Slave分析](#SPI 设备端/SPI Slave分析)

[SPI 控制器/SPI Master与SPI 设备端/SPI Slave驱动模型](#SPI 控制器/SPI Master与SPI 设备端/SPI Slave驱动模型)

[Linux内核自带的SPI 设备端/SPI Slave代码spidev.c](#Linux内核自带的SPI 设备端/SPI Slave代码spidev.c)

小结


SPI设备如 何使用

一般我们使用spi设备驱动是类似文件操作,使用open/read/write/ioctl这些去控制/dev/spix.x,而/dev/spix.x是spi设备驱动实现的。而spi 控制器驱动实现的则是从设备树解析出spi 控制器与设备端的映射关系,并且实现传输接口。

SPI驱动模型框架

SPI驱动分成两部分:SPI控制器或者叫SPI Master,SPI 设备端或者SPI Slave。

先看设备树节点:

复制代码
&ecspi3 { 
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_ecspi3>;
    cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
    status = "okay";
    
    
    spidev: icm20608@0{
        compatible = "invensense,icm20608";
        interrupt-parent = <&gpio1>;
        interrupts = <1 1>;
        spi-max-frequency = <8000000>; 
        reg = <0>; 
    };
};

ecspi3是控制器节点,在这之下有一个spi设备节点(spidev: icm20608@0)。

那么我们要写驱动应该怎么写呢?猜想应该是要分别实现SPI 控制器以及SPI 设备端。

SPI 控制器/SPI Master分析

如上设备树节点,在设备树的结构里spi控制器为大节点,然后在其内部创建spi设备节点,如下图设备树节点事例。

使用platform总线驱动用来与设备树中的SPI 控制器节点进行匹配,在下图中platform device自然是从设备树中获取,platform driver我们用module_platform_driver或者platform_driver_register来注册。并通过设备树中的compatible属性匹配。最后进入到probe函数中做下一步处理(如下图中的spi_gpio_probe)

这里以spi-imx.c(实现的是SPI 控制器的驱动代码)代码分析:

用一句话概括就是做了三件事:

1.创建spi_master,这个结构体里包含有传输数据的实现。

2.解析出SPI 控制器节点下的所有设备节点,创建spi_device与每一个设备节点对应.

3.映射spi_master与spi_device关系,并初始化硬件信息,实现传输数据。

具体如下:

在spi_imx_probe函数中用spi_alloc_master创建一个spi_master结构体,然后spi_bitbang_start-->spi_register_master---->of_register_spi_devices函数中把设备树中的每一个spi控制器节点下的设备节点(如上图gpio_spi)创建spi_device结构体,这样spi_device与spi_master(如上图的spi3)就有了映射关系,以后操作设备节点的时候,就可以通过spi_device设备节点找到与之对应的spi_master,然后调用spi_master里的传输接口来传输数据。具体传输数据是如何实现的可以在spi-imx.c查看下面设置的3个接口实现

1.spi_imx_probe-->(spi_imx->bitbang.txrx_bufs = spi_imx_transfer;)

2.spi_imx_probe-->spi_bitbang_start-->(master->transfer_one = spi_bitbang_transfer_one;)

3.spi_imx_probe-->spi_bitbang_start-->spi_register_master--> spi_master_initialize_queue-->(master->transfer_one_message = spi_transfer_one_message;)

SPI 设备端/SPI Slave分析

设备端这块就相对简单,因为在SPI 控制器的驱动里已经实现了获取设备端的节点,也就是实现了下图中spi总线下的spi_device,所以我们使用spi_register_driver注册spi_driver结构体,然后实现file_operations结构体的open/read/write/ioctl,这块linux自带的spidev.c已经实现了。

SPI 控制器/SPI Master与SPI 设备端/SPI Slave驱动模型

如下图,类似在SPI 控制器驱动代码下的probe分枝下挂载SPI 设备端驱动代码

Linux内核自带的SPI 设备端/SPI Slave代码spidev.c

spidev.c实现的就是常规的字符设备驱动,调用spi_register_driver注册spi_driver结构体。

只要你在设备树文件里SPI控制器节点下的设备节点里的compatible = "rohm,dh2228fv";如下图

那么就能与SPI 控制器驱动代码里spi_device匹配到,这样就会进入spidev_probe里创建/dev/spix.x。以后当你open的时候,就会获取到SPI 控制器驱动代码里的spi_device,然后用spi_master进行数据传输。

小结

可以看出spidev.c的作用相当于创建一个字符设备然后与设备树里SPI控制器下的设备节点匹配。

这块之所以能够与任何SPI设备通用,就是因为分离出了SPI 控制器的驱动,我们只需要实现SPI 控制器需要做的事情就好。

相关推荐
l1t8 分钟前
用split命令恢复被wget -c命令误追加的zip压缩包
linux
辉灰笔记1 小时前
MySQL8 意外关机/误移data目录导致服务启动失败 PID报错/权限报错 修复文档
linux·数据库·mysql·centos
ylscode3 小时前
CVE-2026-31694 漏洞深度分析:Linux 内核 FUSE 组件存在本地提权风险,普通用户可直取 root 权限
linux·运维·服务器
无足鸟ICT4 小时前
【RHCA+】bash命令
linux·开发语言·bash
weixin_307779134 小时前
Linux下Docker Compose里运行的MySQL数据库故障诊断Shell脚本
linux·运维·mysql·docker·自动化
小生不才yz4 小时前
Shell脚本精读 · S14-02 | 脚本模板:从 20 行工具到可维护项目
linux
x-cmd4 小时前
Linus 9 年前说「模糊测试有效」——今天已成 OSS-Fuzz 时代铁律
linux·ai·rust·开源·自动化·agent·安全性测试
六点_dn6 小时前
Linux学习笔记-chmod命令
linux·笔记·学习
编程令我快乐6 小时前
windows单次传linux文件太大
linux·运维·服务器
AOwhisky6 小时前
Python 基础语法(上篇 + 下篇)——综合自测题
linux·windows·python