您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > Linux设备驱动模型介绍
广州致远电子有限公司文库资料©2017GuangzhouZHIYUANElectronicsStockCo.,Ltd.文章源自广州致远电子有限公司,转载或引用请注明出处1嵌入式-ARM工控机第1章Linux设备驱动模型介绍设备驱动模型,对系统的所有设备和驱动进行了抽象,形成了复杂的设备树型结构,采用面向对象的方法,抽象出了device设备、driver驱动、bus总线和class类等概念,所有已经注册的设备和驱动都挂在总线上,总线来完成设备和驱动之间的匹配。总线、设备、驱动以及类之间的关系错综复杂,在Linux内核中通过kobject、kset和subsys来进行管理,驱动编写可以忽略这些管理机制的具体实现。设备驱动模型的内部结构还在不停的发生改变,如device、driver、bus等数据结构在不同版本都有差异,但是基于设备驱动模型编程的结构基本还是统一的。Linux设备驱动模型是Linux驱动编程的高级内容,这一节只对device、driver等这些基本概念作介绍,便于阅读和理解内核中的代码。实际上,具体驱动也不会孤立的使用这些概念,这些概念都融合在更高层的驱动子系统中。对于大多数读者可以忽略这一节内容。1.1.1设备在Linux设备驱动模型中,底层用device结构来描述所管理的设备。device结构在文件linux/device.h中定义,如程序清单1.1所示。程序清单1.1device数据结构定义structdevice{structdevice*parent;/*父设备*/structdevice_private*p;/*设备的私有数据*/structkobjectkobj;/*设备的kobject对象*/constchar*init_name;/*设备的初始名字*/structdevice_type*type;/*设备类型*/structmutexmutex;/*同步驱动的互斥信号量*/structbus_type*bus;/*设备所在的总线类型*/structdevice_driver*driver;/*管理该设备的驱动程序*/void*platform_data;/*平台相关的数据*/structdev_pm_infopower;/*电源管理*/#ifdefCONFIG_NUMAintnuma_node;/*设备接近的非一致性存储结构*/#endifu64*dma_mask;/*DMA掩码*/u64coherent_dma_mask;/*设备一致性的DMA掩码*/structdevice_dma_parameters*dma_parms;/*DMA参数*/structlist_headdma_pools;/*DMA缓冲池*/structdma_coherent_mem*dma_mem;/*DMA一致性内存*//*体系结构相关的附加项*/structdev_archdataarchdata;/*体系结构相关的数据*/#ifdefCONFIG_OFstructdevice_node*of_node;广州致远电子有限公司文库资料©2017GuangzhouZHIYUANElectronicsStockCo.,Ltd.文章源自广州致远电子有限公司,转载或引用请注明出处2嵌入式-ARM工控机#endifdev_tdevt;/*创建sysfs的dev文件*/spinlock_tdevres_lock;/*驱动的锁*/structlist_headdevres_head;structklist_nodeknode_class;structclass*class;/*设备所属的类*/conststructattribute_group**groups;/*可选的组*/void(*release)(structdevice*dev);/*指向设备的release方法*/};注册和注销device的函数分别是device_register()和device_unregister(),函数原型如下:int__must_checkdevice_register(structdevice*dev);voiddevice_unregister(structdevice*dev);大多数不会在驱动中单独使用device结构,而是将device结构嵌入到更高层的描述结构中。例如,内核中用spi_device来描述SPI设备,spi_device结构在linux/spi/spi.h文件中定义,是一个嵌入了device结构的更高层的结构体,如程序清单1.2所示。程序清单1.2spi_device数据结构structspi_device{structdevicedev;/*device数据结构*/structspi_master*master;u32max_speed_hz;u8chip_select;u8mode;u8bits_per_word;intirq;void*controller_state;void*controller_data;charmodalias[SPI_NAME_SIZE];};系统提供了device_create()函数用于在sysfs/classs中创建dev文件,以供用户空间使用。device_create()函数定义如下:structdevice*device_create(structclass*cls,structdevice*parent,dev_tdevt,void*drvdata,constchar*fmt,...);说明:cls是指向将要被注册的class结构;parent是设备的父指针;devt是设备的设备编号;drvdata是被添加到设备回调的数据;fmt是设备的名字。与device_create()函数相反的是device_destroy()函数,用于销毁sysfs/class目录中的dev文件。device_destroy()函数原型如下:广州致远电子有限公司文库资料©2017GuangzhouZHIYUANElectronicsStockCo.,Ltd.文章源自广州致远电子有限公司,转载或引用请注明出处3嵌入式-ARM工控机voiddevice_destroy(structclass*cls,dev_tdevt);1.1.2驱动与设备相对应,Linux设备驱动模型中,对管理的驱动也用device_driver结构来描述,在linux/device.h中定义,如程序清单1.3所示。程序清单1.3device_driver结构定义structdevice_driver{constchar*name;/*驱动的名称*/structbus_type*bus;/*驱动所在的总线*/structmodule*owner;/*驱动的所属模块*/constchar*mod_name;/*模块名称(静态编译的时候使用)*/boolsuppress_bind_attrs;/*通过sysfs禁止bind或者unbind*/#ifdefined(CONFIG_OF)conststructof_device_id*of_match_table;/*匹配设备的表*/#endifint(*probe)(structdevice*dev);/*probe探测方法*/int(*remove)(structdevice*dev);/*remove方法*/void(*shutdown)(structdevice*dev);/*shutdown方法*/int(*suspend)(structdevice*dev,pm_message_tstate);/*suspend方法*/int(*resume)(structdevice*dev);/*resume方法*/conststructattribute_group**groups;conststructdev_pm_ops*pm;/*电源管理*/structdriver_private*p;/*驱动的私有数据*/};系统提供了driver_register()和driver_ungister()分别用于注册和注销device_driver,函数原型分别如下:int__must_checkdriver_register(structdevice_driver*drv);voiddriver_unregister(structdevice_driver*drv);与device结构类似,在驱动中一般也不会单独使用device_driver结构,通常也是嵌入在更高层的描述结构中。还是以SPI为例,SPI设备的驱动结构为spi_driver,在linux/spi/spi.h文件中定义,是一个内嵌了device_driver结构的更高层的结构体,原型如程序清单1.4所示。程序清单1.4spi_driver数据结构structspi_driver{conststructspi_device_id*id_table;int(*probe)(structspi_device*spi);int(*remove)(structspi_device*spi);void(*shutdown)(structspi_device*spi);int(*suspend)(structspi_device*spi,pm_message_tmesg);int(*resume)(structspi_device*spi);广州致远电子有限公司文库资料©2017GuangzhouZHIYUANElectronicsStockCo.,Ltd.文章源自广州致远电子有限公司,转载或引用请注明出处4嵌入式-ARM工控机structdevice_driverdriver;/*driver数据结构*/};1.1.3总线在设备驱动模型中,所有的设备都通过总线相连,总线既可以是实际的物理总线,也可以是内核虚拟的platform总线。驱动也挂在总线上,总线是设备和驱动之间的媒介,为它们提供服务。当设备插入系统,总线将在所注册的驱动中寻找匹配的驱动,当驱动插入系统中,总线也会在所注册的设备中寻找匹配的设备。在Linux设备驱动模型中,总线用bus_type结构来描述。bus_type结构在linux/device.h中定义,如程序清单1.5所示。程序清单1.5bus_type结构定义structbus_type{constchar*name;/*总线名称*/structbus_attribute*bus_attrs;/*总线属性*/structdevice_attribute*dev_attrs;/*设备属性*/structdriver_attribute*drv_attrs;/*驱动属性*/int(*match)(structdevice*dev,structdevice_driver*drv);/*match方法:匹配设备和驱动*/int(*uevent)(structdevice*dev,structkobj_uevent_env*env);/*uevent方法,支持热插拔*/int(*probe)(structdevice*dev);/*probe方法*/int(*remove)(structdevice*dev);/*remove方法*/void(*shutdown)(structdevice*dev);/*shutdown方法*int(*suspend)(structdevice*dev,pm_message_tstate);/*suspend方法*/int(*resume)(structdevice*dev);/*resume方法*/conststructdev_pm_ops*pm;/*电源管理*/structbus_type_private*p;/*总线的私有数据结构*/};说明一下bus总线的match方法。当往总线添加一个新设备或者新驱动的时候,match方法会被调用,为设备
本文标题:Linux设备驱动模型介绍
链接地址:https://www.777doc.com/doc-7872248 .html