字符设备驱动2:易错点【注册 、 注销】
2014-10-08 12:18
357 查看
概要:
cdev_add时分配设备号不足的错误示范
unregister_chrdev_region没有完全注销设备
相关错误现象:
error, can't open /dev/led1
insmod: cannot insert '/module/myleds_new.ko': File exists (-1): File exists
1.cdev_add时分配设备号不足的错误示范
正确代码及现象:
错误代码及现象:
2.unregister_chrdev_region没有完全注销设备
void unregister_chrdev_region(dev_t from, unsigned count); //count: the number of device numbers to unregister
正确代码及现象:
错误代码及现象:
cdev_add时分配设备号不足的错误示范
unregister_chrdev_region没有完全注销设备
相关错误现象:
error, can't open /dev/led1
insmod: cannot insert '/module/myleds_new.ko': File exists (-1): File exists
1.cdev_add时分配设备号不足的错误示范
正确代码及现象:
static int __init s3c24xx_leds_init() { int ret ; int minor = 0 ; dev_t devno = MKDEV(leds_major , 0); /*申请设备号,当xxx_major不为0时,表示静态指定;当为0时,表示动态申请*/ if(leds_major){ ret = register_chrdev_region(devno , LEDS_DEV_COUNT , LEDS_DEV_NAME); }else{ ret = alloc_chrdev_region(devno, LEDS_BASE_MINOR, LEDS_DEV_COUNT, LEDS_DEV_NAME); leds_major = MAJOR(devno); } if(ret<0){ return ret ; } //初始化并添加cdev结构体 cdev_init(&leds_cdev , &s3c24xx_leds_fops ); leds_cdev.owner = THIS_MODULE ; leds_cdev.ops = &s3c24xx_leds_fops; ret = cdev_add(&leds_cdev , devno , LEDS_DEV_COUNT); printk("cdev_add(&leds_cdev , devno , 4);\n"); //这里因为下面要建立四个子设备,因此必须至少 4个(LEDS_DEV_COUNT)。否则,使用该设备是,子设备0后面的设备是无法使用的 //现象见下面的:“cdev_add时分配设备号不足的错误示范”。 if(ret){ printk(LEDS_DEV_NAME"Error %d adding leds_cdev",ret); } //oo00 :begin : 分配了四个子设备号 minor == 0 1 2 3 //class_create动态创建设备的逻辑类,并完成部分字段的初始化,然后将其添加到内核中。创建的逻辑类位于/sys/class/。 leds_class = class_create(THIS_MODULE, "leds"); if (IS_ERR(leds_class)) return PTR_ERR(leds_class); leds_class_devs[0] = class_device_create(leds_class, NULL, MKDEV(leds_major, 0), NULL, "leds"); for (minor = 1; minor < 4; minor++){ leds_class_devs[minor] = class_device_create(leds_class, NULL, MKDEV(leds_major, minor), NULL, "led%d", minor); if (unlikely(IS_ERR(leds_class_devs[minor]))) return PTR_ERR(leds_class_devs[minor]); } //oo00 :end //prow: device_create ? or class_device_create? printk(LEDS_DEV_NAME" initialized\n"); return 0; } 现象: # insmod myleds_new.ko cdev_add(&leds_cdev , devno , 4); leds initialized # ./ledtest /dev/leds on info new: in s3c24xx_leds_ioctl! # ./ledtest /dev/led1 off info new: in s3c24xx_leds_ioctl!
错误代码及现象:
ret = cdev_add(&leds_cdev , devno , 1); printk("cdev_add(&leds_cdev , devno , 1);\n"); 现象: insmod正常,cat /proc/devices 能看见 leds 231;在app里面使用子设备号为0的设备ok,使用0以上的打不开。 # insmod myleds_new.ko cdev_add(&leds_cdev , devno , 1);//printk , 分配数量不够 leds initialized //printk # ./ledtest /dev/leds on info new: in s3c24xx_leds_ioctl! # ./ledtest /dev/led1 off error, can't open /dev/led1
2.unregister_chrdev_region没有完全注销设备
void unregister_chrdev_region(dev_t from, unsigned count); //count: the number of device numbers to unregister
正确代码及现象:
static void __exit s3c24xx_leds_exit() { dev_t devno = MKDEV(leds_major , 0); int minor; for( minor = 0;minor<4;minor++){ class_device_unregister(leds_class_devs[minor]); } class_destroy(leds_class); cdev_del(&leds_cdev);//删除结构体 unregister_chrdev_region(devno, LEDS_DEV_COUNT);//注销设备区域,正确的,将4个子设备域都注销了 } //执行rmmod之后,cat /proc/devices 没有leds 231
错误代码及现象:
unregister_chrdev_region(devno, 1);//注销设备区域, 4个子设备域没有完全注销 //执行rmmod之后,cat /proc/devices 仍有leds 231,并导致下次insmod失败。并且此时leds设备实体已经被注销了。
相关文章推荐
- 字符设备驱动--- 数据结构 设备注册struct cdev , 注销
- Linux(2.6.35.7)字符设备驱动注册接口
- 块设备驱动注册和注销、加载与卸载、块设备驱动的I/O请求
- linux2.6标准字符设备驱动模型(手动注册)
- 以杂项设备驱动的方法注册字符设备驱动
- gendisk,request与bio结构体,以及块设备驱动注册与注销,以及加载与卸载
- Linux字符设备驱动--设备注册
- linux 驱动程序 设备模块 设备号 设备文件创建 设备注册 字符驱动设备分析
- linux驱动设备--------字符设备的注册
- linux驱动---字符设备的注册register_chrdev说起
- 笔记二:字符设备之cdev方式注册字符驱动
- linux驱动---字符设备的注册register_chrdev说起
- Linux驱动编程--字符设备文件注册
- 普通字符设备驱动的两种注册方式(新&旧)
- rtc驱动框架 与 新的字符设备驱动注册方式
- linux驱动---字符设备的注册register_chrdev说起
- 2.6内核前后--注册字符设备驱动区别
- 关于字符设备驱动注册的常用办法
- linux驱动---字符设备的注册register_chrdev说起
- 字符设备驱动高级篇2——字符设备驱动注册代码分析