您的位置:首页 > 其它

字符设备驱动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时分配设备号不足的错误示范

正确代码及现象:

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设备实体已经被注销了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: