linux cdev详解 http://blog.chinaunix.net/uid-24517893-id-161446.html
用cdev_add添加字符设备驱动:
//linux2.6中用cdev_add添加字符设备驱动
//传统的是直接使用register_chrdev
//新的方式,驱动初始化写起来要繁琐一点,但是好处是能够根据需要控制cdev_add的设备数量,且主设备号不再完全受256个的限制。详情可以参考2.6的内核代码linux/fs/char_dev.c,以及上面引用的文章。
static struct cdev *leds_cdev ;
static int leds_major = xx ;//
static int __init s3c24xx_leds_init()
{
dev_t devno = MKDEV(leds_major , 0);
leds_cdev = (LEDS_DEV_ST*)kmalloc(sizeof(LEDS_DEV_ST),GFP_KERNEL) ;
/*申请设备号,当xxx_major不为0时,表示静态指定;当为0时,表示动态申请*/
if(leds_major){
ret = register_chrdev_region(devno , LEDS_DEV_COUNT , LEDS_DEV_NAME); //register_chrdev_region若成功,返回值0
}else{
ret = alloc_chrdev_region(&devno, LEDS_BASE_MINOR, LEDS_DEV_COUNT, LEDS_DEV_NAME);
leds_major = MAJOR(devno);
}
//初始化并添加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);
//class_create动态创建设备的逻辑类,并完成部分字段的初始化,然后将其添加到内核中。
// 创建的逻辑类位于 /sys/class/。
leds_class = class_create(THIS_MODULE, "leds_class"); // /sys/class/下的类名
for (minor = 0; minor < 4 ; minor++){
leds_class_devs[minor] = class_device_create(leds_class,
NULL,
MKDEV(leds_major, minor),
NULL,
(minor==0)?"leds":"led%d", minor);
}
//为简化逻辑,出错处理代码略
}