- 平台设备总线
- 概念:
- 一般对于 I2C、SPI、USB 这些常见类型的物理总线来说,Linux 内核会自动创建与之相应的驱动总线,因此 I2C 设备、SPI 设备、USB 设备自然是注册挂载在相应的总线上。但是,实际项目开发中还有很多结构简单的设备,对它们进行控制并不需要特殊的时序。它们也就没有相应的物理总线,比如 led、rtc 时钟、蜂鸣器、按键等等,Linux 内核将不会为它们创建相应的驱动总线。为了使这部分设备的驱动开发也能够遵循设备驱动模型,Linux 内核引入了一种虚拟的总线——平台总线(platform bus)。平台总线用于管理、挂载那些没有相应物理总线的设备,这些设备被称为平台设备,对应的设备驱动则被称为平台驱动。平台设备驱动的核心依然是 Linux 设备驱动模型,平台设备使用 platform_device 结构体来进行表示,其继承了设备驱动模型中的 device 结构体。而平台驱动使用 platform_driver 结构体来进行表示,其则是继承了设备驱动模型中的 device_driver结构体。
- 一般对于 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);
- id_table匹配方式为主
- match匹配函数四种方式
- 使用结构体 struct resource 来保存设备所提供的资源,比如设备使用的中断编号,寄存器物理地址等
- struct resource 结构体
- struct resource 结构体
- BUS结构体
- 平台设备
- 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
- 结构体
- 例子
- 结构体
- 参数解释
- platform_device 结构体
- 平台驱动
- 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
- 函数原型
- 函数原型
- 记录引脚
- 创建设备节点
- 获取source
- platform_driver 结构体
- 参数解释
- probe:函数指针,驱动开发人员需要在驱动程序中初始化该函数指针,当总线为设备和驱动匹配上之后,会回调执行该函数。我们一般通过该函数,对设备进行一系列的初始化。
- 例子
- 例子
- remove:函数指针,驱动开发人员需要在驱动程序中初始化该函数指针,当我们移除某个平台设备时,会回调执行该函数指针,该函数实现的操作,通常是 probe 函数实现操作的逆过程。
- driver:Linux 设备模型中用于抽象驱动的 device_driver 结构体,platform_driver 继承该结构体,也就获取了设备模型驱动对象的特性;
- id_table:表示该驱动能够兼容的设备类型。
- 例子
- 例子
- 例子:
- probe:函数指针,驱动开发人员需要在驱动程序中初始化该函数指针,当总线为设备和驱动匹配上之后,会回调执行该函数。我们一般通过该函数,对设备进行一系列的初始化。
- 注册:int platform_driver_register(struct platform_driver *drv);
- 例子
- 例子
- 注销: void platform_driver_unregister(struct platform_driver *drv);
- 例子
- 例子
- 参数解释
- init函数
- 匹配的四种方法
- 1:比较名字进行匹配
- 2:设备树
- 3:acpi
- 4:通过id_table
- id_table
- id_table
- 5:第五种
- 总结:
- 1:比较名字进行匹配
- 概念:
平台设备总线模型-整理
最新推荐文章于 2025-06-01 21:09:33 发布