以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。
参考
前言
这里说的“总线式”,包括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 this device */ void *platform_data; /* Platform specific data, device core doesn't touch it */ struct dev_pm_info power; #ifdef CONFIG_NUMA int numa_node; /* NUMA node this device is close to */ #endif u64 *dma_mask; /* dma mask (if dma'able device) */ u64 coherent_dma_mask;/* Like dma_mask, but for alloc_coherent mappings as not all hardware supports 64 bit addresses for consistent allocations 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 mem override */ /* arch specific additions */ struct dev_archdata archdata; #ifdef CONFIG_OF struct device_node *of_node; #endif dev_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_CLASS struct device *usb_classdev; #endif #ifdef CONFIG_USB_DEVICEFS struct dentry *usbfs_dentry; #endif int maxchild; struct usb_device *children[USB_MAXCHILDREN]; u32 quirks; atomic_t urbnum; unsigned long active_duration; #ifdef CONFIG_PM unsigned long last_busy; int autosuspend_delay; unsigned long connect_time; unsigned do_remote_wakeup:1; unsigned reset_resume:1; #endif struct 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)这些模型里全是一些结构体套结构体,因此对基本功要求很高。