另一种字符设备驱动程序

前一种字符设备驱动程序

之前通过register_chrdev(0, “hello”, &hello_fops)注册字符驱动程序,一个主设备号下的所有设备(major,0)—(major,255)都对应hello_fops。

另一种字符设备驱动程序
实现函数:
//自动分配主设备号,只有(major,0)和(major,1)对应hello_fops
alloc_chrdev_region(&devid, 0, 2, “hello”);
major=MAJOR(devid);
dev_init(&hello_cdev,&hello_fops);
cdev_add(hello_cdev,devid,HELLO_CNT);
device_create(cls, NULL, MKDEV(major, 0), NULL, “hello0”); / /dev/hello0
device_create(cls, NULL, MKDEV(major, 1), NULL, “hello1”); /*/dev/hello1

程序源码

 
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h>
#include <linux/cdev.h>

static struct class *cls;
static struct cdev hello_cdev;
static struct cdev hello2_cdev;

static int major;
#define HELLO_CNT 2//两个次设备号

/*构造hello_open*/
static ssize_t hello_open (struct inode * inode, struct file * file)
{
	printk("hello_open");
		return 0;
}

static struct file_operations hello_fops={
	.owner = THIS_MODULE,
	.open = hello_open,
};

/*构造hello2_open*/
static int hello2_open(struct inode *inode, struct file *file)
{
	printk("hello2_open\n");
	return 0;
}
static struct file_operations hello2_fops = {
	.owner = THIS_MODULE,
	.open  = hello2_open,
};


static int hello_init(void)
{	
	dev_t devid;
	/*(major,0)-(major,255)都对应hello_fops
		major=register_chrdev(0, "hello", &hello_fops);
	*/
	if(major){//手动分配主设备号
		devid=MKDEV(major,0);
		/*从0开始2个;(major,0)-(major,1)对应hello_fops*/
		register_chrdev_region(devid, HELLO_CNT, "hello");
	}
	else{//自动分配主设备号
		/*(major,0)-(major,1)对应hello_fops*/
		alloc_chrdev_region(&devid, 0, HELLO_CNT, "hello");
		major=MAJOR(devid);
	}
	
	cdev_init(&hello_cdev,&hello_fops);
	cdev_add(hello_cdev,devid,HELLO_CNT);
	
	/*(major,2)对应hello2_fops*/
	devid = MKDEV(major, 2);
	register_chrdev_region(devid, 1, "hello2");
	cdev_init(&hello2_cdev, &hello2_fops);
	cdev_add(&hello2_cdev, devid, 1);

	cls = class_create(THIS_MODULE, "hello");
	device_create(cls, NULL, MKDEV(major, 0), NULL, "hello0"); /* /dev/hello0 */
	device_create(cls, NULL, MKDEV(major, 1), NULL, "hello1"); /* /dev/hello1 */
	device_create(cls, NULL, MKDEV(major, 2), NULL, "hello2"); /* /dev/hello2 */
	device_create(cls, NULL, MKDEV(major, 3), NULL, "hello3"); /* /dev/hello3 打不开*/

	return 0;
}

static void hello_exit(void)
{  
	device_destroy(cls, MKDEV(major, 0));
	device_destroy(cls, MKDEV(major, 1));
	device_destroy(cls, MKDEV(major, 2));
	device_destroy(cls, MKDEV(major, 3));
	class_destroy(cls);

	cdev_del(&hello_cdev);
	unregister_chrdev_region(MKDEV(major, 0), HELLO_CNT);

	cdev_del(&hello2_cdev);
	unregister_chrdev_region(MKDEV(major, 2), 1);
}

module_init(hello_init);//入口函数
module_exit(hello_exit);//出口函数
MODULE_LICENSE("GPL");

猜你喜欢

转载自blog.csdn.net/weixin_43542305/article/details/86382711