linuxspi子系统驱动程序结构分析

上传人:w****i 文档编号:106647460 上传时间:2019-10-15 格式:PDF 页数:9 大小:202.17KB
返回 下载 相关 举报
linuxspi子系统驱动程序结构分析_第1页
第1页 / 共9页
linuxspi子系统驱动程序结构分析_第2页
第2页 / 共9页
linuxspi子系统驱动程序结构分析_第3页
第3页 / 共9页
linuxspi子系统驱动程序结构分析_第4页
第4页 / 共9页
linuxspi子系统驱动程序结构分析_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《linuxspi子系统驱动程序结构分析》由会员分享,可在线阅读,更多相关《linuxspi子系统驱动程序结构分析(9页珍藏版)》请在金锄头文库上搜索。

1、Linux SPI 子系统驱动程序结构分析 关键之:SPI、framework、platform、driver、device Linux SPI 这个子系统系列的介绍会在 linux 驱动模型的基础上进行阐述,会偏重于 framework的介绍, 对于大牛可能会对这类文章不屑, 但本系列仅当是一个知识备忘, 当linux 体系这张大网织的差不多了,会有一个全新的系列,来去繁就简,成之经典,毕竟,现阶段, 对这些的感悟还不是太深,将原来的工作内容进行回忆,将现在工作碰到的问题补充,下一 阶段会有更深的体会的。 由于这是这个系统的第一篇文章,可能零碎的东西介绍的会多些。 0,分层与分离 在面向对象

2、的程序设计中, 可以为某一类相似的事物定义一个基类, 而具体的事物可以继承 这个基类中的函数。Linux 内核中频繁使用到面向对象的设计思想。在设备驱动方面,往往 为同类的设备设计了一个框架, 而框架中的核心层则实现了该设备通用的一些功能。 而且具 体的设备不想使用核心层的函数, 它可以重载之。 这就是我们所说的在驱动设计中的分层思 想。 此外,在驱动的设计中,我们还会使用分离的思想。如果一个设备的驱动和 host 的驱动休 戚相关,那么,这就意味着这个普通的设备如果用在不同的 host 上,会采用 n 个版本的驱 动。如果产品单一,也许感觉不到不使用分离思想来设计驱动的危害,但是我们想一下,

3、这 个世上被人们称道的多是什么?精品,艺术品!精品如何打造?注重细节,不只考虑单一需 求!大家开发个东西不容易,怎么能随随便便就让它茫然众码矣呢,所以,何时何地,我们 都要以打造精品的思想来要求自己,让自己的劳动力不浪费。 使用分离的思想来设计驱动的话,就够就是这样的: 外设驱动与主机控制器的驱动不相关, 主机控制器的驱动不关心外设, 而外设驱动也不关心 主机, 外设只是访问核心层的通用 API 进行数据传输, 主机和外设之间可以进行任意的组合。 相当于在控制器驱动和设备驱动之间增加一层核心层,对内对外都隐藏了对端的不确定性。 仔细通读 USB,SPI,PCI 的代码就会发现这种思想的体现。

4、1,设备模型 在最新的设备驱动模型中,主要包含总线、设备和驱动三个实体,总线将设备和驱动绑定, 在系统每注册一个设备的时候,会寻找与之匹配的驱动,反之,在系统每注册一个驱动的时 候,会寻找与之匹配的设备,而匹配由总线完成。 所以,因此,由是之(之所以写这么多,是因为自己在理解这个设备模型的时候,对照代码 产生很多疑问,特别是在这儿。现在回过头来看,觉得很显而易见的啊,:)看来那个什么 Q 还是有些问题),根据这个模型的需求,一个现实的 linux 设备和驱动通常都需要挂接在一 种总线上,否则谁来管他们的匹配啊,注册驱动和注册设备都是由不同的 API 来完成的。对 于本身依附于 PCI,USB,

5、I2C,SPI 等的设备而言,这自然不是问题,但是在嵌入式系统里 面,Controller 系统中集成的外设控制器,挂载在内存空间的外设确不依附于此类总线。那 Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 咋整呢?而且这些东西还不少,像 SPI 控制器,PCI 控制器啊都是这些,这些很多都已经是 主了,还让他们靠谁去?基于这一背景,Linux 发明了一种虚拟的总线(就是我们所说的除 了政治领袖以外的精神领袖),称为 platform 总线,相应的设备称为 platform_device,而 驱动称为 platf

6、orm_driver。 2,platform 总线 这个框架中为 platform 总线定义了一个 bus_type 的实例 platform_bus_type: 1 struct bus_type platform_bus_type = 2 .name = “platform”, 3 .dev_attrs = platform_dev_attrs, 4 .match = platform_match, 5 .uevent = platform_uevent, 6 .pm = PLATFORM_PM_OPS_PTR, 7 ; 8 EXPORT_SYMBOL_GPL(platform_bus_t

7、ype); 这里重点关注其 match 成员函数,正是此成员表明了 platform_device 和 platform_driver 之间如何匹配。 1 static int platform_match(struct device *dev, struct device_driver *drv) 2 3 struct platform_device *pdev; 4 5 pdev = container_of(dev, struct platform_device, dev); 6 return (strncmp(pdev-name, drv-name, BUS_ID_SIZE) = 0)

8、; 7 从代码中可以看出,匹配 platform_device 和 platform_driver 主要看两者的 name 字段是否 相同。 对 platform_device 的定义通常在 BSP 包里面实现(即 arch 目录下的),在 BSP 文件中, 将 platform_device 归纳为一个数组,最终通过 platform_add_devices()函数统一注册。 platform_add_devices()函数可以讲平台设备添加到系统中。 3,SPI 讲了这么多才说道 SPI,看来老婆没有说错我啊,罗里啰嗦因为该文档权当备忘,所以 接下来还会罗嗦几句 SPI 的缘由 3.1 w

9、hat is SPI SPI(同步外设接口)是由摩托罗拉公司开发的全双工同步串行总线,其接口由 MISO(串 行数据输入),MOSI(串行数据输出),SCK(串行移位时钟),SS(从使能信号)四种 信号构成(当然了,现在芯片技术日新月异,SPI 模块的结构也在变化中,象 OMAP 系列中 的 SPI 模块还支持 5 线的一种模式),SS 决定了唯一的与主设备通信的从设备,主设备通 Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 过产生移位时钟来发起通讯。通讯时,数据由 MOSI 输出,MISO 输入,数据在时钟的

10、上升 或下降沿由 MOSI 输出,在紧接着的下降或上升沿由 MISO 读入,这样经过 8/16 次时钟的 改变,完成 8/16 位数据的传输。 SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性(CPOL) 和相位(CPHA)可以进行配置。如果 CPOL=0,串行同步时钟的空闲状态为低电平;如果 CPOL=1,串行同步时钟的空闲状态为高电平。如果 CPHA=0,在串行同步时钟的第一个跳 变沿(上升或下降)数据被采样;如果 CPHA=1,在串行同步时钟的第二个跳变沿(上升或 下降)数据被采样。 3.2 SPI Framework #控制器设备和驱动 控制器设备在 BSP

11、 的初始化中注册,驱动在 drvier/spi 中 #核心层驱动 核心层代码负责这个框架中通用的部分,满足分层的思想。主题承担的工作包括:注册 spi 总线,提供基本 SPI 总线操作 API。 #SPI 外设驱动 对于 SPI 的设备驱动,因为可爱的 linux driver framework 设计者的功劳,这里我们只需要 用到 spi.h 中定义的方法就可以了,不用去修改 spi 控制器的代码。一般的,我们的设备驱 动框架是使用 spi_regiser_driver 向系统进行注册, 就可以让系统用你指定的与.name 相匹配 的硬件交互并执行你的读写请求,满足分离的思想。 spi.h

12、中大部分函数中都会用到 struct spi_device *spi 这个指针,在 probe 函数中获得这个 指针,保存好这个指针,就可以在驱动中的任何地方通过他去处理与 spi 设备相关的操作。 3.3 SPI 控制器驱动 SPI 控制器要挂载到 platform 总线上的,so, 需要在 BSP 文件中添加相应的资源代码: 通常,会在 xxxx.c 中添加: static struct platform_device da850_spi_pdev1 = .name = “dm_spi”, .id = 1, .resource = da850_spi_resources1, .num_re

13、sources = ARRAY_SIZE(da850_spi_resources1), .dev = .platform_data = 然后会在 BSP 的 init 过程中使用 platform_device_register 将它注册进系统 Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 MACHINE_START(DAVINCI_DA850_EVM, “Gemstones Platform version 0.03) .phys_io = IO_PHYS, .io_pg_offst = (_IO_ADDRE

14、SS(IO_PHYS) 18) 其中,pdev 为 platform_device 的指针,当然也可以通过别的方法,只要能获得 device 的 指针。 到这里先小总结一下: 控制器驱动的流程主要就是: 第一步:注册 platform_device;第二步:注册 platform_driver,然后 platform 总线会让两 者匹配在一起。 使用 platform 总线在驱动中大体有以下几个好处: a,使得设备被挂接在一个总线上,使配套的 sysfs 节点、设备电源管理都成为可能。 b, 隔离了 BSP 和驱动。BSP 中定义 platform 设备和设备使用的资源(可以使用 platfo

15、rm_data 的形式来包括 platform 设备的设备),设备的具体配置信息。而在驱动中, 只需要通过通用 API 去获取资源和数据, 做到了板相关代码和驱动代码的分离, 使得驱动具 有更好的可扩展性和跨平台性。 以上注册完设备,下面就要开始注册驱动。 注册 platform driver,首先要有 platform_driver 数据结构 static struct platform_driver davinci_spi_driver = .driver = .name = “dm_spi”, .owner = THIS_MODULE, , .probe = davinci_spi_pr

16、obe, Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 .remove = davinci_spi_remove, .suspend = davinci_spi_suspend, .suspend_late = davinci_spi_suspend_late, .resume_early = davinci_spi_resume_early, ; name 字段要和 device 保持一致。 然后将 probe, remove, suspend, suspend_late, resume_early 函数注册, driver framwork 会在合适的时候调用。 其中 probe 函数是比较重要的一个,该函数中将创建 davinci_spi 数据结构,这个数据结构 在文档上描述为 spi 驱动的私有数据,该结构中包括 spi_bitbang 这个重要的数据结构,它 的重要性在 probe 函数最后介绍。 在 Linux 中,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号