Linux下PCI设备驱动开发详解(一)

这篇具有很好参考价值的文章主要介绍了Linux下PCI设备驱动开发详解(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux下PCI设备驱动开发详解(一)

PCI总线是目前应用最广泛的计算机总线标准,而且是一种兼容性最强,功能最全的计算机总线。
而linux作为一种开源的操作系统,同时也为PCI总线与各种新型设备互联成为可能。尤其被现在的异构计算GPU/FPGA、软硬结合新的方向广泛运用。

一、PCI设备和驱动概述

应用程序位于用户空间,驱动程序位于内核空间。linux系统规定,用户空间不可以直接调用内核函数,所以必须经过系统调用,应用程序才可以调用驱动程序的函数。另外应用程序通过系统调用去调用驱动程序的函数,还有一个前提就是驱动程序必须留有接口,这里的接口就是ops函数的操作集合。

          linux libpci库,PCI设备驱动开发详解,linux,驱动开发

  驱动最终通过与文件系统相关的系统调用或C库函数(本质也是基于系统调用)被访问,而设备驱动的结构也是为了迎合应用程序,提供给应用程序的SDK API。

sys:linux设备驱动模型中的总线、驱动和设备都可以在sysfs文件系统中找到相应的节点。当内核检测到系统中出现新的设备后,内核会在sysfs文件系统中为设备生成一项新的记录。

sysfs是一个虚拟的文件系统,它可以产生一个包括所有系统硬件的层级视图,与提供进程和状态的proc文件系统十分类似。可以让用户空间存取,向用户空间导出内核数据结构以及它的属性

在linux内核中,设备和驱动是分开注册的,注册1个设备的时候,并不需要驱动已经存在,而1个驱动被注册的时候,也不需要对应的设备被注册。设备和驱动各自涌入内核,而每个设备和驱动涌入内核的时候,都会寻找另外一半_。而正是bus_type的match()成员函数将两者绑定在一起。

简单来说,设备和驱动就是红尘的男女,而bus_type的match()则是牵引红线的月老,它可以识别什么设备与什么驱动,是配对的。一旦成功,xxx_driver的probe就被执行。

二、PCI总线描述

          
linux libpci库,PCI设备驱动开发详解,linux,驱动开发

PCI是CPU和外围设备通信的高速传输总线。普通PCI总线带宽一般为132MB/s或者264MB/s。

PCI总线体系结构是一种层次式的体系结构,PCI桥设备占据重要的地位,它将父总线与子总线连接在一起,从而使整个系统看起来像一颗倒置的树形结构。

三、PCI配置空间

PCI有3种地址空间:PCI配置空间、PCI/IO空间、PCI内存地址空间。

1. PCI配置空间

          linux libpci库,PCI设备驱动开发详解,linux,驱动开发

deviceID和vendorID寄存器:由pcisig分配,只读,vendorID代表pci设备的厂商,deviceID代表厂商的具体设备;
status:设备状态字;
command:设备状态字;
base address register:决定pci/pcie设备空间映射到系统具体位置的寄存器,IO和memory映射两种;

2. PCI/IO空间(PIO)

pio端口的编址是独立于系统的地址空间,其实是一段地址区域,所有外设的地址都映射到这段区域中。不同外设的IO端口不同,访问IO端口需要特殊的IO指令,OUT/IN,out用于write操作,in用于read操作;
IO地址空间有限;

3. PCI内存地址空间(MMIO)

io内存就是把寄存器的地址空间直接映射到系统的地址空间,系统地址空间保留一段内存用于MMIO的映射。

上述的方案只适用于外设和内存进行小数据量的传输时,假如进行大数据量的传输,PIO以字节为单位的传输不用说了,MMIO虽然进行了内存映射,但是范围相对于大量的数据,不值得一提,所以即使采用了MMIO仍然满足不了需要,会让吧CPU大部分时间处理繁琐的映射,极大浪费CPU资源。在这种情况下,引入了DMA,由DMA控制器控制,完成后中断通知CPU,极大解放了CPU。后面的文章会接收DMA。

四、PCI设备驱动组成

PCI本质上就是一种总线,具体的PCI设备可以是字符设备、网络设备、USB等,所以PCI设备驱动应该包括两个部分:

  1. PCI通用驱动
  2. 根据实际需要的设备驱动
    根据需求的设备驱动是最终目的,PCI驱动只是手段帮助设备驱动达到最终目的而已。换句话,PCI设备驱动不仅实现PCI驱动还要包括具体需求的设备驱动。
              
    linux libpci库,PCI设备驱动开发详解,linux,驱动开发
    PCI驱动注册与注销:
int pci_register_driver(struct pci_driver *driver);
int pci_unregister_driver(struct pci_driver *driver);

PCI_driver结构体:

struct pci_driver {
    struct list_head node;
    char *name; /* 驱动程序的名称 */
    struct module *owner;
    /* 指向设备驱动程序感兴趣的设备ID的一个列表,包括:
     * 厂商ID、设备ID、子厂商ID、子设备ID、类别、类别掩码、私有数据
     */
    const struct pci_device_id *id_table;
    /* 指向一个函数对于每一个id_table中的项匹配的且未被其他驱动程序处理的设备,
     * 在执行pci_register_driver时候调用此函数或者如果是以后插入的一个新设备的话,只要满足上述条件也会调* 用此函数
     */
    int (*probe) (struct pci_dev *dev, const struct pci_device_id *id);
    /* 指向一个函数当驱动函数程序卸载或者被该驱动程序管理的设备被卸下的时候,调用此函数
     */
    int (*remove) (struct pci_dev *dev);
    int (*save_state) (struct pci_dev *dev, u32 state); /* 设备被挂起之前保存的相关状态 */
    int (*suspend) (struct pci_dev *dev, u32 state); /* 挂起设备使之处于节能状态 */
    int (*resume) (struct pci_dev *dev); /* 唤醒挂起的设备 */
    /* 使设备能够从挂起态产生唤醒事件*/
    int   (*enable_wake) (struct pci_dev *dev, u32 state, int enable);
};

五、未完待续

Linux下PCI设备驱动开发详解(二),将介绍具体的函数实现。文章来源地址https://www.toymoban.com/news/detail-762039.html

到了这里,关于Linux下PCI设备驱动开发详解(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 宋宝华《Linux设备驱动开发详解》 宋老师csdn上分享的网盘已失效,特意新增的。

    https://pan.baidu.com/s/1rCbRUmnDtjE4jHNB5eQ8CQ 提取码:t12r 案例代码: https://pan.baidu.com/s/1lSMGxLnEFwO0aJGORqx8Og 提取码: bglj Linux设备驱动开发详解:基于最新的Linux4.0内核 (电子与嵌入式系统设计丛书) (宋宝华 著)电子书: https://download.csdn.net/download/MINGTING1323/86831055

    2024年02月13日
    浏览(44)
  • Linux驱动开发笔记(四):设备驱动介绍、熟悉杂项设备驱动和ubuntu开发杂项设备Demo

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/134533533 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中… 上一篇:《Linux驱动开发笔记(三

    2024年02月05日
    浏览(53)
  • 4、Linux驱动开发:设备-设备号&设备号注册

    🍅点击这里查看所有博文   随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记下来。存在很多在特殊情况下有

    2024年02月15日
    浏览(57)
  • Linux驱动开发实战(一)——设备驱动模型

    在早期的Linux内核中并没有为设备驱动提供统一的设备模型。随着内核的不断扩大及系统更加复杂,编写一个驱动程序越来越困难,所以在Linux2.6内核中添加了一个统一的设备模型。这样,写设备驱动程序就稍微容易一些了。本章将对设备模型进行详细的介绍。 设备驱动模型

    2024年02月16日
    浏览(51)
  • 正点原子嵌入式linux驱动开发——Linux 网络设备驱动

    网络驱动是linux里面驱动三巨头之一 ,linux下的网络功能非常强大,嵌入式linux中也常常用到网络功能。前面已经讲过了字符设备驱动和块设备驱动,本章就来学习一下linux里面的 网络设备驱动 。 本次笔记中讨论的都是有线网络! 提起网络,一般想到的硬件就是“网卡”。在

    2024年01月17日
    浏览(71)
  • 深入探讨Linux驱动开发:Linux设备树

    设备树(Device Tree,简称 DT)是一种在嵌入式系统中描述硬件设备的一种数据结构和编程语言。它用于将硬件设备的配置信息以树形结构的方式进行描述,以便操作系统(如 Linux)可以根据这些信息正确地识别、配置和管理硬件设备。 设备树最初被引入到 Linux 内核中,用于解

    2023年04月27日
    浏览(51)
  • Linux设备驱动开发 - 虚拟时钟Clock驱动示例

    By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 很多设备里面系统时钟架构极其复杂,让学习Clock驱动的盆友头大。这里我参考S3C2440的clock驱动写了一个virtual clock,即虚拟时钟驱动,分别包含clock的provider和

    2023年04月21日
    浏览(43)
  • Linux -- 字符设备驱动--LED的驱动开发(初级框架)

    看原理图确定引脚,确定引脚输出什么电平才能点亮 / 熄灭 LED 看主芯片手册,确定寄存器操作方法:哪些寄存器?哪些位?地址是? 编写驱动:先写框架,再写硬件操作的代码 注意 :在芯片手册中确定的寄存器地址被称为 物理地址 ,在 Linux 内核中无法直接使用。 需要使

    2024年04月28日
    浏览(37)
  • 嵌入式Linux驱动开发 04:基于设备树的驱动开发

    前面文章 《嵌入式Linux驱动开发 03:平台(platform)总线驱动模型》 引入了资源和驱动分离的概念,这篇文章将在前面基础上更进一步,引入设备树的概念。 在平台总线驱动模型中资源和驱动已经从逻辑上和代码组织上进行了分离,但每次调整资源还是会涉及到内核,所以现

    2024年02月16日
    浏览(70)
  • 新型LINUX驱动开发 DTS设备树

    1.为什么使用设备树 linux内核3.版本之后才有设备树。 没有设备树之前的板级信息都写在.c文件里面,导致内核臃肿。 因此将板级信息独立成格式,文件名为dts,一个平台对应一个dts。 2.dts dtb dtc dts是设备树源码文件。 dtb是将设备树dts编译以后得到的二进制文件。 dtc是将dt

    2024年02月09日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包