自动创建设备文件,可以让驱动自动创建设备文件,
不再使用 mknod /dev/myled c 250 0
一个struct class结构体类型变量对应一个类 ,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应 device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点
1. 自动创建设备文件使用的设备模型中的class的机制
类的定义: struct class
需要头文件<linux/device.h>
struct class * myclass
/**
* struct class - device classes
* @name: Name of the class.
* @owner: The module owner.
* @class_attrs: Default attributes of this class.
* @dev_attrs: Default attributes of the devices belong to the class.
* @dev_bin_attrs: Default binary attributes of the devices belong to the class.
* @dev_kobj: The kobject that represents this class and links it into the hierarchy.
* @dev_uevent: Called when a device is added, removed from this class, or a
* few other things that generate uevents to add the environment
* variables.
* @devnode: Callback to provide the devtmpfs.
* @class_release: Called to release this class.
* @dev_release: Called to release the device.
* @suspend: Used to put the device to sleep mode, usually to a low power
* state.
* @resume: Used to bring the device from the sleep mode.
* @ns_type: Callbacks so sysfs can detemine namespaces.
* @namespace: Namespace of the device belongs to this class.
* @pm: The default device power management operations of this class.
* @p: The private data of the driver core, no one other than the
* driver core can touch this.
*
* A class is a higher-level view of a device that abstracts out low-level
* implementation details. Drivers may see a SCSI disk or an ATA disk, but,
* at the class level, they are all simply disks. Classes allow user space
* to work with devices based on what they do, rather than how they are
* connected or how they work.
*/
struct class {
const char *name;
struct module *owner;
struct class_attribute *class_attrs;
struct device_attribute *dev_attrs;
struct bin_attribute *dev_bin_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 subsys_private *p;
};
2. 类的创建 class_create
// 在/sys/class/ 下创建一个目录
struct class *class_create(struct module *owner, const char *name);
owner : 这个类的指针 myclass
name : 这个类的名称
3. 类的销毁 class_destroy
void class_destroy(struct class *cls);
cls : 是要销毁类的指针
4. 创建一个类设备 <==> mknod /dev/led c 250 0
在我们使用busybox 做的文件系统中,都有mdev,在/sbin/mdev udev的嵌入式版本
在使用这个函数创建了一个类设备时,会在shengli/led文件,会触发一个udev事件,mdev会把这个路径
下的led创建到/dev/led,相当与在/dev目录下创建设备文件 ,设备号是参数中的devno
/**
* 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, ...)
class : struct class 的指针
parent : 父类的指针 没有的话 为空
devt : 设备号
drvdat : 为空
fmt : 这个类设备的名称 比如led
5. 类设备的销毁 <==> rm /dev/led
void device_destroy(struct class *class, dev_t devt)
class : 要销毁类的指针
devt : 要销毁设备的设备号