Linux字符驱动之主设备号与次设备号

 // drv_demo.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

dev_t dev;
struct cdev  virdev;
static struct class *dev_class;

int openc(struct inode *inode,struct file *filep)
{
    printk ("in openc\n");
    return 0;
}

int releasec(struct inode *inode,struct file *filep)
{
    printk ("in releasec\n");
    return 0;
}

ssize_t writec (struct file *filep, const char __user *buf, size_t count,loff_t *offp)
{
    printk ("in writec\n");
    return 0;
}

ssize_t readc(struct file *filep, char __user *buf, size_t count, loff_t *offp)
{
    printk ("in readc\n");
    return 0;
}

int mymemmap(struct file* filep, struct vm_area_struct *vma)
{
    printk ("in mymemmap\n");
    return 0;
}

struct file_operations dev_fops={
    .owner =  THIS_MODULE,
    .open  =  openc,
    .read  =  readc,
    .write =  writec,
    .mmap  =  mymemmap,
    .release = releasec
};

static int __init dev_init(void)
{
    int status;
    int num = 0;
    struct device *rdev = NULL;

    status = alloc_chrdev_region(&dev, 0, 4, "dev_test");
    if( status ) {
            printk ("alloc chrdev region failed\n");
            return status;
    }

    cdev_init(&virdev, &dev_fops);
    virdev.owner = THIS_MODULE;
    cdev_add(&virdev, dev, 4);

    dev_class = class_create(THIS_MODULE, "dev_test");
    if (IS_ERR(dev_class)) {
        unregister_chrdev_region (dev, 4);
        return PTR_ERR(dev_class);
    }

    for (num = 0; num < 4; ++num) {
        rdev = device_create (dev_class, NULL, MKDEV (MAJOR(dev), num), NULL, "dev_test%d", num);
        status = PTR_RET(rdev);
        if (!!status) {
            printk  ("Error: device_create %d \n", num);
        }
    }

    printk ("in init\n");
    return 0;
}

static void __exit dev_exit(void)
{
    int num = 0;

    printk ("in exit\n");

    for (num = 0; num < 4; ++num) {
        device_destroy (dev_class, MKDEV (MAJOR(dev), num));
    }

    class_destroy (dev_class);

    cdev_del (&virdev);

    unregister_chrdev_region (dev, 4);

    printk ("end exit\n");
    return ;
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("Dual BSD/GPL");

// Makefile

ifneq ($(KERNELRELEASE),)
	obj-m := drv_demo.o
else
	KERNELDIR ?= /lib/modules/$(shell uname -r)/build
	PWD := $(shell pwd)
default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD)  modules
endif
clean:  
	rm -rf *.mod.* *.o *.ko *.cmd *.symvers *.order 

 

你可能感兴趣的:(嵌入式,Linux,driver,char,次设备号,主设备号)