以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。
参考
Linux总线设备驱动模型的理解
struct class 和 struct class_device
前言
这里说的“总线式”,包括I2C总线等具体物理总线,以及平台总线这个虚拟总线。
root@ubuntu:/sys# ls block bus class dev devices firmware fs hypervisor kernel module power root@ubuntu:/sys# cd bus/ root@ubuntu:/sys/bus# ls ac97 eisa isa pci_express sdio virtio acpi event_source machinecheck platform serio workqueue clockevents gameport mdio_bus pnp spi xen clocksource hid mmc rapidio usb xen-backend cpu i2c pci scsi usb-serial root@ubuntu:/sys/bus# cd platform/ root@ubuntu:/sys/bus/platform# ls devices drivers drivers_autoprobe drivers_probe uevent root@ubuntu:/sys/bus/platform# cd ../i2c root@ubuntu:/sys/bus/i2c# ls devices drivers drivers_autoprobe drivers_probe uevent root@ubuntu:/sys/bus/i2c#
1、总线:struct bus_type结构体
(1)物理上的真实总线及其作用
(2)驱动框架中的总线式设计
总线管理设备(有一个设备链表)和驱动(有一个驱动链表),它们通过名字来匹配。
(3)结构体struct bus_type
该结构体位于x210kernel/inclue/linux/device.h文件中。
struct bus_type {const char *name; //总线的名字struct bus_attribute *bus_attrs;struct device_attribute *dev_attrs;struct driver_attribute *drv_attrs;//match函数(负责设备和驱动的匹配) 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 bus_type_private *p; };
2、设备:struct device结构体
(1)结构体struct device是硬件设备在内核驱动框架中的抽象。
该结构体位于x210kernel/inclue/linux/device.h文件中。
struct device {struct device *parent;struct device_private *p;struct kobject kobj;const char *init_name; /* initial name of the device */struct device_type *type;struct mutex mutex; /* mutex to synchronize calls to* its driver.*/struct bus_type *bus; /* type of bus device is on */struct device_driver *driver; /* which driver has allocated thisdevice */void *platform_data; /* Platform specific data, devicecore doesn't touch it */struct dev_pm_info power;#ifdef CONFIG_NUMAint numa_node; /* NUMA node this device is close to */ #endifu64 *dma_mask; /* dma mask (if dma'able device) */u64 coherent_dma_mask;/* Like dma_mask, but foralloc_coherent mappings asnot all hardware supports64 bit addresses for consistentallocations such descriptors. */struct device_dma_parameters *dma_parms;struct list_head dma_pools; /* dma pools (if dma'ble) */struct dma_coherent_mem *dma_mem; /* internal for coherent memoverride *//* arch specific additions */struct dev_archdata archdata; #ifdef CONFIG_OFstruct device_node *of_node; #endifdev_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); };
(2)device_register由内核开发者提供的框架提供,用于向内核驱动框架注册一个设备。
(3)struct device通常被包含在一个具体设备结构体中。
比如struct usb_device:
struct usb_device {int devnum;char devpath[16];u32 route;enum usb_device_state state;enum usb_device_speed speed;struct usb_tt *tt;int ttport;unsigned int toggle[2];struct usb_device *parent;struct usb_bus *bus;struct usb_host_endpoint ep0;struct device dev;struct usb_device_descriptor descriptor;struct usb_host_config *config;struct usb_host_config *actconfig;struct usb_host_endpoint *ep_in[16];struct usb_host_endpoint *ep_out[16];char **rawdescriptors;unsigned short bus_mA;u8 portnum;u8 level;unsigned can_submit:1;unsigned persist_enabled:1;unsigned have_langid:1;unsigned authorized:1;unsigned authenticated:1;unsigned wusb:1;int string_langid;/* static strings from the device */char *product;char *manufacturer;char *serial;struct list_head filelist; #ifdef CONFIG_USB_DEVICE_CLASSstruct device *usb_classdev; #endif #ifdef CONFIG_USB_DEVICEFSstruct dentry *usbfs_dentry; #endifint maxchild;struct usb_device *children[USB_MAXCHILDREN];u32 quirks;atomic_t urbnum;unsigned long active_duration;#ifdef CONFIG_PMunsigned long last_busy;int autosuspend_delay;unsigned long connect_time;unsigned do_remote_wakeup:1;unsigned reset_resume:1; #endifstruct wusb_dev *wusb_dev;int slot_id; };
比如 struct platform_device:
struct platform_device {const char * name;int id;struct device dev;//!!!!u32 num_resources;struct resource * resource;const struct platform_device_id *id_entry;/* arch specific additions */struct pdev_archdata archdata; };
3、驱动:struct device_driver结构体
(1)结构体struct device_driver是驱动程序在内核驱动框架中的抽象。
该结构体位于x210kernel/inclue/linux/device.h文件中。
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 */#if defined(CONFIG_OF)const struct of_device_id *of_match_table; #endif//驱动程序的探测函数,用来检测某个设备是否可以被该驱动所管理//比如该设备是否正常、以及一些初始化。见参考微博的描述。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; };
(2)struct platform_driver的内容如下
struct platform_driver {int (*probe)(struct platform_device *);int (*remove)(struct platform_device *);void (*shutdown)(struct platform_device *);int (*suspend)(struct platform_device *, pm_message_t state);int (*resume)(struct platform_device *);struct device_driver driver;const struct platform_device_id *id_table; };
4、类:struct class结构体
(1)相关结构体:struct class(类) 和 struct class_device(类下面的某个设备)
结构体struct class在x210kernel/inclue/linux/device.h文件中定义:
struct class {const char *name;struct module *owner;struct class_attribute *class_attrs;struct device_attribute *dev_attrs;struct kobject *dev_kobj;int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);char *(*devnode)(struct device *dev, mode_t *mode);void (*class_release)(struct class *class);void (*dev_release)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct kobj_ns_type_operations *ns_type;const void *(*namespace)(struct device *dev);const struct dev_pm_ops *pm;struct class_private *p; };
结构体struct class_device:该结构体好像已经不再使用了?怎么查询不到的!
(2)udev的使用离不开class。class的意义在于作为同属于一个class的多个设备的容器。也就是说class是一种人造概念,目的就是为了对各种设备进行分类管理。当然,class在分类的同时还对每个类贴上了一些“标签”,这也是设备驱动模型为我们写驱动提供的基础设施。
5、总结:模型即面向对象的思想
(1)模型,其实就是面向对象的思想。
(2)这些模型里全是一些结构体套结构体,因此对基本功要求很高。