标签:
一、设备驱动的分层思想:以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