Linux字符设备驱动的注册

来源:互联网 发布:守望先锋性能数据rtt 编辑:程序博客网 时间:2024/05/19 17:27

很多学习Linux编程的新人都会被字符设备注册搞糊涂了,我刚开始也一样糊里糊涂的,看到网上例程有各种版本,就是调用module_init时传递的实参,先记为xxx_init()。大家可能还会看到杂项设备驱动misc_register、平台设备驱动platform_device_register但是作为Linux编程的初级者,建议先不着急去学习复杂的注册方式。现在我先贴出一份比较标准的设备注册程序

1.定义全局变量

#define DEVICE_NAME"Tounie-fasync"

int major = 0; //定义主设备号
static struct class * fasync_cls; //定义一个类指针
struct cdev fasync_cdev; //定义一个设备结构体


设备注册函数

static int xxx_init(void)

{

int result,err;

dev_t fasyncn = MKDEV(major, 0);//根据主设备号获取设备号

if(major)//判断是静态注册还是动态注册

result = register_chrdev_region(fasyncn, 1, DEVICE_NAME);//静态注册设备号,即自己定义主设备号

esle

{

result = alloc_chrdev_region(&fasyncn, 0, 1, DEVICE_NAME);//动态注册设备号,即开始将主设备号初始化为0
major = MAJOR(fasyncn);//通过设备号获取主设备号

}


if(result)//注册设备号失败,如果注册设备号成功result为0
{
printk("fasync register failure!\n");
unregister_chrdev_region(fasyncn, 1);
return result;
}

/* 初始化cdev */
cdev_init(&fasync_cdev, &fasync_fops);//将设备结构体与字符设备操作函数关联,实际上就是将fasync_fops赋给fasync_cdev的成员


/* 注册cdev */
err = cdev_add(&fasync_cdev, fasyncn, 1);//向内核添加一个字符设备结构体


if(err)//向内核添加字符设备结构体失败
{
printk("Error %d adding fasync!\n",err);
unregister_chrdev_region(fasyncn, 1);
return err;
}

printk("adding cdev successed!\n");


/* 以下程序可以不要,如果不要需要在我们加载模块之后手动创建设备节点,所以最好将这些工作全部在驱动程序中实现 */

/* 自动创建设别节点 */
/* 创建设备类 */
fasync_cls = class_create(THIS_MODULE, DEVICE_NAME);


if(IS_ERR(fasync_cls))
{
printk("Err: failed in Tounie-fasync.\n");
return -1;
}


/* 创建设备节点 */
device_create(fasync_cls, NULL, fasyncn, NULL, DEVICE_NAME);


printk(DEVICE_NAME" initialized!\n");


return 0;

}

/* 字符设备驱动注册程序到此完毕 */

你们可能会发现有些论坛贴出的程序没那么麻烦,人家一般就三个步骤:

1.register_chrdev(LED_MAJOR, DEVICE_NAME, &Tounie_leds_fops);//注册字符设备

2.led_class = class_create(THIS_MODULE,DEVICE_NAME);//注册字符设备类

3.device_create(led_class,NULL,MKDEV(LED_MAJOR, 0),NULL,DEVICE_NAME);//创建设备类

以上方法也可以实现字符设备驱动的注册,register_chrdev函数是2.6的内核以前的注册方法,虽然现在一些版本还兼容这些方法,但是在将来这些方法即将被淘汰,所以我们还是学习新内核的注册方法比较好。

2.6版本以前的register_chrdev相当于register_chrdev_region、cdev_init和cdev_add三个函数的功能

0 0
原创粉丝点击