使用register_chdev注册多个次设备号

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>

static int major = 237;
static int minor = 0;
static int err;
static dev_t devno;
static struct class *hello_class;
struct device dev;
#define name "hello"

#define MAX_COM_NUM 2

struct mydev{
	struct cdev cdev;
	char *reg;
};
struct mydev *pmydev[MAX_COM_NUM];

ssize_t dev_fifo_read (struct file *file, char __user *buf, size_t size, loff_t *pos)
{
	struct mydev *cd;

	cd = (struct mydev *)file->private_data;
	printk("read()       file->private_data         cd->test=%d\n",cd->test);

	if(copy_to_user(buf, &(MINOR(cd->cdev.dev)), size)){
		return -EFAULT;
	}

	return size;
}
int dev_fifo_close (struct inode *inode, struct file *file)
{
	printk("dev_fifo_close()\n");
	return 0;
}
static int dev_fifo_open (struct inode *inode, struct file *file)
{
	struct mydev *cd;

	cd = pmydev[MINOR(inode->i_rdev)];
	
	file->private_data = cd;
	return 0;
}
static struct file_operations dev_fifo_ops = 
{
	.open = dev_fifo_open,
	.read = dev_fifo_read,
	.release = dev_fifo_close,
};
static int dev_init(void)
{
	int result;
	int error;
	int i = 0;

	register_chrdev(major, "hello", &dev_fifo_ops);

	hello_class = class_create(THIS_MODULE, "hello_class");
	
	for(i=0;i<MAX_COM_NUM;i++){
		pmydev[i] = kmalloc(sizeof(struct mydev), GFP_KERNEL);
	}

	for(i=0;i<MAX_COM_NUM;i++){		
		pmydev[i]->cdev.dev = MKDEV(major,i);
		err = device_create(hello_class, NULL, MKDEV(major,i), NULL, "%s%d",name,i);
	}
		return 0;
}

static void __exit hello_exit(void)
{
	int i;

	printk("dev_fifo_exit \n");

	for(i=0;i<MAX_COM_NUM;i++)
	{
		cdev_del(&pmydev[i]->cdev);
		kfree(pmydev[i]);
		device_destroy(hello_class, MKDEV(major, i));
	}

	class_destroy(hello_class);
	
	unregister_chrdev(major, "hello");
	
	return ;
}

module_init(dev_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

1、内存分配

pmydev[i] = kmalloc(sizeof(struct mydev), GFP_KERNEL);

kmalloc返回是无类型指针;pmydev[i]是struct mydev的指针;


2、设备号分配和储存

...
register_chrdev(major, "hello", &dev_fifo_ops);
hello_class = class_create(THIS_MODULE, "hello_class");
....
	
for(i=0;i<MAX_COM_NUM;i++){		
		pmydev[i]->test = i; 	
		pmydev[i]->cdev.dev = MKDEV(major,i);
		err = device_create(hello_class, NULL, MKDEV(major,i), NULL, "%s%d",name,i);
	}

利用cdev结构体中dev_t dev来储存主次设备号;
register_chrdev和hello_class已经在sys下创建了对应目录了;
device_create 第三个参数是需要使用次设备号的,这点和cdev_add不一样 (cdev_add(&cdev,devno,2);只在意主设备号,第三个参数来设定次设备号);设备创建完之后由udev在/dev下创建设备节点。


3、open的实现

static int dev_fifo_open (struct inode *inode, struct file *file)
{
	struct mydev *cd;

	cd = pmydev[MINOR(inode->i_rdev)];
	
	file->private_data = cd;
	return 0;
}

利用file中的void类型成员private_data存储信息,将内核中的结构体mydev以指针形式赋值给private_data。所以只要愿意,就可以在mydev填充任何信息。


4、read的实现

ssize_t dev_fifo_read (struct file *file, char __user *buf, size_t size, loff_t *pos)
{
	struct mydev *cd;

	cd = (struct mydev *)file->private_data;
	printk("read()       file->private_data         cd->test=%d\n",cd->test);

	if(copy_to_user(buf, &(MINOR(cd->cdev.dev)), size)){
		return -EFAULT;
	}

	return 



;
}

cd = (struct mydev *)file->private_data;将private_data类型转化回去,准备读取pmydev[i]的数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值