Linux设备驱动总线模型简介

前言:

本篇blog主要是整理了一下总线,驱动,设备之间的关系概述。


一、总线、驱动、设备

     1.1 设备模型提供了一个独立的机制专门来表示设备,并描述其在系统中的拓扑结构

     1.2 在2.4内核中,设备的信息放在/proc中,在2.6内核以后,把设备相关的信息归类在新增加sysfs文件系统,并将它挂载到/sys目录中,把设备信息归类的同时,让用户可以通过用户空间访问。

简单介绍一些sys中的目录:

       block:用于管理块设备,系统中的每一个块设备会在该目录下对应一个子目录。

bus:用于管理总线,每注册一条总线,在该目录下有一个对应的子目录。

                其中,每个总线子目录下会有两个子目录:devices和drivers。

        devices包含系统中所有属于该总线的的设备。

        class:将系统中的设备按功能分类。

        dev:该目录包含已注册的设备号(设备节点)的视图,包括char和block

        kernel:内核中的相关参数。

        module:内核中的模块信息。

        fireware:内核中的固件信息。


Fs:描述内核中的文件系统。

         


           sys中的其他目录都是将devvice目录下的数据加以转换加工而得,通过/sys中信息,内核就能方便对设备进行管理

 1.3   总线 是处理器和设备之间的通道,在设备模型中,所有的设备都通过总线相连,以总线来管理设备和驱动函数。
          总线用bus_type结构表示
struct bus_type {
const char *name; // 总线名
struct bus_attribute *bus_attrs; // 总线属性
struct device_attribute *dev_attrs;
struct driver_attribute *drv_attrs;

int (*match)(struct device *dev, struct device_driver *drv); // 匹配方法
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);

int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);

const struct dev_pm_ops *pm;

struct subsys_private *p;
};
总线的注册和注销:
int bus_register(struct bus_type *bus);
void bus_unregister(struct bus_type *bus);

1.4,设备:在最底层,linux系统中每个设备都用一个struct device结构体来表示
struct device {
struct device *parent; // 当前设备的父类
struct device_private *p;
struct kobject kobj;
const char *init_name; /* initial name of the device 设备名*/
const struct device_type *type;
struct mutex mutex;
struct bus_type *bus; /* type of bus device is on 设备所在的总线*//
struct device_driver *driver; /* which driver has allocated this device ,该对象中包含操作设备的的方法*/
void *platform_data; /* Platform specific data, device core doesn't touch it,私有平台数据,给用户使用 */
struct dev_pm_info power;
struct dev_power_domain *pwr_domain;

/* arch specific additions */
struct dev_archdata archdata;

struct device_node *of_node; /* associated device tree node */

dev_t devt; /* dev_t, creates the sysfs "dev" */

spinlock_t devres_lock;
struct list_head devres_head;

struct klist_node knode_class;
struct class *class;
const struct attribute_group **groups; /* optional groups */
void (*release)(struct device *dev); //当设备的最后一个引用被删除时,调用该函数
};
设备的注册和注销:
int device_register(struct device *dev)
void device_unregister(struct device *dev)

1.5   驱动 其实就是我们平常写的用于驱动设备的代码,里面就已经包含了驱动对象,设备模型跟踪所有系统所知道的设备。进行跟踪的主要原因是让驱动程序协调与设备之间的关系
struct device_driver {
const char *name; // 驱动名字
struct bus_type *bus; // 所属总线

struct module *owner;
const char *mod_name; /* used for built-in modules */

bool suppress_bind_attrs; /* disables bind/unbind via sysfs */

const struct of_device_id *of_match_table;// 设备id表,表示该驱动支持哪些型号的设备

int (*probe) (struct device *dev); // 当设备和驱动匹配的时候执行的方法
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;

const struct dev_pm_ops *pm;

struct driver_private *p;
};

驱动的注册和注销:
int driver_register(struct device_driver *drv);
void driver_unregister(struct device_driver *drv)
总结:总线的成功注册后会在/sys/bus目录下创建相应的目录。

设备的成功注册后会在/sys/device目录下创建相应的目录,如果指定总线,会在指定总线目录/sys/bus/xx/device下创建一个指向/sys/device目录的软连接。

驱动函数的注册会在/sys/bus/xx/driver目录下创建相应的目录。

二、配对函数(match)、探测函数(probe)和卸载函数(remove)


1.  int (*match)(struct device *dev, struct device_driver *drv);--总线bus

当总线上添加了新设备或者新驱动函数的时候,内核会调用一次或者多次这个函数。
如果现在添加了一个新的驱动(driver),内核就会调用所属总线(bus)的match函数,配对总线上所有的设备(device),如果驱动能够对应处理其中一个设备,函数返回1,告诉内核配对成功。
一般的,match函数是判断设备的结构体成员device->bus_id和驱动函数的结构体成员device_driver->name是否一致,如果一致,那就表明配对成功。

2,int (*probe)(struct device *dev);---- 驱动driver
当配对(match)成功后,内核就会调用指定驱动中的probe函数来查询设备能否被该驱动操作,如果可以,驱动就会对该设备进行相应的操作,如初始化。所以说,真正的驱动函数入口是在probe函数中。

3, int (*remove) (struct device *dev); ---驱动driver
当设备从总线中移除时,内核会调用驱动函数中的remove函数调用,进行一些设备卸载相应的操作







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值