字符
回帖 (1)
2021-12-23 14:51:22
概念
设备类 bus device driver 都是有比较明确定义的,bus 代表总线,device 代表实际的设备和接口,driver 代表驱动
class 是设备类,他是一个抽象的概念,没有对应的实体,它是提供给用户借口相似的一类设备的集合,常见的输入子系统input,u*** 串口tty,块设备block 等
生成设字符类设备节点
函数class_create 创建类文件
参数1一般是THIS_MODULE
参数2 设备名称
创建一个设备类用与节点文件的创建
返回一个class 结构体变量
class 结构体变量
class 是设备驱动模型中的通用设备类结构
在头文件include /linux /device.h 中定义
-class_destory 释放class
初始化代码中创建设备节点
创建设备节点函数device_create
头文件在include/linux/device.h
参数1设备所属的类
参数2设备的父设备,NULL
参数3设备号
参数4设备数据NULL
参数5设备名称
摧毁设备节点函数device_destory 参数1 所属类,参数2 设备号
释放内存kfree
源码
#include
#include
// 定义module_param module_param_arrary 函数的头文件
#include
// 定义参数函数中perm 参数的枚举量头文件
#include
// MKDEV 转换设备号数据类型的宏定义
#include
// 三个字符设备号函数
#include
// 定义字符设备的结构体
#include
// 分配内存空间的函数
#include
#defind DEVICE_NAME "dcdev";
#defind DEVICE_MINOR_NUM 2;
#defind DEVICE_MAJOR 0;// 主设备号
#defind DEVICE_MINOR 0;
#defind REGDEV_SIZE 3000;
#include ;
static struct class *myClass;
module_init(sdev_init);
module_exit(sdev_exit);
static int module_arg1,module_arg2;
static int int_array[50];
static int int_num;
int numdev_major = DEVICE_MAJOR;
int numdev_minor = DEVICE_MINOR;
/**/
// 输入主设备号
module_param(numdev_major,int,S_IRUSR);
// 输入次设备号
module_param(numdev_minor,int,S_IRUSR);
struct reg_dev{
char* data;
unsigned long size;
struct cdev cdev;
};
struct file_operations my_fops = {
.owner = THIS_MODULE,
};
static void ret_init_cdev(struct reg_dev * dev,int index){
int error;
/*数据初始化*/
int devno = MKDEV(numdev_major,numdev_minor+index);
cdev_init(&dev->cdev,&my_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &my_fops;
err = cdev_add(&dev->cdev,devno,1);
if(err){
printk(KERN_EMERG,"t cdev_add is fail err is %d n ",err);
}else{
printk(KERN_EMERG,"t cdev_add success! n" );
}
}
struct reg_dev* my_devices;
static int sdev_init(void)
{
int ret = -1;
dev_t num_dev;
if(numdev_major){// 如果0 则动态申请
num_dev = MKDEV(numdev_major,numdev_minor);
ret = register_chrdev_region(num_dev,DEVICE_MINOR_NUM,DEVICE_NAME);
}else{
ret = allo_chrdev_region(&num_dev,numdev_minor,DEVICE_MINOR_NUM,DEVICE_NAME);
numdev_major = MAJOR(num_dev);
printk(KERN_EMERG,"t numdev_major %d is failedn ",numdev_major);
}
if(!ret){
printk(KERN_EMERG,"t register_chrdev_region req %d is failedn ",numdev_major);
}
myClass = class_create(THIS_MODULE,DEVICE_NAME);
my_devices = kmalloc(DEVICE_MINOR_NUM*sizeof(struct reg_dev),GPF_KERNEL);
if(!my_devices){
ret = -ENOMEM;
goto fail;
return 0;
}
/*初始化设备*/
for(int i = 0 ;i < DEVICE_MINOR_NUM;i++){
my_devices.data = kmalloc(REGDEV_SIZE,GFP_KERNEL);
memset(my_devices.data,0,REGDEV_SIZE);
/*设备注册到系统*/
ret_init_cdev(&my_devices,i);
/*创建设备节点*/
device_create(myClass,NULL,MKDEV(numdev_major,numdev_minor+i),NULL,DEVICE_NAME"%d",i);
}
memset(my_devices,0,DEVICE_MINOR_NUM * sizeof(struct reg_dev));
printk(KERN_EMERG," dcdev enter!n ");
return 0;
fail:
/*注销设备号*/
unregister_chrdev_region(MKDEV(numdev_major,numdev_minor),DEVICE_MINOR_NUM);
printk(KERN_EMERG,"kmalloc is fail!n ");
return 0;
}
static int sdev_exit(void)
{
int i = 0;
printk(KERN_EMERG,"t cdev is:%dn ",module_arg2);
/*除去字符设备*/
for(i = 0;i < DEVICE_MINOR_NUM;i++){
cdev_del(&(my_devices->cdev));
device_destory(myClass,MKDEV(numdev_major,numdev_minor+i));
}
class_destory(myClass);
kfree(my_devices);
unregister_chrdev_region(MKDEV(numdev_major,numdev_minor),DEVICE_MINOR_NUM);
return 0;
}
ls /sys/class 能看到新的设备类节点
ls /dev/ 看到设备节点
手动创建设备节点
mknod dev/test0 c 249 0mknod dev/test0 c 249 1
概念
设备类 bus device driver 都是有比较明确定义的,bus 代表总线,device 代表实际的设备和接口,driver 代表驱动
class 是设备类,他是一个抽象的概念,没有对应的实体,它是提供给用户借口相似的一类设备的集合,常见的输入子系统input,u*** 串口tty,块设备block 等
生成设字符类设备节点
函数class_create 创建类文件
参数1一般是THIS_MODULE
参数2 设备名称
创建一个设备类用与节点文件的创建
返回一个class 结构体变量
class 结构体变量
class 是设备驱动模型中的通用设备类结构
在头文件include /linux /device.h 中定义
-class_destory 释放class
初始化代码中创建设备节点
创建设备节点函数device_create
头文件在include/linux/device.h
参数1设备所属的类
参数2设备的父设备,NULL
参数3设备号
参数4设备数据NULL
参数5设备名称
摧毁设备节点函数device_destory 参数1 所属类,参数2 设备号
释放内存kfree
源码
#include
#include
// 定义module_param module_param_arrary 函数的头文件
#include
// 定义参数函数中perm 参数的枚举量头文件
#include
// MKDEV 转换设备号数据类型的宏定义
#include
// 三个字符设备号函数
#include
// 定义字符设备的结构体
#include
// 分配内存空间的函数
#include
#defind DEVICE_NAME "dcdev";
#defind DEVICE_MINOR_NUM 2;
#defind DEVICE_MAJOR 0;// 主设备号
#defind DEVICE_MINOR 0;
#defind REGDEV_SIZE 3000;
#include ;
static struct class *myClass;
module_init(sdev_init);
module_exit(sdev_exit);
static int module_arg1,module_arg2;
static int int_array[50];
static int int_num;
int numdev_major = DEVICE_MAJOR;
int numdev_minor = DEVICE_MINOR;
/**/
// 输入主设备号
module_param(numdev_major,int,S_IRUSR);
// 输入次设备号
module_param(numdev_minor,int,S_IRUSR);
struct reg_dev{
char* data;
unsigned long size;
struct cdev cdev;
};
struct file_operations my_fops = {
.owner = THIS_MODULE,
};
static void ret_init_cdev(struct reg_dev * dev,int index){
int error;
/*数据初始化*/
int devno = MKDEV(numdev_major,numdev_minor+index);
cdev_init(&dev->cdev,&my_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &my_fops;
err = cdev_add(&dev->cdev,devno,1);
if(err){
printk(KERN_EMERG,"t cdev_add is fail err is %d n ",err);
}else{
printk(KERN_EMERG,"t cdev_add success! n" );
}
}
struct reg_dev* my_devices;
static int sdev_init(void)
{
int ret = -1;
dev_t num_dev;
if(numdev_major){// 如果0 则动态申请
num_dev = MKDEV(numdev_major,numdev_minor);
ret = register_chrdev_region(num_dev,DEVICE_MINOR_NUM,DEVICE_NAME);
}else{
ret = allo_chrdev_region(&num_dev,numdev_minor,DEVICE_MINOR_NUM,DEVICE_NAME);
numdev_major = MAJOR(num_dev);
printk(KERN_EMERG,"t numdev_major %d is failedn ",numdev_major);
}
if(!ret){
printk(KERN_EMERG,"t register_chrdev_region req %d is failedn ",numdev_major);
}
myClass = class_create(THIS_MODULE,DEVICE_NAME);
my_devices = kmalloc(DEVICE_MINOR_NUM*sizeof(struct reg_dev),GPF_KERNEL);
if(!my_devices){
ret = -ENOMEM;
goto fail;
return 0;
}
/*初始化设备*/
for(int i = 0 ;i < DEVICE_MINOR_NUM;i++){
my_devices.data = kmalloc(REGDEV_SIZE,GFP_KERNEL);
memset(my_devices.data,0,REGDEV_SIZE);
/*设备注册到系统*/
ret_init_cdev(&my_devices,i);
/*创建设备节点*/
device_create(myClass,NULL,MKDEV(numdev_major,numdev_minor+i),NULL,DEVICE_NAME"%d",i);
}
memset(my_devices,0,DEVICE_MINOR_NUM * sizeof(struct reg_dev));
printk(KERN_EMERG," dcdev enter!n ");
return 0;
fail:
/*注销设备号*/
unregister_chrdev_region(MKDEV(numdev_major,numdev_minor),DEVICE_MINOR_NUM);
printk(KERN_EMERG,"kmalloc is fail!n ");
return 0;
}
static int sdev_exit(void)
{
int i = 0;
printk(KERN_EMERG,"t cdev is:%dn ",module_arg2);
/*除去字符设备*/
for(i = 0;i < DEVICE_MINOR_NUM;i++){
cdev_del(&(my_devices->cdev));
device_destory(myClass,MKDEV(numdev_major,numdev_minor+i));
}
class_destory(myClass);
kfree(my_devices);
unregister_chrdev_region(MKDEV(numdev_major,numdev_minor),DEVICE_MINOR_NUM);
return 0;
}
ls /sys/class 能看到新的设备类节点
ls /dev/ 看到设备节点
手动创建设备节点
mknod dev/test0 c 249 0mknod dev/test0 c 249 1
举报
更多回帖