平台设备总线模型-整理

本文介绍了Linux内核中的平台总线,用于挂载无物理总线的简单设备。平台设备通过platform_device和platform_driver结构表示,支持四种匹配方式,包括设备树、ACPI和id_table。文章还详细讲解了注册、注销平台设备和驱动的过程,以及probe和remove函数的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 平台设备总线
    • 概念:
      • 一般对于 I2C、SPI、USB 这些常见类型的物理总线来说,Linux 内核会自动创建与之相应的驱动总线,因此 I2C 设备、SPI 设备、USB 设备自然是注册挂载在相应的总线上。但是,实际项目开发中还有很多结构简单的设备,对它们进行控制并不需要特殊的时序。它们也就没有相应的物理总线,比如 led、rtc 时钟、蜂鸣器、按键等等,Linux 内核将不会为它们创建相应的驱动总线。为了使这部分设备的驱动开发也能够遵循设备驱动模型,Linux 内核引入了一种虚拟的总线——平台总线(platform bus)。平台总线用于管理、挂载那些没有相应物理总线的设备,这些设备被称为平台设备,对应的设备驱动则被称为平台驱动。平台设备驱动的核心依然是 Linux 设备驱动模型,平台设备使用 platform_device 结构体来进行表示,其继承了设备驱动模型中的 device 结构体。而平台驱动使用 platform_driver 结构体来进行表示,其则是继承了设备驱动模型中的 device_driver结构体。

    • 平台总线
      • BUS结构体

        • match匹配函数四种方式

          • id_table匹配方式为主

          • platform 总线提供了四种匹配方式,并且这四种方式存在着优先级:设备树机制 >ACPI 匹配模式 >id_table 方式 > 字符串比较。
          • 在init内注册

            • 函数:bus_register(&platform_bus_type);
      • 使用结构体 struct resource 来保存设备所提供的资源,比如设备使用的中断编号,寄存器物理地址等
        • struct resource 结构体

    • 平台设备
      • platform_device 结构体

        • 参数解释
          • dev:Linux 设备模型中的 device 结构体,linux 内核大量使用了面向对象思想,platform_device通过继承该结构体可复用它的相关代码,方便内核管理平台设备;
          • name:设备名称,总线进行匹配时,会比较设备和驱动的名称是否一致;
          • id:指定设备的编号,Linux 支持同名的设备,而同名设备之间则是通过该编号进行区分;
          • num_resources:记录资源的个数,当结构体成员 resource 存放的是数组时,需要记录 resource数组的个数,内核提供了宏定义 ARRAY_SIZE 用于计算数组的个数;
          • resource:平台设备提供给驱动的资源,如 irq,dma,内存等等。该结构体会在接下来的内容进行讲解;
          • id_entry:平台总线提供的另一种匹配方式,原理依然是通过比较字符串,这部分内容会在平台总线小节中讲,这里的 id_entry 用于保存匹配的结果;
          • 例子:

        • 注册函数:int platform_device_register(struct platform_device *pdev)
          • 例子

        • 注销函数:void platform_device_unregister(struct platform_device *pdev)
          • 例子

        • 获取resource
          • 结构体

          • 例子

    • 平台驱动
      • init函数
        • 例:

        • 注册file_operations结构体:major = register_chrdev(0, "100ask_led", &led_drv); /* /dev/led */

          • open函数
          • write函数
        • led_class = class_create(THIS_MODULE, "100ask_led_class");
        • /* C. 注册platform_driver */ err = platform_driver_register(&led_driver);
      • exit函数
        • 例:

        • /* C. 反注册platform_driver */platform_driver_unregister(&led_driver);
        • class_destroy(led_class);
        • unregister_chrdev(major, "100ask_led");
      • Probe函数

        • 获取source

          • 函数原型

        • 记录引脚

        • 创建设备节点

      • platform_driver 结构体

        • 参数解释
          • probe:函数指针,驱动开发人员需要在驱动程序中初始化该函数指针,当总线为设备和驱动匹配上之后,会回调执行该函数。我们一般通过该函数,对设备进行一系列的初始化。
            • 例子

          • remove:函数指针,驱动开发人员需要在驱动程序中初始化该函数指针,当我们移除某个平台设备时,会回调执行该函数指针,该函数实现的操作,通常是 probe 函数实现操作的逆过程。
          • driver:Linux 设备模型中用于抽象驱动的 device_driver 结构体,platform_driver 继承该结构体,也就获取了设备模型驱动对象的特性;
          • id_table:表示该驱动能够兼容的设备类型。
            • 例子

          • 例子:

        • 注册:int platform_driver_register(struct platform_driver *drv);
          • 例子

        • 注销: void platform_driver_unregister(struct platform_driver *drv);
          • 例子

    • 匹配的四种方法

      • 1:比较名字进行匹配

      • 2:设备树

      • 3:acpi

      • 4:通过id_table

        • id_table

      • 5:第五种

      • 总结:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值