Misc means mixed and miscellaneous, so misc driver is also called miscellaneous driver, that is, misc driver can be used when some peripherals on our board cannot be classified. Misc driver is actually the simplest character device driver. It is usually nested in platform bus driver to realize complex driver. In this chapter, we will learn the writing of misc driver.
Introduction to MISC device driver
The master device number of all MISC device drivers is 10, and different devices use different slave device numbers. With the continuous increase of linux character device driver, the device number becomes more and more nervous, 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 before. Therefore, using MISC device driver can simplify the writing of character device driver. We need to register a miscdevice device with Linux, miscdevice
Is a structure defined in the file include/linux/miscdevice.h, as follows:
57 struct miscdevice { 58 int minor; /* Sub equipment No*/ 59 const char *name; /* Device name*/ 60 const struct file_operations *fops; /* Device operation set*/ 61 struct list_head list; 62 struct device *parent; 63 struct device *this_device; 64 const struct attribute_group **groups; 65 const char *nodename; 66 umode_t mode; 67 };
After defining a MISC device (miscdevice type), we need to set three member variables: minor, name and fops. Minor indicates the sub equipment number. The main equipment number of MISC equipment is 10. This is fixed and needs to be specified by the user. The Linux system has predefined some sub equipment numbers of MISC equipment, which are defined in
In the include/linux/miscdevice.h file, as follows:
13 #define PSMOUSE_MINOR 1 14 #define MS_BUSMOUSE_MINOR 2 /* unused */ 15 #define ATIXL_BUSMOUSE_MINOR 3 /* unused */ 16 /*#define AMIGAMOUSE_MINOR 4 FIXME OBSOLETE */ 17 #define ATARIMOUSE_MINOR 5 /* unused */ 18 #define SUN_MOUSE_MINOR 6 /* unused */ ...... 52 #define MISC_DYNAMIC_MINOR 255
When using, we can select one of these predefined sub device numbers. Of course, we can also define it ourselves, as long as the sub device number is not used by other devices.
Name is the name of the MISC device. After 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. MISC device driver finally needs to use the fops operation set provided by the user.
After setting miscdevice, you need to use misc_register function registers a MISC device in the system. The prototype of this function is as follows:
int misc_register(struct miscdevice * misc)
Function parameters and return values have the following meanings:
MISC: MISC device to register.
Return value: negative number, failed; 0, successful.
Previously, we needed to call a bunch of functions to create devices. For example, in the previous character device driver, we used the following functions to complete the device creation process:
1 alloc_chrdev_region(); /* Application equipment No*/ 2 cdev_init(); /* Initialize cdev */ 3 cdev_add(); /* Add cdev */ 4 class_create(); /* Create class*/ 5 device_create(); /* Create device*/
Now we can use MISC directly_ Register a function to complete these steps in example code 57.1.3. When we uninstall the device driver module, we need to call misc_deregister function to log off the MISC device. The function prototype is as follows:
int misc_deregister(struct miscdevice *misc)
Function parameters and return values have the following meanings:
MISC: MISC device to log off.
Return value: negative number, failed; 0, successful.
Before logging off the device driver, we need to call a bunch of functions to delete the previously created cdev, device, etc., as shown below:
1 cdev_del(); /* Delete cdev */ 2 unregister_chrdev_region(); /* Logout equipment number*/ 3 device_destroy(); /* Delete device*/ 4 class_destroy(); /* Delete class*/
Now we just need a MISC_ The deregister function does this in sample code 57.1.4. That's all for MISC device driver. Next, we'll use platform and MISC driver framework to write beep buzzer driver.
Hardware schematic analysis
In this chapter, we only use BEEP buzzer on IMX6U-ALPHA development board. Therefore, refer to section 14.3 for the schematic diagram of experimental hardware.
Experimental programming
The routine path corresponding to this experiment is: development board CD - > 2, Linux driver routine - > 17_ misc.
In this chapter, we use platform plus misc to write beep driver, which is also a common method in actual Linux driver. Platform is used to realize bus, device and driver, and misc is mainly responsible for the creation of character device.
Modify device tree
In this chapter, we need to use the buzzer in the experiment, so we need to create the buzzer device node in the imx6ull-alientek-emmc.dts file. Here, we can directly use the beep device node created in section 46.3.1.
beep driver programming
Create a new folder named "19_miscbeep", and then_ Create a vscode project in the miscbeep folder, and the workspace is named "miscbeep". Create a new driver file named miscbeep.c, and enter the following contents in miscbeep.c:
1 #include <linux/types.h> 2 #include <linux/kernel.h> 3 #include <linux/delay.h> 4 #include <linux/ide.h> 5 #include <linux/init.h> 6 #include <linux/module.h> 7 #include <linux/errno.h> 8 #include <linux/gpio.h> 9 #include <linux/cdev.h> 10 #include <linux/device.h> 11 #include <linux/of.h> 12 #include <linux/of_address.h> 13 #include <linux/of_gpio.h> 14 #include <linux/platform_device.h> 15 #include <linux/miscdevice.h> 16 #include <asm/mach/map.h> 17 #include <asm/uaccess.h> 18 #include <asm/io.h> 19 /*************************************************************** 20 Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved. 21 File name: miscbeep.c 22 Author: Zuo Zhongkai 23 Version: V1.0 24 Description: using MISC buzzer driver. 25 Others: None 26 Forum: www.openedv.com 27 Log: first version v1.0 created by Zuo Zhongkai on August 20, 2019 28 ***************************************************************/ 29 #define MISCBEEP_NAME "miscbeep" / * name*/ 30 #define MISCBEEP_MINOR 144 / * sub equipment No*/ 31 #define BEEPOFF 0 / * turn off the buzzer*/ 32 #define BEEPON 1 / * turn on the buzzer*/ 33 34 /* miscbeep Equipment structure*/ 35 struct miscbeep_dev{ 36 dev_t devid; /* Equipment number*/ 37 struct cdev cdev; /* cdev */ 38 struct class *class; /* class*/ 39 struct device *device; /* equipment*/ 40 struct device_node *nd; /* Device node*/ 41 int beep_gpio; /* beep GPIO number used*/ 42 }; 43
Lines 29-94, standard character device driver.
Lines 97 to 101 set the MISC device beep_miscdev, line 98 set the sub device number to 144, and line 99 set the device name to "miscbeep", so that a device file named "miscbeep" will exist in the / dev / directory after the system is started. Line 100 sets the operating function set of the MISC device to file_operations.
Lines 109-145 are the probe function of the platform framework. This function will be executed after the driver matches the device. First, initialize the IO used by BEEP in this function. Finally, in line 138, register the MISC device with the Linux kernel through the misc_register function, that is, the beep_miscdev defined above.
Line 152~160, the remove function of the platform framework. In this function, the misc_deregister function is invoked to cancel the MISC device.
163 ~ 196, standard platform driver.
Write test APP
Create a new miscbeepApp.c file, and then enter the following contents in it:
1 #include "stdio.h" 2 #include "unistd.h" 3 #include "sys/types.h" 4 #include "sys/stat.h" 5 #include "fcntl.h" 6 #include "stdlib.h" 7 #include "string.h" 8 /*************************************************************** 9 Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved. 10 File name: miscbeepApp.c 11 Author: Zuo Zhongkai 12 Version: V1.0 13 Description: beep test APP under MISC driven framework. 14 Others: None 15 Usage:. / miscbeepApp /dev/miscbeep 0 turn off the buzzer 16 ./misdcbeepApp /dev/miscbeep 1 Turn on the buzzer 17 Forum: www.openedv.com 18 Log: first version v1.0 created by Zuo Zhongkai on August 20, 2019 19 ***************************************************************/ 20 #define BEEPOFF 0 21 #define BEEPON 1 22 23 /* 24 * @description : main main program 25 * @param - argc : argv Number of array elements 26 * @param - argv : Specific parameters 27 * @return : 0 Success; other failures 28 */ 29 int main(int argc, char *argv[]) 30 { 31 int fd, retvalue; 32 char *filename; 33 unsigned char databuf[1]; 34 35 if(argc != 3){ 36 printf("Error Usage!\r\n"); 37 return -1; 38 } 39
The miscbeepApp.c file is basically the same as the test APP of other routines. It is very simple and will not be explained here.
Run test
Compile driver and test APP
1. Compile driver
Write the Makefile file. The Makefile file of the experiment in this chapter is basically the same as the experiment in Chapter 40, except that the value of obj-m variable is changed to "miscbeep.o". The contents of the Makefile are as follows:
1 KERNELDIR := /home/zuozhongkai/linux/IMX6ULL/linux/temp/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek ...... 4 obj-m := miscbeep.o ...... 11 clean: 12 $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
In line 4, set the value of obj-m variable to "miscbeep.o".
Input the following command to compile the driver module file:
make -j32
After successful compilation, a driver module file named "miscbeep.ko" will be generated.
2. Compile test APP
Enter the following command to compile the test program miscbeepApp.c:
arm-linux-gnueabihf-gcc miscbeepApp.c -o miscbeepApp
After successful compilation, the application miscbeepApp will be generated.
Run test
Copy the two files miscbeep.ko and miscbeepApp compiled in the previous section to
In the rootfs/lib/modules/4.1.15 directory, restart the development board, enter the directory lib/modules/4.1.15, and enter the following command to load the driver module miscbeep.ko.
depmod //This command needs to be run when the driver is loaded for the first time modprobe miscbeep.ko //Load device module
After the driver module is loaded successfully, we can see a subdirectory named "miscbeep" in the directory / sys/class/misc, as shown in figure 57.4.2.1:
All misc devices belong to the same class. All misc devices in the / sys/class/misc directory correspond to a subdirectory.
After the driver matches the device successfully, the device driver file / dev/miscbeep will be generated. Enter the following command to view the primary and secondary device numbers of this file:
ls /dev/miscbeep -l
The results are shown in figure 57.4.2.2:
As can be seen from figure 57.4.2.2, / dev/miscbeep has a primary device number of 10 and a secondary device number of 144, which is consistent with the settings in our driver.
Open BEEP by entering the following command:
./miscbeepApp /dev/miscbeep 1 //Open BEEP
Turn off the LED after entering the following command:
./miscbeepApp /dev/miscbeep 0 //Close BEEP
Observe whether BEEP can be turned on and off. If yes, the driver works normally. If you want to unload the driver, enter the following command:
rmmod miscbeep.ko