cdev_init和register_chrdev区别
---
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区别的更多相关文章
- register_chrdev、register_chrdev_region以及alloc_chrdev_region之间的区别
register_chrdev:Linux2.6.30之前所用,不用定义cdev:但 如果是register_chrdev 注册的话,这个时候,分配的次设备号,是从0~255,这样子的话,就分配的范围 ...
- misc_register、 register_chrdev 的区别总结
参考: http://longer.spaces.eepw.com.cn/articles/article/item/60415 http://imganquan.org/blog/?p=350 网上 ...
- 转:misc_register、 register_chrdev 的区别总结
杂项设备(misc device) 杂项设备也是在嵌入式系统中用得比较多的一种设备驱动.在 Linux 内核的include/linux目录下有Miscdevice.h文件,要把自己定义的misc d ...
- ⭐register_chrdev、register_chrdev_region以及alloc_chrdev_region之间的区别
register_chrdev:Linux2.6.30之前所用,不用定义cdev:但 如果是register_chrdev 注册的话,这个时候,分配的次设备号,是从0~255,这样子的话,就分配的范围 ...
- cdev_alloc与cdev_init区别
struct cdev *cdev_alloc(void) { struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); if (p) { ...
- 【整理】--【字符设备】分配设备号register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()
(1) 分配设备编号,注册设备与注销设备的函数均在fs.h中声明,如下: extern int register_chrdev_region(dev_t,unsigned int,const char ...
- linux驱动---字符设备的注册register_chrdev说起
首先我们在注册函数里面调用了register_chrdev(MEM_MAJOR,"mem",&memory_fops),向内核注册了一个字符设备. 第一个参数是主设备号,0 ...
- udev和devfs的区别
devfs(设备文件系统)是由Linux2.4内核引入的,它的出现主要使得设备驱动程序能够自主管理自己的设备文件.具体来说,devfs具有如下优点: 可以通过程序在设备初始化时在/dev目录下创建设备 ...
- 字符设备之register_chrdev与register_chrdev_region(转)
之前写字符设备驱动,都是使用register_chrdev向内核注册驱动程序中构建的file_operations结构体,之后创建的设备文件,只要是主设备号相同(次设备号不同),则绑定的都是同一个fi ...
随机推荐
- swift-delegate(代理)或者block传值
1:delegate或者block传值 import UIKit class ViewController: UIViewController,TestDelegatePassValueDelegat ...
- Laravel5.1学习笔记3 HTTP中间件
HTTP 中间件 简介 建立中间件 注册中间件 可终止中间件 简介 HTTP 中间件提供一个方便的机制来过滤进入应用程序的 HTTP 请求,例如,Laravel 默认包含了一个中间件来检验用户身份验证 ...
- Java导入excel并保存到数据库
首先建立好excel表格,并对应excel表格创建数据库表. 前台jsp页面:其中包含js <%@ page language="java" import="jav ...
- Linux通信之poll机制分析
poll机制分析 韦东山 2009.12.10 所有的系统调用,基于都可以在它的名字前加上“sys_”前缀,这就是它在内核中对应的函数.比如系统调用open.read.write.poll,与之对应的 ...
- 使用replace pioneer批量修改文件名
shell的正则表达式还是很难记忆的,也没有沉静的心情看文档,于是使用了replace pioneer. 1. 启动replace pioneer,Tools->batch runner , ...
- 修改默认的gitlab clone地址,要不每次都得自己修改
这个是无法clone的,得换成gitlab的ip地址 下面进行修改 sudo vim /opt/gitlab/embedded/service/gitlab-rails/config/ ...
- c# cookie帮助类
using System; using System.Collections.Generic; using System.Text; using System.Web; namespace Matic ...
- vue 导航菜单默认子路由
export default new Router({ routes: [ { path: '/', name: 'index', component: index, children: [ { pa ...
- Idea 方法注释
Idea 方法注释 http://blog.csdn.net/u014044812/article/details/76577479 http://blog.csdn.net/leixingbang1 ...
- Linux shell文本处理工具
搞定Linux Shell文本处理工具,看完这篇集锦就够了 Linux Shell是一种基本功,由于怪异的语法加之较差的可读性,通常被Python等脚本代替.既然是基本功,那就需要掌握,毕竟学习She ...