Linux设备驱动模型(1)

来源:互联网 发布:sql server中通配符 编辑:程序博客网 时间:2024/06/05 02:59

在Linux内核的说明文档里有一些关于驱动模型的说明文件,首先解读一下第一个文件bus.txt:

struct bus_type {       char               * name;        structsubsystem    subsys;       structkset             drivers;       structkset             devices;        structbus_attribute * bus_attrs;       structdevice_attribute    * dev_attrs;       structdriver_attribute    * drv_attrs;        int           (*match)(struct device * dev, structdevice_driver * drv);       int           (*hotplug) (struct device *dev, char**envp,                                int num_envp, char *buffer, intbuffer_size);       int           (*suspend)(struct device * dev,pm_message_t state);       int           (*resume)(struct device * dev);};

内核里的所有总线结构包括PCI,USB等都应该定义这个bus_type,name一定要定义,回调函数match可选择性定义。例如:

struct bus_type pci_bus_type = {

      .name       = "pci",

      .match      = pci_bus_match,

};

        回调函数的目的是决定所有挂载在该总线的设备device和驱动driver的匹配关系。device和driver的匹配根据他们的ID,在2.6.32内核以前可根据device的bus_id和driver的name是否匹配来判断驱动和设备的匹配关系,但后来的struct device结构里没有bus_id这个参数了,纠结啊。

当驱动注册到总线的时候,会遍历所有挂载在该总线的设备,看是否有匹配的device和driver。

/*************************************************************************************************************************

*************************************************************************************************************************

*************************************************************************************************************************/

现贴出一段代码关于总线的注册。

#include <linux/device.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/string.h> MODULE_AUTHOR("Xie");MODULE_LICENSE("Dual BSD/GPL"); static char *Version = "$Revision: 1.0$"; static int my_match(struct device *dev,struct device_driver *driver){       return!strncmp(dev->bus_id, driver->name, strlen(driver->name));//在以后的内核版本,没有bus_id了。这个回调函数怎么写,可参照内核里的总线注册。}/*****************************************************bus_type结构的填充,定义注册的总线的名字和回调函数。******************************************************/struct bus_type my_bus_type = {                  .name= "my_bus",       .match= my_match,}; //当查看该属性文件时会执行这个函数static ssize_t show_bus_version(structbus_type *bus, char *buf){       returnsnprintf(buf, PAGE_SIZE, "%s\n", Version);} static BUS_ATTR(version, S_IRUGO,show_bus_version, NULL); /********************************************************************设置总线属性有两个步骤:1、创建并初始化bus_attribute结构,使用宏BUS_ATTRBUS_ATTR(_name, _mode, _show, _store)该宏会定义一个名叫bus_attr__name(红色部分是固定的)的bus_attibute的结构,并且成员name设置为_name,文件权限mode设置为_mode,两个函数调用分别用show和store。2、将bus_attibute添加到指定的总线上,使用以下调用:      int bus_create_file(structbus_type *bus, struct bus_attribute *attr)该函数失败时返回错误号。一旦调用该函数,会就在指定bus总线的目录下新建一个名叫_name的文件,权限为_mode,当访问和修改该文件是会分别调用show和store函数调用。 *********************************************************************/ static int __init my_bus_init(void){       intret;             //总线的注册,这个函数会在/sys/bus/目录下创建相应的总线目录       ret= bus_register(&my_bus_type);       if(ret)              returnret;                            if(bus_create_file(&my_bus_type, &bus_attr_version))              printk(KERN_NOTICE"Fail to create version attribute!\n");                    returnret;} static void my_bus_exit(void){       bus_unregister(&my_bus_type);} module_init(my_bus_init);module_exit(my_bus_exit);


原创粉丝点击