From: Http://www.hovercool.com/en/Class_create,_device_create,_device_create_file
When I started writing Linux device drivers, I used the Mknod command to manually create device nodes (including many examples in ldd3), and in fact the Linux kernel now provides us with a set of functions that can be used to automatically load the module The corresponding device node is created under the Dev directory, and the node is removed when the module is unloaded.
A struct class struct is defined in the kernel, as the name implies, a struct class struct type variable corresponds to a class, and the kernel also provides class_create (...). function, which can be used to create a class, this class is stored under SYSFS, once the class is created, then the Device_create (...) is called. function to create the appropriate device node in the/dev directory. This way, when the module is loaded, udev in the user space will automatically respond to the Device_create (...) function, go to/SYSFS and look for the corresponding class to create the device node.
In addition, the Device_create_file function can be used to create a corresponding property file under/sys/class/, thus implementing specific data operations by reading and writing the file.
- 1 First, class_create
- 2 Second, device_create
- 3 three, Device_create_file
- 3.1 A. Creating a property file in a driver using Device_create_file
- 3.2 B. Read properties in user space
- 4 . Use Example
|
First, Class_create
Official Note:
/* #define to keep the compiler from merging different * instances of the __key variable */#defineClass_create(Owner,Name)({Static structLock_class_key __key;__class_create(Owner,Name, &__key);})/** * Class_create-create a struct class structure * @owner: Pointer to the module so is to ' own ' this struct class * @name: Pointer to a string for the name of this class. * @key: The lock_class_key for this class; Used by mutexes Lock debugging * * This is used to create a struct class pointer so can then being used * in calls to Device_ Create (). * * Returns &struct class pointer on success, or ERR_PTR () On error. * * Note, the pointer created here are to being destroyed when finished by * making a call to Class_destroy (). */struct class *__class_create(struct module *owner, Const char *name, struct lock_class_key *key)
The key sentence is:
* This was used to create a struct class pointer the can then be used * in calls to Device_create (). --This function is used to create a struct-class pointer that can be used as a parameter to the Device_create () function.
That is, this function is primarily used before calling Device_create (), creating a variable of struct class type and returning its pointer.
Second, Device_create
Official Note:
/** * Device_create-creates A device and registers it with SYSFS * @class: Pointer to the struct class, this device should be registered to * @parent: pointer to the parent struct device of this new device, if any * @devt: the dev_t for T He char device to is added * @drvdata: The data to is added to the device for callbacks * @fmt: String for the device ' s NA Me * * This function can is used by char device classes. A struct device * would be is created in Sysfs, registered to the specified class. * * A "dev" file would be created, showing the dev_t for the device, if * The dev_t was not 0,0. * If A pointer to a parent struct device was passed in, the newly created * struct device would be a child of this device in Sysfs. * The pointer to the struct device is returned from the call. * Any further SYSFS files, might be required can is created using this * pointer. * * Returns &struct device pointer on success, or ERR_PTR () On error. * * Note:the struct class passed to this funCtion must has previously * been created with a call to Class_create (). */structDevice*device_create (struct *class, struct device *parent, dev_t Devt,void *drvdata, const char*fmt, ...)
First explain the "SYSFS": Sysfs is a virtual file system provided by linux2.6, in the device model, SYSFS file system is used to represent the structure of the device, the image of the hierarchy of the device is reflected in the user space, This allows you to modify the property values of the device by modifying the file properties in the SYSFS; Sysfs is mounted under the/sys folder in the root directory.
Third, Device_create_file
Official Note:
/** * Device_create_file-create SYSFS attribute file for device. * @dev: Device. * @attr: Device attribute descriptor. * /int device_create_file(struct*Dev,conststruct*attr)
Use this function to refer to the device_create returned by the device* pointer, the role is to create a property file under/sys/class/, so that the property file can be read and written to complete the corresponding data operation.
Such as:
A. Creating a property file using Device_create_file in a driver
StaticDevice_attr(Val,S_irugo|S_iwusr,Hello_val_show,Hello_val_store); /* Read register Val value into buffer buf, internal use */ Static ssize_t__hello_get_val(structXxx_dev*Dev, Char*Buf) { IntVal= 0; /* Simultaneous access */ If(Down_interruptible(& (Dev-Sem))) { Return -Erestartsys; }Val=Dev-Val;Up(& (Dev-Sem)); Returnsnprintf(Buf,Page_size, "%d/n",Val); } /* Write the value of the buffer buf to the device register Val, internal use */ Static ssize_t__hello_set_val(structXxx_dev*Dev, Const Char*Buf, size_tCount) { IntVal= 0; /* Convert String to Digital */Val=Simple_strtol(Buf,Null, 10); /* Simultaneous access */ If(Down_interruptible(& (Dev-Sem))) { Return -Erestartsys; }Dev-Val=Val;Up(& (Dev-Sem)); ReturnCount; } /* Read Device properties val*/ Static ssize_tHello_val_show(structDevice* Dev, struct Device_attribute* Attr char* Buf) {struct xxx_dev* Hdev = (struct xxx_dev*) dev_get_drvdata (dev); return __hello_get_val (Hdev, buf);}/* Write device properties val*/static ssize_t hello_val_store (struct device* dev, struct device_attribute* attr, const char* BUF, size_t count {struct xxx_dev* Hdev = (struct xxx_dev*) dev_get_drvdata (Dev), return __hello_set_val (Hdev, buf, Count),}/* Module loading method */S tatic int __init xxx_init (void) {.../* Create a property file under the/sys/class/xxx/xxx directory val*/err = device_create_file (temp, &dev_attr_ Val); if (Err < 0) {PRINTK (kern_alert "Failed to create attribute Val."); goto Destroy_device;} ...}
b. Read properties in user space
... read (dev->fd, Val, sizeof val ... write (dev->fd< Span class= "pun" >, &val sizeof (val ...
Iv. Examples of use
/* Create a device category directory under the/sys/class/directory xxx*/G_vircdev_class=Class_create(This_module,Vircdev_class_name); If(Is_err(G_vircdev_class)) {Err=Ptr_err(G_vircdev_class);Printk(Kern_alert"Failed to create class.\n"); GotoClass_create_err; } /* Create device files separately under the/dev/directory and/sys/class/xxx directory xxx*/Dev=Device_create(G_vircdev_class,Null,Devt,Null,Vircdev_device_name); If(Is_err(Dev)) {Err=Ptr_err(Dev);Printk(Kern_alert"Failed to create device.\n"); GotoDevice_create_err; } /* create a property file under/sys/class/xxx/xxx directory Val*/= Device_create_file (dev , Attrif (err < 0) { PRINTK (kern_alert "Failed to create attribute file." goto Device_create_file_err; /span>
Resources:
Sysfs
http://blog.csdn.net/dianhuiren/article/details/6928500
Http://tech.ccidnet.com/art/302/20080304/1379211_1.html
http://blog.csdn.net/chchchdx123/article/details/6248486
Class Create, device Create, device create file (GO)