device_create device_destroy 使用==mknod及通过class_create自动创建设备节点
2013-12-04 02:00
441 查看
1. device_create()
文件包含: #include <linux/device.h>
函数定义:
函数位置: src/drivers/base/core.c
函数格式:
extern struct device *device_create(struct class
*cls, struct device *parent,dev_t devt, void
*drvdata, const
char *fmt,
...)
函数功能:
函数device_create()用于动态的建立逻辑设备,并对新的逻辑设备类进行相应初始化,将其与函数的第一个参数所代表的逻辑类关联起来,然后将此逻辑设备加到linux内核系统的设备驱动程序模型中。函数能够自动在/sys/devices/virtual目录下创建新的逻辑设备目录,在/dev目录下创建于逻辑类对应的设备文件
参数说明:
struct class cls:与即将创建额逻辑设备相关的逻辑类,在“class类 class_create使用”说明了。
dev_t dev:设备号
void *drvdata: void类型的指针,代表回调函数的输入参数
const char *fmt: 逻辑设备的设备名,即在目录 /sys/devices/virtual创建的逻辑设备目录的目录名。
2.函数device_destroy()
文件包含:#include <linux/device.h>
函数定义: src/drivers/base/core.c
void device_destroy(struct class *dev, dev_t devt);
函数功能:
函数device_destroy()用于从linux内核系统设备驱动程序模型中移除一个设备,并删除/sys/devices/virtual目录下对应的设备目录及/dev/目录下对应的设备文件
======================================================================
class_create() 和 device_create()有什么关系呢??
在刚开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,实际上Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点,当然前提条件是用户空间移植了udev。什么事udev??请查看“ 收集
3个介绍uedv 网址资料 ”
内核中定义了struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
在下面的例子中具体说明关系!!!!!!!!
1. 首先通过 mem_class = class_create(THIS_MODULE,"ywx_class_char");语句建立了逻辑设备类,在 /sys/class/
下新建了 ywx_class_char目录 查看:
ywx@ywx:/sys/class$ ls ywx_class_char
ywx_device_char
2. 通过语句 device_create(mem_class,NULL,MKDEV(MEM_MAJOR,MEM_MINOR),NULL,"ywx_device_char");阿在
/dev/ 下自动建立了 ywx_device_char 设备节点 ,具体查看:
ywx@ywx:/dev$ ls
-l ywx_device_char
crw-------
1 root root 240, 0 2012-01-03 15:40
ywx_device_char
3.那么 class_create 和 device_create还有什么关系呢??
在/sys/devices/virtual/建立了 “ywx_class_char”
在/sys/devices/virtual/ywx/class/char/下建立了 ywx_device_char 目录
ywx@ywx:/sys/devices/virtual/ywx_class_char/ywx_device_char$
ls -la
total 0
drwxr-xr-x 3 root root 0 2012-01-03 15:40
.
drwxr-xr-x 3 root root 0 2012-01-03 15:40
..
-r--r--r--
1 root root 4096 2012-01-03 16:10
dev 这个就是我们在驱动中分配的大小4KB
drwxr-xr-x 2 root root 0 2012-01-03 16:10 power
lrwxrwxrwx 1 root root 0 2012-01-03 15:40 subsystem
->
../../../../class/ywx_class_char符号链接设备
-rw-r--r-- 1 root root 4096 2012-01-03
15:40 uevent
======================================================================
drivers/i2c/i2c-dev.c 也有关于 class_create的例子
i2c_dev_class =
class_create(THIS_MODULE,
"i2c-dev");
====================================================================
自己的字符设备驱动程序
程序代码附加:
cdev_init_add_del.rar
将rar修改为tar.bz2
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/slab.h>//kmalloc
#include <linux/vmalloc.h>//vmalloc()
#include <linux/types.h>//ssize_t
#include <linux/fs.h>//file_operaiotns
#include <linux/uaccess.h>//copy_from_user
#define MEM_MALLOC_SIZE 4096 ////缓冲区大小
#define MEM_MAJOR 240 ////主设备号
#define MEM_MINOR 0
char *mem_spvm
= NULL;
////缓冲区指针,指向内存区
struct cdev *mem_cdev
= NULL;
//字符设备对象指针
struct class *mem_class
= NULL;
//设备类指针
static int __init mem_init(void);
static void __exit mem_exit(void);
static int mem_open(struct inode
*inode,struct file
*filp);
static int mem_release(struct inode
*inode, struct file
*filp);
static ssize_t mem_read(struct file
*filp,char __user
*buf,size_t count,loff_t
*fpos);
static ssize_t mem_write(struct file
*filp, char __user
*buf,size_t count
,loff_t *fops);
static const struct file_operations mem_fops={
.owner = THIS_MODULE,
.open = mem_open,
.release = mem_release,
.read = mem_read,
.write = mem_write,
};
static int __init mem_init(void)
{
int ret;
//创建设备号 主次设备号
int devno
= MKDEV(MEM_MAJOR,MEM_MINOR);
printk("mem_init initial...\n");
//开辟内核内存缓冲区
mem_spvm =
(char *)vmalloc(MEM_MALLOC_SIZE);
if(mem_spvm
==
NULL)
{
printk("vmalloc mem_spvm error\n");
return -ENOMEM;//
}
//
mem_cdev = cdev_alloc();
if(mem_cdev
==
NULL)
{
printk("cdev_alloc error\n");
return -ENOMEM;
}
cdev_init(mem_cdev,&mem_fops);
mem_cdev->owner
= THIS_MODULE;
ret = cdev_add(mem_cdev,devno,1);//将字符设备键入内核系统
if(ret)
{
cdev_del(mem_cdev);
mem_cdev =
NULL;
printk("cdev_add error\n");
return -1;
}
//
mem_class = class_create(THIS_MODULE,"ywx_class_char");
if(IS_ERR(mem_class))
{
printk("class_create error..\n");
return -1;
}
device_create(mem_class,NULL,MKDEV(MEM_MAJOR,MEM_MINOR),NULL,"ywx_device_char");
printk("init finished..\n");
return 0;
}
static void __exit mem_exit(void)
{
printk("mem_exit starting..\n");
if(mem_cdev
!=
NULL)
cdev_del(mem_cdev);
printk("cdev_del ok\n");
device_destroy(mem_class,MKDEV(MEM_MAJOR,MEM_MINOR));
class_destroy(mem_class);
if(mem_spvm
!=
NULL)
vfree(mem_spvm);
printk("vfree ok\n");
printk("mem_exit finished..\n");
}
static int mem_open(struct inode
*inode,struct file
*filp)
{
printk("open vmalloc space..\n");
try_module_get(THIS_MODULE);//模块引用计数器自加
printk("open vamlloc space ok..\n");
return 0;
}
static int mem_release(struct inode
*inode, struct file
*filp)
{
printk("close vmalloc space..\n");
module_put(THIS_MODULE);//模块引用计数器自减
return 0;
}
static ssize_t mem_read(struct file
*filp,char __user
*buf,size_t count,loff_t
*fpos)
{
int ret =
-1;
char *tmp;
printk("copy data to the user space\n");
tmp = mem_spvm;
if(count
> MEM_MALLOC_SIZE)
count = MEM_MALLOC_SIZE;
if(tmp
!=
NULL)//将内核数据写入到用户空间
ret = copy_to_user(buf,tmp,count);
if(ret
== 0)
{
printk("read copy data success\n");
return count;
}
else
{
printk("read copy data error\n");
return 0;
}
}
static ssize_t mem_write(struct file
*filp, char __user
*buf,size_t count
,loff_t *fops)
{
int ret =
-1;
char *tmp;
printk("read data from the user space.\n");
tmp = mem_spvm;
if(count
> MEM_MALLOC_SIZE)
count = MEM_MALLOC_SIZE;
if(tmp
!=
NULL)
ret = copy_from_user(tmp,buf,count);
if(ret
== 0)
{
printk("write copy data success.\n");
return count;
}
else
{
printk("write copy data error.\n");
return 0;
}
}
MODULE_LICENSE("GPL");
module_init(mem_init);
module_exit(mem_exit);
应用程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>//memset()
int main(int argc, char
*argv[])
{
int fd,cnt;
char buf[256];
int i;
printf("char device testing..\n");
fd = open("/dev/ywx_device_char",O_RDWR);
if(fd
== 0)
{
printf("open failed.\n");
return 1;
}
printf("input the data for kernel:");
scanf("%s",buf);
cnt = write(fd,buf,256);
if(cnt
== 0)
printf("write error\n");
printf("clear buf,and will read from kernel...\n");
for(i=0;i<256;i++)
buf[i]
= 32;//32
=" "
cnt = read(fd,buf,256);
if(cnt
> 0)
printf("read data from kernel is:%s\n",buf);
else
printf("read data error\n");
close(fd);
printf("close app..\n");
return 0;
}
应用程序测试:
root@ywx:/home/ywx/desktop/module/api_/cdev_init_add_del/app#
./app
char device testing..
input the data for kernel:yuweixian4230.blog.chinaunix.net
clear buf,and will read from kernel...
read data from kernel is:yuweixian4230.blog.chinaunix.net
close app..
文件包含: #include <linux/device.h>
函数定义:
函数位置: src/drivers/base/core.c
函数格式:
extern struct device *device_create(struct class
*cls, struct device *parent,dev_t devt, void
*drvdata, const
char *fmt,
...)
函数功能:
函数device_create()用于动态的建立逻辑设备,并对新的逻辑设备类进行相应初始化,将其与函数的第一个参数所代表的逻辑类关联起来,然后将此逻辑设备加到linux内核系统的设备驱动程序模型中。函数能够自动在/sys/devices/virtual目录下创建新的逻辑设备目录,在/dev目录下创建于逻辑类对应的设备文件
参数说明:
struct class cls:与即将创建额逻辑设备相关的逻辑类,在“class类 class_create使用”说明了。
dev_t dev:设备号
void *drvdata: void类型的指针,代表回调函数的输入参数
const char *fmt: 逻辑设备的设备名,即在目录 /sys/devices/virtual创建的逻辑设备目录的目录名。
2.函数device_destroy()
文件包含:#include <linux/device.h>
函数定义: src/drivers/base/core.c
void device_destroy(struct class *dev, dev_t devt);
函数功能:
函数device_destroy()用于从linux内核系统设备驱动程序模型中移除一个设备,并删除/sys/devices/virtual目录下对应的设备目录及/dev/目录下对应的设备文件
======================================================================
class_create() 和 device_create()有什么关系呢??
在刚开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,实际上Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点,当然前提条件是用户空间移植了udev。什么事udev??请查看“ 收集
3个介绍uedv 网址资料 ”
内核中定义了struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
在下面的例子中具体说明关系!!!!!!!!
1. 首先通过 mem_class = class_create(THIS_MODULE,"ywx_class_char");语句建立了逻辑设备类,在 /sys/class/
下新建了 ywx_class_char目录 查看:
ywx@ywx:/sys/class$ ls ywx_class_char
ywx_device_char
2. 通过语句 device_create(mem_class,NULL,MKDEV(MEM_MAJOR,MEM_MINOR),NULL,"ywx_device_char");阿在
/dev/ 下自动建立了 ywx_device_char 设备节点 ,具体查看:
ywx@ywx:/dev$ ls
-l ywx_device_char
crw-------
1 root root 240, 0 2012-01-03 15:40
ywx_device_char
3.那么 class_create 和 device_create还有什么关系呢??
在/sys/devices/virtual/建立了 “ywx_class_char”
在/sys/devices/virtual/ywx/class/char/下建立了 ywx_device_char 目录
ywx@ywx:/sys/devices/virtual/ywx_class_char/ywx_device_char$
ls -la
total 0
drwxr-xr-x 3 root root 0 2012-01-03 15:40
.
drwxr-xr-x 3 root root 0 2012-01-03 15:40
..
-r--r--r--
1 root root 4096 2012-01-03 16:10
dev 这个就是我们在驱动中分配的大小4KB
drwxr-xr-x 2 root root 0 2012-01-03 16:10 power
lrwxrwxrwx 1 root root 0 2012-01-03 15:40 subsystem
->
../../../../class/ywx_class_char符号链接设备
-rw-r--r-- 1 root root 4096 2012-01-03
15:40 uevent
======================================================================
drivers/i2c/i2c-dev.c 也有关于 class_create的例子
i2c_dev_class =
class_create(THIS_MODULE,
"i2c-dev");
====================================================================
自己的字符设备驱动程序
程序代码附加:
cdev_init_add_del.rar
将rar修改为tar.bz2
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/slab.h>//kmalloc
#include <linux/vmalloc.h>//vmalloc()
#include <linux/types.h>//ssize_t
#include <linux/fs.h>//file_operaiotns
#include <linux/uaccess.h>//copy_from_user
#define MEM_MALLOC_SIZE 4096 ////缓冲区大小
#define MEM_MAJOR 240 ////主设备号
#define MEM_MINOR 0
char *mem_spvm
= NULL;
////缓冲区指针,指向内存区
struct cdev *mem_cdev
= NULL;
//字符设备对象指针
struct class *mem_class
= NULL;
//设备类指针
static int __init mem_init(void);
static void __exit mem_exit(void);
static int mem_open(struct inode
*inode,struct file
*filp);
static int mem_release(struct inode
*inode, struct file
*filp);
static ssize_t mem_read(struct file
*filp,char __user
*buf,size_t count,loff_t
*fpos);
static ssize_t mem_write(struct file
*filp, char __user
*buf,size_t count
,loff_t *fops);
static const struct file_operations mem_fops={
.owner = THIS_MODULE,
.open = mem_open,
.release = mem_release,
.read = mem_read,
.write = mem_write,
};
static int __init mem_init(void)
{
int ret;
//创建设备号 主次设备号
int devno
= MKDEV(MEM_MAJOR,MEM_MINOR);
printk("mem_init initial...\n");
//开辟内核内存缓冲区
mem_spvm =
(char *)vmalloc(MEM_MALLOC_SIZE);
if(mem_spvm
==
NULL)
{
printk("vmalloc mem_spvm error\n");
return -ENOMEM;//
}
//
mem_cdev = cdev_alloc();
if(mem_cdev
==
NULL)
{
printk("cdev_alloc error\n");
return -ENOMEM;
}
cdev_init(mem_cdev,&mem_fops);
mem_cdev->owner
= THIS_MODULE;
ret = cdev_add(mem_cdev,devno,1);//将字符设备键入内核系统
if(ret)
{
cdev_del(mem_cdev);
mem_cdev =
NULL;
printk("cdev_add error\n");
return -1;
}
//
mem_class = class_create(THIS_MODULE,"ywx_class_char");
if(IS_ERR(mem_class))
{
printk("class_create error..\n");
return -1;
}
device_create(mem_class,NULL,MKDEV(MEM_MAJOR,MEM_MINOR),NULL,"ywx_device_char");
printk("init finished..\n");
return 0;
}
static void __exit mem_exit(void)
{
printk("mem_exit starting..\n");
if(mem_cdev
!=
NULL)
cdev_del(mem_cdev);
printk("cdev_del ok\n");
device_destroy(mem_class,MKDEV(MEM_MAJOR,MEM_MINOR));
class_destroy(mem_class);
if(mem_spvm
!=
NULL)
vfree(mem_spvm);
printk("vfree ok\n");
printk("mem_exit finished..\n");
}
static int mem_open(struct inode
*inode,struct file
*filp)
{
printk("open vmalloc space..\n");
try_module_get(THIS_MODULE);//模块引用计数器自加
printk("open vamlloc space ok..\n");
return 0;
}
static int mem_release(struct inode
*inode, struct file
*filp)
{
printk("close vmalloc space..\n");
module_put(THIS_MODULE);//模块引用计数器自减
return 0;
}
static ssize_t mem_read(struct file
*filp,char __user
*buf,size_t count,loff_t
*fpos)
{
int ret =
-1;
char *tmp;
printk("copy data to the user space\n");
tmp = mem_spvm;
if(count
> MEM_MALLOC_SIZE)
count = MEM_MALLOC_SIZE;
if(tmp
!=
NULL)//将内核数据写入到用户空间
ret = copy_to_user(buf,tmp,count);
if(ret
== 0)
{
printk("read copy data success\n");
return count;
}
else
{
printk("read copy data error\n");
return 0;
}
}
static ssize_t mem_write(struct file
*filp, char __user
*buf,size_t count
,loff_t *fops)
{
int ret =
-1;
char *tmp;
printk("read data from the user space.\n");
tmp = mem_spvm;
if(count
> MEM_MALLOC_SIZE)
count = MEM_MALLOC_SIZE;
if(tmp
!=
NULL)
ret = copy_from_user(tmp,buf,count);
if(ret
== 0)
{
printk("write copy data success.\n");
return count;
}
else
{
printk("write copy data error.\n");
return 0;
}
}
MODULE_LICENSE("GPL");
module_init(mem_init);
module_exit(mem_exit);
应用程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>//memset()
int main(int argc, char
*argv[])
{
int fd,cnt;
char buf[256];
int i;
printf("char device testing..\n");
fd = open("/dev/ywx_device_char",O_RDWR);
if(fd
== 0)
{
printf("open failed.\n");
return 1;
}
printf("input the data for kernel:");
scanf("%s",buf);
cnt = write(fd,buf,256);
if(cnt
== 0)
printf("write error\n");
printf("clear buf,and will read from kernel...\n");
for(i=0;i<256;i++)
buf[i]
= 32;//32
=" "
cnt = read(fd,buf,256);
if(cnt
> 0)
printf("read data from kernel is:%s\n",buf);
else
printf("read data error\n");
close(fd);
printf("close app..\n");
return 0;
}
应用程序测试:
root@ywx:/home/ywx/desktop/module/api_/cdev_init_add_del/app#
./app
char device testing..
input the data for kernel:yuweixian4230.blog.chinaunix.net
clear buf,and will read from kernel...
read data from kernel is:yuweixian4230.blog.chinaunix.net
close app..
相关文章推荐
- device_create device_destroy 使用==mknod及通过class_create自动创建设备节点
- device_create device_destroy 使用==mknod及通过class_create自动创建设备节点
- 驱动中使用class_device_create()报错的原因,自动创建设备节点
- (一)小记——驱动中使用class_device_create()报错的原因、自动创建设备节点
- 使用class_create(),device_create()为设备自动创建文件结点
- Linux下使用class_create,device_create自动创建设备文件结点
- 关于class_create(),device_create自动创建设备文件结点,class_device_create和class_device_destroy,
- 自动创建设备节点class_create 和device_create
- 关于使用 class_create,device_create,class_device_create 创建设备节点
- class_create(),class_device_create()或device_create()自动创建设备节点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点 .
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点(文章出处没找到)
- class_create(),class_device_create()或device_create()自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点【转】