Linux字符设备驱动的注册
2016-07-20 10:06
316 查看
很多学习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三个函数的功能
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三个函数的功能
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- Linux 下无损图片压缩小工具介绍