免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3363 | 回复: 1
打印 上一主题 下一主题

udev下注册字符设备(以GPIO应用为例) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-02 11:23 |只看该作者 |倒序浏览
#include  
#include  
#include  

#include  
#include  
#include  
//#include  
#include
#include
#include  
#include
#include
#include
#include  
#include  
#include  

#define DEVICE_NAME "key"
#define KEY_MAJOR 234

MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS("key");

static unsigned long key_table [] = {
S3C2410_GPF0,
S3C2410_GPF1,
S3C2410_GPF2,
S3C2410_GPF3,
S3C2410_GPF4,
S3C2410_GPF5,
S3C2410_GPF6,
S3C2410_GPF0_INP,
S3C2410_GPF1_INP,
S3C2410_GPF2_INP,
S3C2410_GPF3_INP,
S3C2410_GPF4_INP,
S3C2410_GPF5_INP,
S3C2410_GPF6_INP,
};


static int keys_ioctl(struct inode *inode,struct file *file,unsigned int pin)
{
return s3c2410_gpio_getpin(key_table[pin]);
}

static struct file_operations keys_fops = {
.owner = THIS_MODULE,
.ioctl = keys_ioctl,
};
static struct cdev key_dev = {
.owner =  THIS_MODULE,
.ops = &keys_fops,
};

static struct class *key_class;
#define KEYDEVMINOR  0
dev_t dev_no;
static int __init keys_init(void)
{
int err = 0, count = 0, result;
//===================register in sysfs
result = alloc_chrdev_region(&dev_no, KEYDEVMINOR, count,
                "key_2410");
if(result
    cdev_init(&key_dev, &keys_fops);
    err = cdev_add (&key_dev, dev_no, 1);
    /* Fail gracefully if need be */
    if (err)
        printk(KERN_NOTICE "Error adding dev");
//============================================

/////////////////////////register in /udev
key_class = class_create(THIS_MODULE,"my_key_class");
if(IS_ERR(key_class))
{
  printk("err:failed in creating class.\n");
  return 0;
}
class_device_create(key_class,NULL,dev_no,NULL,"my_key_class");
//////////////////////////////////////////////
printk("key driver insert\n");
return err;
}

static void __exit keys_exit(void)
{
    cdev_del(&key_dev);
unregister_chrdev_region(dev_no,1);
   
class_device_destroy(key_class,dev_no);
class_destroy(key_class);
   
printk("key driver removed\n");
}

module_init(keys_init);
module_exit(keys_exit);

插入模块后
cat /proc/devices 输出有 254 key_2410 (alloc_chrdev_region()动态分配设备号函数中实现)
ls /sys/module/ 中有 key_driver (插入ko 模块时取的模块名)
ls /sys/class/ 中有my_key_class 目录(class_create() 创建类函数实现)
/dev 下有 my_key_class(class_device_create() 注册类函数中实现)
就现象来看,udev 是根据/sys/class 的更新来生成/dev 下的设备节点(如果我猜得不对,希望能有精通的哥们指正,谢谢!)

如果追求简单的话就注册成misc设备,上面的注册和注销函数换成下面

static struct miscdevice key_dev = {
  MISC_DYNAMIC_MINOR,
  "key_2410",
  &keys_fops,
};

static int __init keys_init(void)
{
int err = 0;
err = misc_register(&key_dev);
    if(err)
    {
        printk("could not register key devices. \n");
        return err;
    }
return err;
}

static void __exit keys_exit(void)
{
    misc_deregister(&key_dev);
        
printk("key driver removed\n");
}

注册成misc设备简单省事,对devfs 和 udev 通用,会直接在/dev 下生成设备结点,只是主设备号都是 10 misc ,不妨碍使用。

注:杂项设备(misc device)
用misc_register(&key_dev)注册,就是主设备号默认取10调用register_chrdev()来实现。
注销misc_deregister(&key_dev).此方法最简单省去了分配设备编号的麻烦


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/85787/showart_1675282.html

论坛徽章:
0
2 [报告]
发表于 2010-12-10 22:40 |只看该作者
好文章,顶一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP