misc device driver

misc device driver

MISC means mixed and miscellaneous, so MISC driver is also called miscellaneous driver, that is, when some peripherals on our board cannot be classified, MISC driver can be used. MISC driver is actually the simplest character device driver, which is usually embedded in the platform bus driver to realize the complex driver. In this chapter, we will learn how to write MISC driver.

1, Introduction to MISC device driver

All MISC device drivers have a master device number of 10, and different devices use different slave device numbers. With the increase of linux character device driver, the device number becomes more and more tense, especially the main device number. MISC device driver is used to solve this problem. MISC device will automatically create cdev, which does not need to be created manually as we used to, so adopting MISC device driver can simplify the writing of character device driver. We need to register a miscdevice device with Linux. Miscdevice is a structure, which is defined in the file include/linux/miscdevice.h, as follows:

struct miscdevice
{
	int minor; /* Subdevice number */
	const char *name; /* Device name */
	const struct file_operations *fops;/* Device operation function set */
	struct list_head list; 
	struct device *parent;
    struct device *this_device;
    const struct attribute_group **groups;
    const char *nodename;
    umode_t mode;
};

After defining a MISC device (miscdevice type), we need to set the three member variables minor, name and fops. Minor indicates the sub device number. The main device number of MISC device is 10, which is fixed. You need to specify the sub device number. Name is the name of MISC device. When the device is registered successfully, a device file named name will be generated in the / dev directory. fops is the operation set of character device, and MISC device driver needs to use the fops operation set provided by users. After setting miscdevice, you need to register a MISC device with the system by using MISC register function. The prototype of this function is as follows:

int misc_register(struct miscdevice * misc)

The function parameters and return values are as follows:
MISC: MISC device to register.
Return value: negative, failed; 0, success.

In the past, we need to call a bunch of functions to create devices. For example, in the previous character device driver, we will use the following functions to complete the device creation process:
Example code, traditional device creation process:

alloc_chrdev_region(); /* Application equipment No */
cdev_init(); /* Initialize cdev */
cdev_add(); /* Add cdev */
class_create(); /* Create class */
device_create(); /* Create device */

Now we can use the MISC register function directly to complete these steps in the sample code. When we uninstall the device driver module, we need to call the MISC? Deregister function to log out the MISC device. The function prototype is as follows:

int misc_deregister(struct miscdevice *misc)

The function parameters and return values are as follows:
MISC: MISC device to unregister.
Return value: negative, failed; 0, success.

When we unregister the device driver, we need to call a bunch of functions to delete the cdev, device and so on
Capacity, as follows:
Example code, the traditional process of deleting a device

cdev_del(); /* Delete cdev */
unregister_chrdev_region(); /* Cancel device number */
device_destroy(); /* Delete device */
class_destroy(); /* Delete class */

Now we just need a MISC Φ deregister function to do the work in the sample code. The MISC device driver is explained here.

2, misc driver example

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ide.h>
#include <linux/device.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/miscdevice.h>

#define MISC_DEVICE_NAME "misc_test"
#define MISC_DEVICE_MINOR 144

static int misc_open(struct inode *inode, struct file *filep)
{
	return 0;
}

static ssize_t misc_read(struct file *filp, char __user *buff, size_t cnt, loff_t *offt)
{
	return 0;
}

static ssize_t misc_write(struct file *filp, char __user *buff, size_t cnt, loff_t *offt)
{
	return 0;
}

static int misc_release(struct inode *inode, struct file *filep)
{
	return 0;
}

/* Operation function structure */
static struct file_operations misc_fops = {
	.owner = THIS_MODULE,
	.open = misc_open,
	.read = misc_read,
	.write = misc_write,
	.release = misc_release,
};

/* misc Equipment structure */
static struct miscdevice miscdevice_test = {
	.minor = MISC_DEVICE_MINOR,
	.name = MISC_DEVICE_NAME,
	.fops = &misc_fops,
};

static __init int misc_init(void)
{
	int ret = misc_register(&miscdevice_test);
	if (ret < 0)
		return -EFAULT;
	return 0;
}

static __exit void misc_exit(void)
{
	misc_deregister(&miscdevice_test);
}

module_init(misc_init);
module_exit(misc_exit);

MODULE_AUTHOR("eurphan<eurphan@163.com>");
MODULE_DESCRIPTION("Misc Driver");
MODULE_LICENSE("GPL");
Published 27 original articles, won praise 8, visited 6877
Private letter follow

Tags: Linux

Posted on Tue, 11 Feb 2020 08:12:18 -0500 by Natty_Dreadlock