SPI系统学习

    xiaoxiao2021-08-23  77

    grep  "SPI_S3C64XX" * -nR find -name "*.o" -type f 分析SPI子系统 Linux中SPI子系统的初始化时从drivers/spi/spi.c文件中的spi_init函数开始的 分配spi buf内存,其中buf和SPI_BUFSZ都是在spi.c文件中定义: 注册spi总线,同样是spi.c文件中: 总线的名字就叫spi, 比较重要的,spi_match_device是spi总线上匹配设备和设备驱动的函数 写过驱动的都应该知道platform总线有struct platform_device 和 struct platform_driver 到了SPI总线,当然也有对应的struct spi_device和struct spi_driver, dev 嵌入到设备模型中用的 master,spi设备的更高描述,每一个spi控制器就对应一个master,一个spi必须对应一个master, master下可以有多个spi设备。 mode,针对时钟相位CPHA(0或1)和时钟极性CPOL(0或1) driver就是在设备模型中使用的那个device_driver,,其他都是一些函数指针的定义, 回到spi_match_driver函数,91行和95行就是设备和驱动匹配的另外两种方法,因为后文 讲的SPI驱动使用的是第三种方法, 对于具体的平台,nand,iic,frame buffer 等这些都是平台设备,spi当然也一样是平台设备 对于平台设备,大部分情况下是先注册设备在注册驱动。 前面简要讨论了如何构建和运行SPI,使得大家对如何用SPI有了一个基本的了解,下面我们 将深入SPI内部的运行机制的讨论。 同样,我们将从系统运行时的对象开始讨论,而这又离不开对sturct的分析,以及系统运行时 的内核对SPI队形的分析 我们首先从spi.h文件中定义了的各个struct对象开始分析 在这个文件中定义了如下结构 spi_device,spi_driver,spi_master,spi_transfer,spi_message,spi_board_info spi_device 是SPI从设备,即连接在SPI总线上的外围设备 spi_driver 是SPI主机边的协议驱动 spi_master 是spi控制器,即s3c6410中的spi端口的软件控制器 spi_transfer :a read/write buffer pair struct spi_message: one M\multi-segment SPI transaction 在spidev.h中定义了如下结构 struct spi_ioc_transfer-describes a single SPI transfer 从这个注释中可以知道这个结构是对内核中的spi_transfer的映射 这个函数生成了一个 spi_message 和一个spi_transfer 并把他们加入到了一个传输队列中,spi_message_init 函数就不细讲了,就是初始化spi_message 的结构而spi_message_add_tail函数做了什么工作呢?是将spi_transfer加入到spi_message的传输任务刘表 即spi_transfer其实是一个院子的传输任务单元 最终由spidev_sync 负责执行,这个函数是同步执行的所以函数内部由异步执行的 status = spi_async(spidev->spi,message); 和wait_for_completion(&done);转换为同步执行 我们再看spi_async函数都做了什么? 它执行了一个内部函数 ret = __spi_async(spi,message); 这个内部函数真正的传输动作是master->transfer(spi,message); 而我们追踪到这里发现api_master结构中transfer仅仅是一个预定义的函数指针 platform_device从字面理解就是平台设备,注意它内含了一个名为dev的device 我们分析一下这个结构,包含了kobject对象,file_operations函数结构体,kobject我们都知道 这是linux文件系统结构中最重要的结构,用来表示文件对象 我们先搁下handle_msg不表,先来回一下这个过程,可以发现整个过程是这样的,具体的传输 任务其实最后都是由芯片厂商提供的代码完成,而linux团队负责定制了spi的用户标准,并为 芯片厂商制定了向下的接口标准,这就是linux内核负责的核心负责的核心负责工作,它与架构无关的 他负责定制标准,芯片厂商根须linux内核的标准,又提供了一些芯片相关的基础设施 而由主板厂商负责进行设备的组装。最终完成了spi控制器和spi从设备在内核中的安装工作 包括静态的数据结构和动态的函数功能的组装 linux内核研发团队,芯片厂商,主板厂商,应用厂商 exynos_device_spi0 Dev-spi.c 目录 arch\arm\mach-exynos static struct s3c64xx_spi_csinfo spi0_csi[]   mach-tiny4412.c     目录 spi_board_info mach-tiny4412.c  spidev_spi_driver spidev.c文件中定义:driver\spi spi_master_class spi.c     driver\spi spi_init spi.c     driver\spi 接下来介绍SPI目录下的各个对象的定义 spi-sunmmary.txt是必须阅读的参考文档 从spi目录可以看出这是与平台无关的,也就是linux对linux对spi接口进行抽象,形成的用户层相关代码 而platform下面的代码是具体进行工作的代码,他们与平台相关,而spi代码是与用户空间接口相关的代码 他必须与平台无关,即平台如何更换过,对用户空间的接口都是一致的,这就是linux设备驱动架构的精髓 我们注意到spi目录下只有一个spidev的驱动,其他都是指向platform下的设备衔接 git clone https://github.com/friendlyarm/linux-3.4.y.git cd linux-3.4.y git checkout nanopi2-lollipop-mr1
    转载请注明原文地址: https://ju.6miu.com/read-676931.html

    最新回复(0)