Linux设备驱动工程师之路——设备模型(下)上层模型

Linux设备驱动工程师之路——设备模型(下)上层模型

K-Style

转载请注明来自于衡阳师范学院08电2 Y-Kee http://blog.csdn.net/ayangke,QQ:843308498

一、重要知识点:

设备模型由总线、设备、驱动三要素组成。

底层模型决定上层模型,在总线,设备,驱动的结构体中你总是可以看到它们间接或者直接的包含了kobject结构或kset结构。

1.总线

总线是处理器和设备之间的通道,在设备模型中,所有设备都通过总线相连,甚至内部的虚拟“platform”总线。在linux设备模型中,总线由bus_type结构表示。定义在<linux/device>中。

总线描述


bus_type的bus_type_private成员



可以看出该结构体中包含了有device和dirver的kset对象。

总线的注册:

int bus_register(structbus_type *bus);

如果成功,新的总线将被添加到系统,在/sys/bus目录下可以看到。

我们在深入看这个函数



从这里

priv->subsys.kobj.kset = bus_kset;
priv->subsys.kobj.ktype = &bus_ktype;

可以看得出总线初始化了自己的kset对象。

总线的删除

void bus_unregister(struct bus_type *bus);

总线的match方法

int (*match)(struct device *dev, struct device_driver *drv);

当一个新设备或者驱动被添加到这个总线时,该方法被调用,用于判断指定的驱动程序是否能处理指定的设备。若可以,则返回非0值。下面的测试程序采用匹配设备的dev->bus_id字符串和驱动的drv->name字符串是否相同来判断驱动是否能处理该设备。

总线uevent方法

int (*uevent)(structdevice *dev, char **envp, int num_envp)

在为用户产生热插拔事件之前,这个方法允许总线添加环境变量。

总线属性由结构bus_attribute描述:

struct bus_attribute {

struct attribute attr;

ssize_t (*show)(struct bus_type *bus,char *buf);

ssize_t (*store)(struct bus_type *bus,const char *buf, size_t count);

};

BUS_ATTR(name,mode, show, store)

在编译时创建和初始化bus_attribute结构,它将bus_attr_作为给定前缀来创建总线的真正名称。

如:static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);

将创建一个bus_attr_version结构体对象。

int bus_create_file(struct bus_type *bus, struct bus_attribute *attr)

创建属性文件

void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr)

删除属性文件

2.设备



可以看出device结构体中也包含了一个kobject对象

intdevice_register(struct device *dev);

注册设备

vioddevice_unregister(struct device *dev)

注销设备

设备属性由struct device_attribute描述

structdevice_attribute {

struct attribute attr;

ssize_t (*show)(struct device *dev,struct device_attribute *attr,

char *buf);

ssize_t (*store)(struct device *dev,struct device_attribute *attr,

const char *buf, size_t count);

};

int device_create_file(struct device *dev, struct device_attibute *entry)

创建属性文件

void device_remove_file(struct device *dev, struct device_attibute *entry)

删除属性文件

3.驱动

驱动程序由struct device_driver描述:



在看device_dirver的driver_private 对象

struct driver_private {
struct kobject kobj;
struct klist klist_devices;
struct klist_node knode_bus;
struct module_kobject *mkobj;
struct device_driver *driver;
};

可以看出driver_private结构体中也包含了一个kobject对象。和连接设备的链表。

当总线的match返回非0值,也就是总线找到与驱动相匹配的设备时,驱动的probe的函数将被调用。

当设备从系统总删除是remove被调用。

当系统关机的时候shutdown被调用。

int driver_register(structdevice_driver *drv)

在总线上注册驱动

void driver_unregister(struct device_driver *drv)

载总线上注销驱动

驱动的属性使用structdriver_attribute来描述

structdriver_attribute{

structattribue attr;

ssize_t(*show)(struct device_driver *drv, const char *buf);

ssize_t(*store)(struct device_driver *drv, const char *buf, size_t count);

}

int dirver_create_file(struct device_driver *drv, struct driver_attribute *attr);

创建属性文件

void driver_remove_file struct device_driver *drv, struct driver_attribute *attr);

删除属性文件


二、测试模块

1.BUS

创建一条名为my_bus_type的总线和一个名为my_bus的总线设备,注意总线也是一个设备,也需要注册。

测试结果:

Linux设备驱动工程师之路——设备模型(下)上层模型

2.DEVICE


注册一个bus_id即名字为my_dev的设备,该设备的bus成员指向上一步创建的my_bus_type总线,parent成员指向上一步创建的my_bus总线设备。

测试结果:

Linux设备驱动工程师之路——设备模型(下)上层模型

3.DRIVER

创建一个名为“bus_dev”的驱动,并将bus成员指向第一步创建的my_bus_type总线

测试结果:


Linux设备驱动工程师之路——设备模型(下)上层模型

你可能感兴趣的:(linux)