从module_exit(l138_led_exit);中的函数l138_led_exit(void)来看字符设备驱动建立的过程
static int l138_led_exit(void)
{
unregister_chrdev_region(led_dev,count); //删除主从设备号
cdev_del(&led_cdev); //cdev设备删除
device_destroy(led_class,led_dev); //删除led类
class_destroy(led_class); //卸载led类
printk(KERN_INFO "l138_led exit\n");
}
1、先给设备自动分配一个主从设备号
if(LED_MAJOR){
led_dev = MKDEV(LED_MAJOR,LED_MINOR);
ret1=register_chrdev_region(led_dev,count,L138_LED_NAME);
if(ret1 < 0){
printk(KERN_INFO "l138_led_dev fail\n");
}
}
else{
ret1 = alloc_chrdev_region(&led_dev,LED_MINOR,count,L138_LED_NAME);
LED_MAJOR = MAJOR(led_dev);
if(ret1 < 0){
printk(KERN_INFO "l138_led_dev fail\n");
return -1;
}
}
2、创建led_cdev以及注册led_cdev
分配led_cdev空间:
led_cdev = cdev_alloc();
初始化led_cdev:
cdev_init(led_cdev,&led_fops);
led_cdev->ops = &led_fops;
led_cdev->owner = THIS_MODULE;
其中 struct file_operations led_fops;这个变量很重要
struct file_operations led_fops=
{
.owner = THIS_MODULE,
.open = l138_led_open,
.release = l138_led_release,
.unlocked_ioctl = l138_led_ioctl,
};
直接跟应用程序的open ioctl函数有关系。
添加注册led_cdev: cdev_add(&led_cdev,led_dev,count);
到这里设备已经添加完成,这时候可以通过 cat /proc/devices查看到有led的设备已经其主设备号了
为了在/dev下自动生成节点,这时候需要给他创建一个class
3、为led创建一个led_class的内容
static struct class *led_class;
led_class = class_create(THIS_MODULE,L138_LED_NAME);
4、挂载led类
ret2= device_create(led_class,NULL,led_dev,NULL,L138_LED_NAME);
这样便大功构成,这些操作过后便可以在/dev下自动生成节点。
如果不想在驱动程序里边自动生成节点,可以进行手动添加
mknod 设备名 c/b(c为字符设备b为块设备)主设备号 从设备号