博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Class create, device create, device create file【转】
阅读量:5966 次
发布时间:2019-06-19

本文共 4241 字,大约阅读时间需要 14 分钟。

来自:

开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点(包括ldd3中不少例子也是这样),实际上现在Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点。

内核中定义了struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。

此外,利用device_create_file函数可以在/sys/class/下创建对应的属性文件,从而通过对该文件的读写实现特定的数据操作。

一、class_create

官方说明:

/* This is a #define to keep the compiler from merging different * instances of the __key variable */#define class_create(owner, name) \ ({ \ static struct lock_class_key __key; \ __class_create(owner, name, &__key); \ }) /** * class_create - create a struct class structure * @owner: pointer to the module that is to "own" this struct class * @name: pointer to a string for the name of this class. * @key: the lock_class_key for this class; used by mutex lock debugging * * This is used to create a struct class pointer that can then be used * in calls to device_create(). * * Returns &struct class pointer on success, or ERR_PTR() on error. * * Note, the pointer created here is to be destroyed when finished by * making a call to class_destroy(). */ struct class *__class_create(struct module *owner, const char *name, struct lock_class_key *key)

关键的一句是:

* This is used to create a struct class pointer that can then be used * in calls to device_create(). -->这个函数用来创建一个struct class的结构体指针,这个指针可用作device_create()函数的参数。

也就是说,这个函数主要是在调用device_create()前使用,创建一个struct class类型的变量,并返回其指针。

 

二、device_create

官方说明:

/** * device_create - creates a device and registers it with sysfs * @class: pointer to the struct class that this device should be registered to * @parent: pointer to the parent struct device of this new device, if any * @devt: the dev_t for the char device to be added * @drvdata: the data to be added to the device for callbacks * @fmt: string for the device's name * * This function can be used by char device classes.  A struct device * will be created in sysfs, registered to the specified class. * * A "dev" file will be created, showing the dev_t for the device, if * the dev_t is not 0,0. * If a pointer to a parent struct device is passed in, the newly created * struct device will be a child of that device in sysfs. * The pointer to the struct device will be returned from the call. * Any further sysfs files that might be required can be created using this * pointer. * * Returns &struct device pointer on success, or ERR_PTR() on error. * * Note: the struct class passed to this function must have previously * been created with a call to class_create(). */struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...)

首先解释一下"sysfs":sysfs是linux2.6所提供的一种虚拟档案系统;在设备模型中,sysfs文件系统用来表示设备的结构,将设备的层次结构形象的反应到用户空间中,从而可以通过修改sysfs中的文件属性来修改设备的属性值;sysfs被挂载到根目录下的"/sys"文件夹下。

 

三、device_create_file

官方说明:

/** * device_create_file - create sysfs attribute file for device. * @dev: device. * @attr: device attribute descriptor. */int device_create_file(struct device *dev, const struct device_attribute *attr)

使用这个函数时要引用 device_create所返回的device*指针,作用是在/sys/class/下创建一个属性文件,从而通过对这个属性文件进行读写就能完成对应的数据操作。

如:

a.在驱动程序中使用 device_create_file创建属性文件

static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, hello_val_show, hello_val_store); /*读取寄存器val的值到缓冲区buf中,内部使用*/ static ssize_t __hello_get_val(struct xxx_dev* dev, char* buf) { int val = 0; /*同步访问*/ if(down_interruptible(&(dev->sem))) { return -ERESTARTSYS; } val = dev->val; up(&(dev->sem)); return snprintf(buf, PAGE_SIZE, "%d/n", val); } /*把缓冲区buf的值写到设备寄存器val中去,内部使用*/ static ssize_t __hello_set_val(struct xxx_dev* dev, const char* buf, size_t count) { int val = 0; /*将字符串转换成数字*/ val = simple_strtol(buf, NULL, 10); /*同步访问*/ if(down_interruptible(&(dev->sem))) { return -ERESTARTSYS; } dev->val = val; up(&(dev->sem)); return count; } /*读取设备属性val*/ static ssize_t hello_val_show(struct device* dev, struct device_attribute* attr, char* buf) { struct xxx_dev* hdev = (struct xxx_dev*)dev_get_drvdata(dev); return __hello_get_val(hdev, buf); } /*写设备属性val*/ static ssize_t hello_val_store(struct device* dev, struct device_attribute* attr, const

转载于:https://www.cnblogs.com/sky-heaven/p/4741799.html

你可能感兴趣的文章
linux之权限之隐藏权限
查看>>
XDCTF成长记录
查看>>
Linux系统中的文本处理工具
查看>>
IDE---Python IDE之Eric5在window下的安装
查看>>
Mybatis调用Oracle中的存储过程和function
查看>>
telnet :No route to host
查看>>
基本安装lnmp环境
查看>>
yum源资料汇总
查看>>
7、MTC与MTV,http请求介绍
查看>>
logstash消费阿里云kafka消息
查看>>
第四节课作业
查看>>
EasyUI Calendar 日历
查看>>
unix 环境高级编程
查看>>
为数据库建立索引
查看>>
第二周作业-软件工作量的估计
查看>>
MAXIMO 快速查找实现
查看>>
Oracle——条件控制语句
查看>>
[Linux][Redis][05]Benchmark
查看>>
第一次作业-准备篇
查看>>
HDU1848 Fibonacci again and again
查看>>