---

01:include/linux/fs.h

static inline int register_chrdev(unsigned int major, const char *name,                                                              const struct file_operations *fops)
{
return __register_chrdev(major, , , name, fops);
}

fs/char_dev.c

/**
* __register_chrdev() - create and register a cdev occupying a range of minors
* @major: major device number or 0 for dynamic allocation
* @baseminor: first of the requested range of minor numbers
* @count: the number of minor numbers required
* @name: name of this range of devices
* @fops: file operations associated with this devices
*
* If @major == 0 this functions will dynamically allocate a major and return
* its number.
*
* If @major > 0 this function will attempt to reserve a device with the given
* major number and will return zero on success.
*
* Returns a -ve errno on failure.
*
* The name of this device has nothing to do with the name of the device in
* /dev. It only helps to keep track of the different owners of devices. If
* your module name has only one type of devices it's ok to use e.g. the name
* of the module here.
*/
int __register_chrdev(unsigned int major, unsigned int baseminor,
¦ ¦ unsigned int count, const char *name,
¦ ¦ const struct file_operations *fops)
{
struct char_device_struct *cd;
struct cdev *cdev;
int err = -ENOMEM; cd = __register_chrdev_region(major, baseminor, count, name);
if (IS_ERR(cd))
return PTR_ERR(cd); cdev = cdev_alloc();
if (!cdev)
goto out2; cdev->owner = fops->owner;
cdev->ops = fops;
kobject_set_name(&cdev->kobj, "%s", name); err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);
if (err)
goto out; cd->cdev = cdev; return major ? : cd->major;
out:
kobject_put(&cdev->kobj);
out2:
kfree(__unregister_chrdev_region(cd->major, baseminor, count));
return err;
}

02:fs/char_dev.c

/**
* cdev_init() - initialize a cdev structure
* @cdev: the structure to initialize
* @fops: the file_operations for this device
*
* Initializes @cdev, remembering @fops, making it ready to add to the
* system with cdev_add().
*/
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, , sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj, &ktype_cdev_default);
cdev->ops = fops;
}

---------------------------------使用--------------------------

static int flashlight_probe(struct platform_device *dev)
{
int ret = , err = ; logI("[flashlight_probe] start ~"); #ifdef ALLOC_DEVNO
ret = alloc_chrdev_region(&flashlight_devno, , , FLASHLIGHT_DEVNAME);
if (ret) {
logI("[flashlight_probe] alloc_chrdev_region fail: %d ~", ret);
goto flashlight_probe_error;
} else {
logI("[flashlight_probe] major: %d, minor: %d ~", MAJOR(flashlight_devno),
¦ ¦MINOR(flashlight_devno));
}
cdev_init(&flashlight_cdev, &flashlight_fops);
flashlight_cdev.owner = THIS_MODULE;
err = cdev_add(&flashlight_cdev, flashlight_devno, );
if (err) {
logI("[flashlight_probe] cdev_add fail: %d ~", err);
goto flashlight_probe_error;
}
#else
#define FLASHLIGHT_MAJOR 242
ret = register_chrdev(FLASHLIGHT_MAJOR, FLASHLIGHT_DEVNAME, &flashlight_fops);
if (ret != ) {
logI("[flashlight_probe] Unable to register chardev on major=%d (%d) ~",
¦ ¦FLASHLIGHT_MAJOR, ret);
return ret;
}
flashlight_devno = MKDEV(FLASHLIGHT_MAJOR, );
#endif flashlight_class = class_create(THIS_MODULE, "flashlightdrv");
if (IS_ERR(flashlight_class)) {
logI("[flashlight_probe] Unable to create class, err = %d ~",
¦ ¦(int)PTR_ERR(flashlight_class));
goto flashlight_probe_error;
}
flashlight_device =
¦ device_create(flashlight_class, NULL, flashlight_devno, NULL, FLASHLIGHT_DEVNAME);
if (NULL == flashlight_device) {
logI("[flashlight_probe] device_create fail ~");
goto flashlight_probe_error;
} /* initialize members */
spin_lock_init(&flashlight_private.lock);
init_waitqueue_head(&flashlight_private.read_wait);
/* init_MUTEX(&flashlight_private.sem); */
sema_init(&flashlight_private.sem, ); flashlight_gpio_init(dev);
logI("[flashlight_probe] Done ~");
return ; flashlight_probe_error:
#ifdef ALLOC_DEVNO
if (err == )
cdev_del(&flashlight_cdev);
if (ret == )
unregister_chrdev_region(flashlight_devno, );
#else
if (ret == )
unregister_chrdev(MAJOR(flashlight_devno), FLASHLIGHT_DEVNAME);
#endif
return -;
}

---

cdev_init和register_chrdev区别的更多相关文章

  1. register_chrdev、register_chrdev_region以及alloc_chrdev_region之间的区别

    register_chrdev:Linux2.6.30之前所用,不用定义cdev:但 如果是register_chrdev 注册的话,这个时候,分配的次设备号,是从0~255,这样子的话,就分配的范围 ...

  2. misc_register、 register_chrdev 的区别总结

    参考: http://longer.spaces.eepw.com.cn/articles/article/item/60415 http://imganquan.org/blog/?p=350 网上 ...

  3. 转:misc_register、 register_chrdev 的区别总结

    杂项设备(misc device) 杂项设备也是在嵌入式系统中用得比较多的一种设备驱动.在 Linux 内核的include/linux目录下有Miscdevice.h文件,要把自己定义的misc d ...

  4. ⭐register_chrdev、register_chrdev_region以及alloc_chrdev_region之间的区别

    register_chrdev:Linux2.6.30之前所用,不用定义cdev:但 如果是register_chrdev 注册的话,这个时候,分配的次设备号,是从0~255,这样子的话,就分配的范围 ...

  5. cdev_alloc与cdev_init区别

    struct cdev *cdev_alloc(void) { struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); if (p) { ...

  6. 【整理】--【字符设备】分配设备号register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()

    (1) 分配设备编号,注册设备与注销设备的函数均在fs.h中声明,如下: extern int register_chrdev_region(dev_t,unsigned int,const char ...

  7. linux驱动---字符设备的注册register_chrdev说起

    首先我们在注册函数里面调用了register_chrdev(MEM_MAJOR,"mem",&memory_fops),向内核注册了一个字符设备. 第一个参数是主设备号,0 ...

  8. udev和devfs的区别

    devfs(设备文件系统)是由Linux2.4内核引入的,它的出现主要使得设备驱动程序能够自主管理自己的设备文件.具体来说,devfs具有如下优点: 可以通过程序在设备初始化时在/dev目录下创建设备 ...

  9. 字符设备之register_chrdev与register_chrdev_region(转)

    之前写字符设备驱动,都是使用register_chrdev向内核注册驱动程序中构建的file_operations结构体,之后创建的设备文件,只要是主设备号相同(次设备号不同),则绑定的都是同一个fi ...

随机推荐

  1. 设计模式之桥接模式(Java语言描述)

    桥接模式定义 將抽象部分与它的具体实现部分分离,使它们都可以独立地变化.它是一种对象结构型模式,又称为柄体模式或接口模式. Decouple an abstraction from its imple ...

  2. 《深入理解Android虚拟机内存管理》示例程序编译阶段生成的各种语法树完整版

    1.tokens "int"                   "int" <SPACES>                " &quo ...

  3. mui图片懒加载

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  4. 【Oracle】truncate分区表

    分区表是生产中常用的一种表,它可以实现数据的按类存放,极大的提高了数据的查询及维护.当我们不需要某一分区的数据时,可以采用truncate来清空分区.实验如下: SQL)) partition by ...

  5. 指定DIV局部刷新的简单实现,很简单,但是网上搜到的大部分都很复杂

    脚本部分: <script type="text/javascript"> $(function () { setInterval(function () { $(&q ...

  6. WebGL绘制三角形

    本文程序实现绘制一个三角形的任务,如下图. 整个程序包含两个文件,分别是: 1. HelloTriangle.html <!DOCTYPE HTML PUBLIC "-//W3C//D ...

  7. Cache-Control 机制是为浏览器定制的?

    Cache-Control 机制是为浏览器定制的?

  8. vue系列---identify(生成图片验证码)插件

    identify 这是一个vue的插件,使用canvas来生成图形验证码. 具体参数如下: identify.vue组件(主要用于定义参数和方法) <template> <div c ...

  9. spring cloud(五) hystrix

    开启feign 熔断 hystrix    整合hystrix-dashboard监控面板 1. 服务调用者boot工程 pom引入依赖 <!-- hystrix-dashboard 监控依赖 ...

  10. [luogu2414 NOI2011]阿狸的打字机 (AC自动机)

    传送门 Solution 我们知道AC自动机上如果有一点A的fail[A]->B那么B为A的一个后缀 那么我们的问题\((x,y)\)就变为在y中有多少个点直接或间接连向x的终止节点 如果写暴力 ...