关于字符设备驱动(2)

这种注册设备的方法是最经常看到的,据说是以前老版本的内核推荐的方法,个人感觉虽然这种方法使用起来方便,但是
却屏蔽了很多细节,对于学系内核来说并不是很直观。

使用此种方法注册的驱动程序,主次设备号都不能大于255

下面看一下几个函数的调用关系

register_chrdev |---- __register_chrdev |---- __register_chrdev_region |---- cdev_alloc |---- cdev_add

可以看出register_chardev函数封装了,分配设备号的__register_chrdev_region函数和注册设备的cdev_alloc函数和cdev_add函数,就是将上边的过程封装了起来,

使用设备类自动注册设备文件

自动注册设备节点需要mdev的支持,(PC平台叫做udev)mdev会以守护进程的形式运行,在后台监听sysfs的uevent事件,自动在/dev,目录下创建相应的设备节点。

为了满足这样的需求,根文件系统首先需要相应的支持。
1、必须存在sysfs文件系统 mount -t sysfs sysfs /sys
2、/dev目录需要挂载为tmpfs mount -t tmpfs mdev /dev
3、在设备开机时启动mdev, 在/etc/init.d/rcS中添加echo /bin/mdev > /proc/sys/kernel/hotplug && mdev -s

其次代码中也要添加创建设备节点的相应代码。

/* This is a #define to keep the compiler from merging different * instances of the __key variable */ #define class_create(owner, name) /** * class_destroy - destroys a struct class structure * @cls: pointer to the struct class that is to be destroyed * * Note, the pointer to be destroyed must have been created with a call * to class_create(). */ void class_destroy(struct class *cls) { if ((cls == NULL) || (IS_ERR(cls))) return; class_unregister(cls); }

class_create 是一个宏,参数有两个,owner指所属模块,一般为THIS_MODULE,name为设备类名,
此宏调用了 __class_create(owner, name, &__key); 函数,调用关系如下

__class_create | ---- __class_register | ---- kset_init | ---- kobject_set_name | ---- kset_register | ---- kobject_add_internal | ---- kobject_uevent v | ---- add_class_attrs | ---- class_create_file /** * device_create - creates a device and registers it with sysfs * @class: pointer to the struct class that this device should be registered to * @parent: pointer to the parent struct device of this new device, if any * @devt: the dev_t for the char device to be added * @drvdata: the data to be added to the device for callbacks * @fmt: string for the device's name * * This function can be used by char device classes. A struct device * will be created in sysfs, registered to the specified class. * * A "dev" file will be created, showing the dev_t for the device, if * the dev_t is not 0,0. * If a pointer to a parent struct device is passed in, the newly created * struct device will be a child of that device in sysfs. * The pointer to the struct device will be returned from the call. * Any further sysfs files that might be required can be created using this * pointer. * * Returns &struct device pointer on success, or ERR_PTR() on error. * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */ struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) /** * device_destroy - removes a device that was created with device_create() * @cla: pointer to the struct class that this device was registered with * @devt: the dev_t of the device that was previously registered * * This call unregisters and cleans up a device that was created with a * call to device_create(). */ void device_destroy(struct class *class, dev_t devt)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/693ef441c9831a83cea8cf2d502c7db2.html