linux字符驱动

字符驱动:cdev一般有两种初始化方式:静态和动态

GFP_KERNEL:在linux/gfp.h中定义的一个宏,是分配内核空间的内存时的一个标志位。

静态1: struct cdev my_cdev;
    cdev_init(&my_cdev,&fops);
    my_cdev.owner=THIS_MODULE;
    cdev_add(my_cdev, my_dev, 1 );

静态2: struct user_dev{
    int uerdata;
    struct cdev cdev;
};
    struct user_dev *my_dev;
    my_dev=kmalloc(sizeof(struct user_dev),GFP_KERNEL);    
    my_dev->userdata=0;
    cdev_init(&my_dev->cdev,&fops);
    my_dev->cdev.owner=THIS_MODULE;
    cdev_add(&my_dev->cdev,my_dev,1);


动态: struct cdev* my_dev;
        my_dev=cdev_alloc();
    my_cdev->ops=&fops;   // 注意这些,别忘添加
    my_cdev->owner=THIS_MODULE;
    //cdev_init(my_cdev,&fops);//可以去掉
    cdev_add(my_cdev, my_dev, 1 );


struct cdev *cdev_alloc(void)
{
   struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
   if (p) {
       INIT_LIST_HEAD(&p->list);
       kobject_init(&p->kobj, &ktype_cdev_dynamic);
   }
   return p;
}

void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
   memset(cdev, 0, sizeof *cdev);
   INIT_LIST_HEAD(&cdev->list);
   kobject_init(&cdev->kobj, &ktype_cdev_default);
   cdev->ops = fops;
}
两个函数完成都功能基本一致,只是 cdev_init() 还多赋了一个 cdev->ops 的值。

int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
   p->dev = dev;
   p->count = count;
   return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
}

void cdev_del(struct cdev *p)
{
   cdev_unmap(p->dev, p->count);
   kobject_put(&p->kobj);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值