资源描述:
《linux设备驱动程式学习(13)-linux设备模型(总线、设备、驱动程式和类)》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、实用标准文案Linux设备驱动程式学习(13)-Linux设备模型(总线、设备、驱动程式和类)文章的例子和实验使用《LDD3》所配的lddbus模块(稍作修改)。总线总线是处理器和一个或多个设备之间的通道,在设备模型中,所有的设备都通过总线相连,甚至是内部的虚拟"platform"总线。总线能相互插入。设备模型展示了总线和他们所控制的设备之间的实际连接。在Linux设备模型中,总线由bus_type结构表示,定义在:structbus_type{ constchar *name;/*总线类型名称*/ structmodule *owner;/*指向模块的指针(如果
2、有),此模块负责操作这个总线*/ structkset subsys;/*和该总线相关的子系统*/ structkset drivers;/*总线驱动程式的kset*/ structkset devices;/*挂在该总线的所有设备的kset*/ structklist klist_devices;/*和该总线相关的驱动程式链表*/ structklist klist_drivers;/*挂接在该总线的设备链表*/ structblocking_notifier_headbus_notifier; structbus_att
3、ribute *bus_attrs;/*总线属性*/ structdevice_attribute*dev_attrs;/*设备属性,指向为每个加入总线的设备建立的默认属性链表*/ structdriver_attribute*drv_attrs;/*驱动程式属性*/ structbus_attributedrivers_autoprobe_attr;/*驱动自动探测属性*/ structbus_attributedrivers_probe_attr;/*驱动探测属性*/ int (*match)(structdevice*dev,structdevice_driv
4、er*drv); int (*uevent)(structdevice*dev,char**envp, intnum_envp,char*buffer,intbuffer_size); int (*probe)(structdevice*dev); int (*remove)(structdevice*dev); void (*shutdown)(structdevice*dev); int(*suspend)(structdevice*dev,pm_message_tstate); int(*suspend_la
5、te)(structdevice*dev,pm_message_tstate); int(*resume_early)(structdevice*dev); nt(*resume)(structdevice*dev);/*处理热插拔、电源管理、探测和移除等事件的方法*/ unsignedintdrivers_autoprobe:1;};总线的注册和删除总线的主要注册步骤:(1)申明和初始化bus_type结构体。只有非常少的bus_type成员需要初始化,大部分都由设备模型核心控制。但必须为总线指定名字及一些必要的方法。例如:structbus_typeldd_bus_type={
6、 .name="ldd", .match=ldd_match, .uevent=ldd_uevent,};(2)调用bus_register函数注册总线。精彩文档实用标准文案intbus_register(structbus_type*bus)调用可能失败,所以必须始终检查返回值。若成功,新的总线子系统将被添加进系统,并可在sysfs的/sys/bus下看到。之后能向总线添加设备。例如:ret=bus_register(&ldd_bus_type);if(ret)returnret;当必须从系统中删除一个总线时,调用:voidbus_unregister(structbus_typ
7、e*bus);总线方法在bus_type结构中定义了许多方法,他们允许总线核心作为设备核心和独立的驱动程式之间提供服务的中介,主要介绍以下两个方法:int(*match)(structdevice*dev,structdevice_driver*drv);/*当一个新设备或驱动被添加到这个总线时,这个方法会被调用一次或多次,若指定的驱动程式能够处理指定的设备,则返回非零值。必须在总线层使用这个函数,因为那里存在正确的逻辑,核心内核不