Linux设备模型之——注册接口的使用

前言

平时写驱动或者看一份驱动代码的时候,经常被各种注册接口函数搞晕,到底什么时候用哪一个呢?这个问题必须要在理解了Linux的设备模型后才能有个清晰的概念,本文只是在阅读了网上一些大神的博客后的一些小小的总结。不过本文暂时不会对Linux的设备模型有过多的深入,只是在自己的理解上,理清一下注册接口之间的关系。

正文

先来看一下我们在驱动开发过程中,最常接触到的两个结构体。

1、device和device_driver

这两个结构体是驱动开发的基础,顾名思义,device就是设备的抽象,device_driver就是驱动的抽象。结构体都比较复杂,但是好在注释比较清晰,具体可以参考:include\linux\device.h。驱动开发中接触最多的就是怎么使用这些接口,所以我们先看一下这些使用步骤。

下面以hid总线(bus)、uhid设备(device)、hid-generic驱动(device_driver)为例子,讲述一下流程,代码目录为:drivers\hid\。

1.1、bus

因为这一小节重点讲device和device_driver,所以bus的概念我们先放一边。注册hid总线的代码在:drivers\hid\hid-core.c

1.2、device

分配一个struct device类型的变量,填充必要的信息后,把它注册到内核中。

代码目录:
drivers\hid\uhid.c

函数调用关系:
uhid_char_open //分配了uhid_device结构体,其中就包含了struct device
->uhid_device_add_worker
    ->hid_add_device
        ->device_add //这个函数就是将分配到的device注册到内核中,并在这个过程中匹配合适的device_driver
            ->bus_probe_device //注册进总线
                ->device_attach
                    ->__device_attach
                        ->driver_match_device //最终会调用driver的match函数

1.3、device_driver

分配一个struct device_driver类型的变量,填充必要的信息后,把它注册到内核中

代码目录:
drivers\hid\hid-generic.c

函数调用关系:
module_hid_driver //分配的struct hid_driver就包含了struct device_driver
->__hid_register_driver
    ->driver_register
        ->bus_add_driver //将driver加到bus上
            ->driver_attach //匹配对应的device

1.4、小结

所以我们可以看到,注册device用的device_add接口(或者device_register、device_create_vargs和device_create,不过它们最终都是调用device_add);注册device_driver用的driver_register接口。不过实际开发中,除了直接用device和device_driver,也会用,在这两个结构体封装上的其他结构体,比如下一小节要讲的内容。

2、platform_device和platform_driver

系统中,每个设备都需要连接到一个bus上,这个bus可以是一个实际存在的内部bus、虚拟的bus或者是platform bus。这一小节我们主要关注platform bus。

那么连接到platform bus的platform device又有哪些呢?kernel在platform.txt中有相关的定义,总的来说就是,platform device包括:基于端口的设备(已不推荐使用,保留下来只为兼容旧设备,legacy);连接物理总线的桥设备;集成在SOC上的各种控制器;连接在其他bus上的设备等等。

platform bus基于底层的bus模块,抽象出来的一个虚拟的platform bus,用于platform设备的连接;platform device基于底层的device模块,用于表示platform设备;platform driver基于底层的driver模块,用于驱动platform设备。

其实从platform device和platform driver两个结构体的定义就可以看出,他们是和struct device和struct device_driver有着千丝万缕的关系。具体的定义可以参考:include\linux\platform_device.h。下面我们只是看一下怎么用系统提供的API。

2.1、struct platform_device

代码路径:
drivers\base\platform.c

函数调用关系:
platform_device_register
->platform_device_add
    ->device_add

从函数调用关系来看,最终还是走到了device_add,也进一步说明platform_device是在device上的一层封装而已。还有其它的注册接口可以参考include\linux\platform_device.h

2.2、struct platform_driver

代码路径:
linux\platform_device.h

函数调用关系:
platform_driver_register
->__platform_driver_register
    ->driver_register  //类似于platform_device,最终也是调用到注册device_driver的函数

2.3、platform bus

想注册device和driver,当然需要有对应的bus,而platform bus的注册在drivers\base\platform.c的platform_bus_init实现。细节就不过多说了,有兴趣的同学可以自行查阅代码。

2.4、小结

上面只是提到了一些API,具体的驱动代码例子可以参考我以前写的文章:设备、驱动、总线模型简介

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值