标签:
一、设备驱动的分层思想:以platform设备驱动、input设备驱动为例看看他们在分层思想上的体现struct bus_type { //具备总线名、总线属性、总线上设备属性、总线上驱动属性 const char *name; struct bus_attribute *bus_attrs; struct device_attribute *dev_attrs; struct driver_attribute *drv_attrs; //具备匹配、热插拔、探测、移除设备方案 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 (*suspend_late)(struct device *dev, pm_message_t state); int (*resume_early)(struct device *dev); int (*resume)(struct device *dev); struct dev_pm_ops *pm; struct bus_type_private *p; //设备具有不同特性--这本身就是一种共性 };针对platform设备,内核并没有去实现上面这些通用的功能属性,毕竟在现实中大多数情况,设备的不同功能还是比较多,除非是要在一个cpu下控制批量相同的设备,这只是我个人的看法
struct bus_type platform_bus_type = { .name = "platform", .dev_attrs = platform_dev_attrs, .match = platform_match, .uevent = platform_uevent, .pm = PLATFORM_PM_OPS_PTR, };也就是说内核认为platform设备在多数情况下具备的通用功能特性有上面5个方面并给他们赋予了默认方案,
bus_register(&platform_bus_type);platform总线上就具有这类设备的一套默认的方案。
struct input_handle { void *private; int open; const char *name; struct input_dev *dev; //##关键成员 struct input_handler *handler; //##关键成员 struct list_head d_node; struct list_head h_node; };派生到:
struct evdev { int exist; int open; int minor; char name[16]; struct input_handle handle;//继承input_handle基类 wait_queue_head_t wait; struct evdev_client *grab; struct list_head client_list; spinlock_t client_lock; /* protects client_list */ struct mutex mutex; struct device dev; };什么时候被实例化?
evdev_connect(struct input_handler *handler, struct input_dev *dev,const struct input_device_id *id) { ...... evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); evdev->minor = minor; evdev->handle.dev = input_get_device(dev); // 指向input_dev evdev->handle.name = evdev->name; evdev->handle.handler = handler; //指向input_handler evdev->handle.private = evdev; error = input_register_handle(&evdev->handle);//让input_dev和input_handler的h_list指向evdev->handle ...... }【2】在设备层和驱动层:同样,内核先抽象出设备驱动的基类,再派生出某种设备驱动,最后再实例化到具体的设备驱动中来
struct device { struct device *parent; struct device_private *p; struct kobject kobj; const char *init_name; /* initial name of the device 这个就是传统的bus_id,具体到每一个设备之后当做默认值 */ struct device_type *type; ...... struct bus_type *bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this device */ void *driver_data; /* data private to the driver */ void *platform_data; /* Platform specific data, device core doesn't touch it */ ...... void (*release)(struct device *dev); };//驱动基类:
struct device_driver { const char *name; struct bus_type *bus; struct module *owner; const char *mod_name; /* used for built-in modules */ 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); struct attribute_group **groups; struct dev_pm_ops *pm; struct driver_private *p; };platform设备/驱动的派生:
struct platform_device { const char *name; int id; // 硬件设备的象征/代表 struct device dev; // 由此继承基类 u32 num_resources; struct resource * resource;//这个驱动使用的资源 struct platform_device_id *id_entry; }; 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 (*suspend_late)(struct platform_device *, pm_message_t state); int (*resume_early)(struct platform_device *); int (*resume)(struct platform_device *); struct device_driver driver; //继承基类 struct platform_device_id *id_table; };实例化到具体的led设备:
static struct platform_device led_dev = { .name = "myled", .id = -1, .num_resources = ARRAY_SIZE(led_resource), .resource = led_resource, .dev = { .release = led_release, }, }; struct platform_driver led_drv = { .probe = led_probe, .remove = led_remove, .driver = { .name = "myled", } };例(2)input设备/事件驱动层:
struct input_dev { const char *name; const char *phys; const char *uniq; struct input_id id; unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; ...... struct timer_list timer; int sync; int abs[ABS_MAX + 1]; int rep[REP_MAX + 1]; ...... unsigned long key[BITS_TO_LONGS(KEY_CNT)]; unsigned long led[BITS_TO_LONGS(LED_CNT)]; ...... int (*open)(struct input_dev *dev); void (*close)(struct input_dev *dev); int (*flush)(struct input_dev *dev, struct file *file); int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); struct input_handle *grab; ...... struct device dev; //同样继承于内核抽象出来的设备基类 struct list_head h_list; struct list_head node; };input设备实例化--按键:
struct input_dev buttons_dev = input_allocate_device(); set_bit(EV_KEY, buttons_dev->evbit); set_bit(EV_REP, buttons_dev->evbit); set_bit(KEY_L, buttons_dev->keybit); set_bit(KEY_S, buttons_dev->keybit); set_bit(KEY_ENTER, buttons_dev->keybit); set_bit(KEY_LEFTSHIFT, buttons_dev->keybit);事件处理基类:
struct input_handler { void *private; void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); void (*disconnect)(struct input_handle *handle); void (*start)(struct input_handle *handle); const struct file_operations *fops; int minor; const char *name; const struct input_device_id *id_table; const struct input_device_id *blacklist; struct list_head h_list; struct list_head node; };事件处理基类实例化:
static struct input_handler evdev_handler = { .event = evdev_event, .connect = evdev_connect, .disconnect = evdev_disconnect, .fops = &evdev_fops, .minor = EVDEV_MINOR_BASE, .name = "evdev", .id_table = evdev_ids, };小结:
标签:
原文地址:http://blog.csdn.net/clb1609158506/article/details/45198941