增加序号和目录.

Signed-off-by: lion.chan <cy187lion@sina.com>
This commit is contained in:
lion.chan 2022-09-06 09:36:45 +08:00
parent f878b0b1af
commit d1418f8502
1 changed files with 22 additions and 11 deletions

View File

@ -4,14 +4,25 @@ title: "Linux SPI 子系统"
subtitle: "基于 x86 平台"
description: "Linus 内核 SPI 子系统介绍。"
excerpt: "本文重点在于理清与 SPI 有关的相关概念和 SPI 子系统的初始化的流程。"
date: 2020-01-17 13:18:00
date: 2022-09-06 09:32:00
author: "Rick Chan"
tags: ["Kernel", "SPI"]
categories: ["Software"]
published: true
---
## 前言
- [1. 前言](#1-前言)
- [2. 总述](#2-总述)
- [3. SPI 硬件系统与软件抽象之间的关系](#3-spi-硬件系统与软件抽象之间的关系)
- [4. SPI 驱动的 Probe 和 Match 过程](#4-spi-驱动的-probe-和-match-过程)
- [4.1. SPI Board Info](#41-spi-board-info)
- [4.2. 从设备驱动的 Match 和 Probe 过程](#42-从设备驱动的-match-和-probe-过程)
- [5. SPI 核心层](#5-spi-核心层)
- [6. 对于开发的一些简单指导](#6-对于开发的一些简单指导)
- [7. 总结](#7-总结)
- [8. 外部参考资料](#8-外部参考资料)
## 1. 前言
写文在于交流和传播知识,本人才粗学浅,还请多多指教,板砖轻拍。
@ -19,7 +30,7 @@ published: true
另外,本文主要描述 x86 体系下的 SPI 框架,也可作为 ARM 体系下 SPI 框架的参考,因为两种框架下的概念和原理都是相通的,只是有些地方的具体实现不同。
## 总述
## 2. 总述
SPI 是一种总线通讯协议由总线控制器和从设备构成。Linux SPI 驱动包含两个部分,分别用于驱动 SPI 总线控制器和从设备,内核中的 SPI 子系统为这两种驱动提供了开发框架。
@ -31,7 +42,7 @@ SPI 是一种总线通讯协议由总线控制器和从设备构成。Linux S
接下来将从 SPI 硬件系统与软件抽象之间的关系,以及 SPI 驱动的探测过程两个方面展开说明。
## SPI 硬件系统与软件抽象之间的关系
## 3. SPI 硬件系统与软件抽象之间的关系
电子系统中有很多外设,有像 GPIO 这样简单的设备,也有像 LCD 控制器这样复杂的。有一类特殊的外设,用于实现总线通信,通常以控制器的角色出现,被称为总线控制器,例如 UART 控制器、以太网控制器,以及本文的主角 SPI 控制器。
@ -51,7 +62,7 @@ SPI 通讯离不开 SPI 总线控制器和从设备,因此在 Linux 系统中
了解 Linux SPI 子系统中两个主要角色SPI 控制器驱动和 SPI 从设备驱动)后,就需要知道他们是如何被初始化的,以及如何与具体设备匹配上的,这涉及到 SPI 总线控制器、SPI 从设备的枚举和发现,以及驱动匹配等。
## SPI 驱动的 Probe 和 Match 过程
## 4. SPI 驱动的 Probe 和 Match 过程
有些总线设备是可以自动枚举到的,如 PCI 总线可以通过 BDF总线号 Bus、设备号 Device 和功能号 Function 来枚举设备并通过 Device ID 和 Vendor ID 来匹配驱动程序。然而有很多总线不能自动枚举设备并匹配驱动程序。因此内核提供了几种配置表用于声明某些设备的存在,对于 ARM 平台目前使用 Device Tree而 x86 平台有 ACPI 表,或者干脆以平台设备的形式注册 Board Info。Linux 内核会扫描这些表或已注册的 Board Info并根据其中的信息触发对应驱动程序的 Probe 流程。这个过程由系统内核框架实现的,不需要设备驱动开发人员关心,只需要写好 Device Tree提供好 ACPI 表,或注册好 Board Info 即可,而这一般会有 Demo 可以参考。
@ -61,7 +72,7 @@ SPI 通讯离不开 SPI 总线控制器和从设备,因此在 Linux 系统中
*注x86 系统的平台设备声明在 arch->x86->platform 下。*
### SPI Board Info
### 4.1. SPI Board Info
对于 spi_board_info需要重点关注 bus_num 和 modaliasbus_num 将设备与对应的总线控制器驱动匹配modalias 用于与 SPI 从设备匹配。以下是 spi_board_info 的具体结构,注意每个成员后面的注释:
@ -83,7 +94,7 @@ struct spi_board_info {
接下来,根据 bus_num 和 modalias 分析下从设备驱动的 Match 和 Probe 流程。
### 从设备驱动的 Match 和 Probe 过程
### 4.2. 从设备驱动的 Match 和 Probe 过程
系统启动时,先执行 arch_initcall 中的定义的板级初始化程序,由该程序完成 spi_board_info 的注册,并由此形成一张 SPI 从设备列表。之后,在 x86 平台下,当系统进行 PCI 设备枚举时,将发现 SPI 总线控制器,并调用与之对应的 SPI 总线控制器驱动中的 Probe 程序,该 Probe 程序继续调用 regist 函数来注册 SPI master/controller在这个注册函数中比较当前 SPI 控制器的总线号,如果与 SPI 从设备列表中的总线号对应,则将该从设备挂接到这个控制器上。在 4.19.23 版本内核中,以 pxa2xx 为例,可用以下函数调用关系来描述:
@ -189,11 +200,11 @@ module_exit(spidev_exit);
可以看出,代码一方面注册了 File Operation 方法用于实现用户态访问接口,另一方面则通过其 SPI 控制器来访问和控制实际设备。而从 spi_driver 结构体不难看出spidev 不但可以驱动已注册的 SPI 平台设备,还可以驱动以 Device Tree 或 ACPI 表声明的 SPI 从设备(匹配 Device Tree 或 ACPI 表)。
## SPI 核心层
## 5. SPI 核心层
有了 SPI 总线控制器驱动和 SPI 从设备驱动SPI 子系统就可以工作了。但是我们发现,对于 SPI 子系统,有很多核心的代码是完全通用的,把这些共通代码抽取出来,便构建成了 SPI 核心层。
## 对于开发的一些简单指导
## 6. 对于开发的一些简单指导
基于当前的 SPI 子系统框架,首先要有办法感知或声明 SPI 控制器以及从设备的存在,然后开发对应的驱动程序。
@ -203,13 +214,13 @@ module_exit(spidev_exit);
SPI 控制器驱动一般由芯片供应商或开源社区会提供,下游的开发者只需要实现 SPI 从设备驱动即可。对于 SPI 控制器驱动,可以参考 pxa2xx 这个驱动程序;对于 SPI 从设备驱动可以参考 spidev 这个驱动程序。
## 总结
## 7. 总结
最后晒一张来自网友的大图(来源见图中水印),系统总结了 SPI 子系统的 Probe 过程和各部分的功能:
![SPI 子系统总结](./img/Linux_SPI_子系统_x86平台/004.jpg)
## 外部参考资料
## 8. 外部参考资料
1. [linux设备模型之spi子系统](https://www.cnblogs.com/gdt-a20/archive/2011/05/22/2291983.html)
2. [PXA2xx SPI on SSP driver HOWTO](https://www.mjmwired.net/kernel/Documentation/spi/pxa2xx)