struct class *myclass = class_create(THIS_MODULE, “char_dev”);
class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, “char_dev”);
这二个函数就是创建一个设备,和他的节点号。
在你加入设备时udev就会判断,然后建立节点。
至于你说的不识别的设备,你得加载驱动啊,加载驱动的时候里面只要有上述的二个函数,通过
UDEV就会创建了。
另外,楼主你写的驱动首先是要进行注册的,要创建一个class和device,class在/dev目录下,device在sysfs目录下,这样,你加载模块是就会根据已创建的device去找sysfs目录下的class。
使用linux-2.6.30.4。
文件的管理使用的是 sysfs.(由udev制作的文件系统)
涉及两个函数:
virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk");
device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk");
使用需添加头文件 #include <linux/device.h>
说明:
当使用利用udev制作的文件系统时,Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点。
内核中定义了struct class结构体,一个struct class结构体类型变量对应一个类(有待商榷),内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应 device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
在linux-2.6.30.4,struct class定义在头文件include/linux/device.h中,
struct class {
const char *name;
struct module *owner;
struct class_attribute *class_attrs;
struct device_attribute *dev_attrs;
struct kobject *dev_kobj;
int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
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);
struct dev_pm_ops *pm;
struct class_private *p;
};
class_create(…)头文件include/linux/device.h中,
#define class_create(owner, name) /
({ /
static struct lock_class_key __key; /
__class_create(owner, name, &__key); /
})
__class_create在/drivers/base/class.c中实现:
struct class *__class_create(struct module *owner, const char *name,
struct lock_class_key *key)
device_create(…)函数在/drivers/base/core.c中实现:
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
* 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
使用示例:
virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk");
device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk");
示例程序(一个简单的字符驱动):
- struct class *virtual_disk_class; /*by yinhf.*/
- /*设备驱动模块加载函数*/
- int VirtualDisk_init(void)
- {
- int result;
- dev_t devno = MKDEV(VirtualDisk_major, 0); /*构建设备号*/
- /* 申请设备号*/
- if (VirtualDisk_major) /* 如果不为0,则静态申请*/
- result = register_chrdev_region(devno, 1, "VirtualDisk");
- else /* 动态申请设备号 */
- {
- result = alloc_chrdev_region(&devno, 0, 1, "VirtualDisk");
- VirtualDisk_major = MAJOR(devno);/* 从申请设备号中得到主设备号 */
- }
- if (result < 0)
- return result;
- /* 动态申请设备结构体的内存*/
- Virtualdisk_devp = kmalloc(sizeof(struct VirtualDisk), GFP_KERNEL);
- if (!Virtualdisk_devp) /*申请失败*/
- {
- result = - ENOMEM;
- goto fail_kmalloc;
- }
- memset(Virtualdisk_devp, 0, sizeof(struct VirtualDisk));/*将内存清零*/
- /*初始化并且添加cdev结构体*/
- VirtualDisk_setup_cdev(Virtualdisk_devp, 0);
- // devfs_mk_cdev(devno, S_IFCHR|S_IRUGO|S_IWUSR, "VirtualDisk"); /*yinhf*/
- printk(KERN_ALERT "Virtualdisk Success/n");
- /* create virtual_disk_class under /sysfs by yinhf.*/
- virtual_disk_class = class_create(THIS_MODULE, "VirtualDisk");
- if(IS_ERR(virtual_disk_class))
- {
- printk("Err: failed in creating virtual_disk_class./n");
- return -1;
- }
- /* register your own device in sysfs, and this will cause udev to create corresponding device node */
- device_create( virtual_disk_class, NULL, devno, 0, "VirtualDisk");
- printk (KERN_INFO "Registered character driver VirtualDisk./n");
- /*end create virtual_disk_class by yinhf.*/
- return 0;
- fail_kmalloc:
- unregister_chrdev_region(devno, 1);
- return result;
- }
- /*模块卸载函数*/
- void VirtualDisk_exit(void)
- {
- cdev_del(&Virtualdisk_devp->cdev); /*注销cdev*/
- kfree(Virtualdisk_devp); /*释放设备结构体内存*/
- device_destroy(virtual_disk_class, MKDEV(VirtualDisk_major, 0)); //delete device node under /dev
- class_destroy(virtual_disk_class); //delete class created by us
- unregister_chrdev_region(MKDEV(VirtualDisk_major, 0), 1); /*释放设备号*/
- }
参考网址:
http://blog.csdn.net/engerled/archive/2011/02/24/6205722.aspx
------------------------------------------------------------------------------------
struct class *myclass = class_create(THIS_MODULE, “my_device_driver”);
class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, “my_device”);
这样的module被加载时,udev daemon就会自动在/dev下创建my_device设备文件。
class_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class *class_create(struct module *owner, const char *name)
class_create - create a struct class structure
@owner: pointer to the module that is to "own" this struct class
@name: pointer to a string for the name of this class.
在/sys/class/下创建类目录
class_device_create()
-------------------------------------------------
linux-2.6.22/include/linux/device.h
struct class_device *class_device_create(struct class *cls,
struct class_device *parent,
dev_t devt,
struct device *device,
const char *fmt, ...)
class_device_create - creates a class device and registers it with sysfs
@cls: pointer to the struct class that this device should be registered to.
@parent: pointer to the parent struct class_device of this new device, if any.
@devt: the dev_t for the char device to be added.
@device: a pointer to a struct device that is assiociated with this class device.
@fmt: string for the class device's name
* device classes
struct class {
const char *name;
struct module *owner;
struct list_head devices;
struct list_head interfaces;
struct kset class_dirs;
struct semaphore sem; /* locks children, devices, interfaces */
struct class_attribute *class_attrs;
struct device_attribute *dev_attrs;
void (*dev_release)(struct device *dev);
int (*resume)(struct device *dev);
/**
* class_create - create a struct class structure
* @owner: pointer to the module that is to "own" this struct class
* @name: pointer to a string for the name of this class.
*
* This is used to create a struct class pointer that can then be used
* in calls to device_create().
*
* Note, the pointer created here is to be destroyed when finished by
* making a call to class_destroy().
*/
struct class *class_create(struct module *owner, const char *name)
{
struct class *cls;
int retval;
cls = kzalloc(sizeof(*cls), GFP_KERNEL);
if (!cls) {
retval = -ENOMEM;
goto error;
}
cls->owner = owner;
cls->class_release = class_create_release;
if (retval)
goto error;
kfree(cls);
return ERR_PTR(retval);
}
第一个参数指定类的所有者是哪个模块,第二个参数指定类名。
在class.c中,还定义了class_destroy(…)函数,用于在模块卸载时删除类。
/**
* 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
* @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.
*
* 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, const char *fmt, ...)
{
va_list vargs;
struct device *dev;
dev = device_create_vargs(class, parent, devt, NULL, fmt, vargs);
va_end(vargs);
return dev;
}
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
int hello_minor = 0;
int number_of_devices = 1;
dev_t dev = 0;
.owner = THIS_MODULE
};
{
int error, devno = MKDEV (hello_major, hello_minor);
cdev_init (&cdev, &hello_fops);
cdev.owner = THIS_MODULE;
cdev.ops = &hello_fops;
error = cdev_add (&cdev, devno , 1);
if (error)
printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev", error);
{
int result;
dev = MKDEV (hello_major, hello_minor);
result = register_chrdev_region (dev, number_of_devices, "hello");
if (result<0) {
printk (KERN_WARNING "hello: can't get major number %d/n", hello_major);
return result;
}
my_class = class_create(THIS_MODULE, "my_class");
if(IS_ERR(my_class))
{
printk("Err: failed in creating class./n");
return -1;
}
device_create( my_class, NULL, MKDEV(hello_major, 0), "hello" "%d", 0 );
return 0;
}
{
dev_t devno = MKDEV (hello_major, hello_minor);
class_destroy(my_class); //delete class created by us
}
module_exit (hello_2_exit);
* module load/unload record keeping
*/
{
int res;
if (res)
goto out;
if (IS_ERR(i2c_dev_class)) {
res = PTR_ERR(i2c_dev_class);
goto out_unreg_chrdev;
}
if (res)
goto out_unreg_class;
class_destroy(i2c_dev_class);
out_unreg_chrdev:
unregister_chrdev(I2C_MAJOR, "i2c");
out:
printk(KERN_ERR "%s: Driver Initialisation failed/n", __FILE__);
return res;
}
{
struct i2c_dev *i2c_dev;
int res;
if (IS_ERR(i2c_dev))
return PTR_ERR(i2c_dev);
i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
MKDEV(I2C_MAJOR, adap->nr), NULL,
"i2c-%d", adap->nr);
if (IS_ERR(i2c_dev->dev)) {
res = PTR_ERR(i2c_dev->dev);
goto error;
}
res = device_create_file(i2c_dev->dev, &dev_attr_name);
if (res)
goto error_destroy;
adap->name, adap->nr);
return 0;
error_destroy:
device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr));
error:
return_i2c_dev(i2c_dev);
return res;
}
在i2cdev_attach_adapter调用device_create(i2c_dev_class, &adap->dev,
MKDEV(I2C_MAJOR, adap->nr), NULL,
"i2c-%d", adap->nr);
本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/zhenwenxian/archive/2010/03/28/5424434.aspx
class_device_destroy();