第一种,字符驱动,比较常用。
if (xx_major) { /* 分配设备号 */
dev_no = MKDEV(xx_major, 0);
ret = register_chrdev_region(dev_no, 1, xx_name);///静态的申请和注册设备号
} else {
ret = alloc_chrdev_region(&dev_no, 0, 1, xx_name);//没有固定的话自动分配一个dev_no设备号,//动态的申请注册一个设备号
xx_major = MAJOR(dev_no);
}
cdev_init(&dev->cdev, fops); /* 注册设备驱动 */
dev->cdev.owner = THIS_MODULE;
//dev->cdev.ops = fops;
ret = cdev_add(&dev->cdev, dev_no, 1);
if (ret != 0) {
printk(KERN_ERR "unable to add cdev of %s!\n", xx_name);
goto out_cdev;
}
dev->cls = class_create(THIS_MODULE, xx_name);/* 创建设备类: "/sysfs/class/xx_name" */
if (IS_ERR(dev->cls)) {
dev->cls = NULL;
printk(KERN_ERR "unable to create sysfs class of %s!\n", xx_name);
}
/* creat /dev/xx_name" */
device_create(dev->cls, NULL, dev_no, "%s", xx_name);
内核例子
int __init usb_devio_init(void)
{
int retval;
retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
"usb_device"); //dev/usb_device
if (retval) {
printk(KERN_ERR "Unable to register minors for usb_device\n");
goto out;
}
cdev_init(&usb_device_cdev, &usbdev_file_operations);
retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
if (retval) {
printk(KERN_ERR "Unable to get usb_device major %d\n",
USB_DEVICE_MAJOR);
goto error_cdev;
}
usb_register_notify(&usbdev_nb);
out:
return retval;
error_cdev:
unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
goto out;
}
第二种,就是一个接口
static inline int register_chrdev(unsigned int major, const char *name,const struct file_operations *fops)//major为0时候动态注册,非零时候静态注册
{
return __register_chrdev(major, 0, 256, name, fops);
}
内核代码例子
static int __init i2c_dev_init(void)
{
int res;
printk(KERN_INFO "i2c /dev entries driver\n");
res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);
if (res)
goto out;
i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
if (IS_ERR(i2c_dev_class)) {
res = PTR_ERR(i2c_dev_class);
goto out_unreg_chrdev;
}
i2c_dev_class->dev_groups = i2c_groups;
/* Keep track of adapters which will be added or removed later */
res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);
if (res)
goto out_unreg_class;
/* Bind to already existing adapters right away */
i2c_for_each_dev(NULL, i2cdev_attach_adapter);
return 0;
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;
}