The code is as follows
#include <linux/init.h>#include<linux/module.h>#include<linux/kernel.h>#include<linux/cdev.h>#include<linux/fs.h>#include<linux/device.h>intDemo_major = -;intDemo_minor =0;intDemo_count =1;structCdev Cdev;Static struct class*Demo_class;Static structDevice *Demo_device;intDemo_open (structInode *INODEP,structFile * Filep)//turn on the device{PRINTK ("%s,%d\n", __func__, __line__); return 0;}intDemo_release (structInode * INODEP,structFile * Filep)//turn off the device{PRINTK ("%s,%d\n", __func__, __line__); return 0;}structFile_operations FoPs ={. Owner=this_module,. Open=Demo_open,. Release=Demo_release,};Static int__init Demo_init (void){ intRET =0; dev_t Devno; PRINTK ("%s,%d\n", __func__, __line__); //Use the following macros to generate dev_t with the main device number and the secondary device numberDevno =MKDEV (Demo_major, Demo_minor); PRINTK ("devno:%d\n", Devno); PRINTK ("demo_major:%d\n", Demo_major); /** before calling the Cdev_add () function to register a character device with the system, you should first call the Register_chrdev_region () or alloc_chrdev_region () function to request a device number from the system **/ if(demo_major) {
Using Cat/proc/devices | grep demo to query ret= Register_chrdev_region (Devno,1,"Demo"); } Else{ret= Alloc_chrdev_region (&devno, Demo_minor,1,"Demo"); } if(ret) {PRINTK ("Failed to register_chrdev_region.\n"); returnret; } //The cdev_init () function initializes the members of the Cdev and establishes a connection between Cdev and File_operationsCdev_init (&cdev, &fops); Cdev.owner=This_module; //the system adds a cdev to complete the registration of the character device. ret = Cdev_add (&Cdev, Devno, Demo_count); if(ret) {PRINTK (Kern_notice"Failed to Cdev_add [Error]%d adding demo%d", ret, demo_minor); GotoFailure_cdev_add; } /*automatically create device node files*/ //1. Register the device Class/sys/class/demo folder
Using LS /sys/class/demo Demo_class = Class_create (This_module,"Demo"); if(Is_err (Demo_class)) {PRINTK ("class_create failed!\n"); RET= Ptr_err ("Demo_class"); Gotofailure_class_create; } //2. Registering the device/sys/class/demo/demo0/dev/demo0Demo_device = device_create (Demo_class, NULL, MKDEV (Demo_major, Demo_minor), NULL,"demo%d", Demo_minor); if(Is_err (Demo_device)) {PRINTK ("device_create failed!\n"); RET=Ptr_err ("Demo_device"); Gotofailure_device_create; } return 0; Failure_device_create:class_destroy (Demo_class); Failure_class_create:cdev_del (&Cdev); Failure_cdev_add:unregister_chrdev_region (Devno, Demo_count); Failure_register_chrdev:returnret;}Static void__exit Demo_exit (void) {PRINTK ("%s,%d\n", __func__, __line__); /*reverse Order Elimination*/ //remove a device from the kernelDevice_destroy (Demo_class,mkdev (Demo_major, Demo_minor)); //removing the device class from the kernelClass_destroy (Demo_class); //Delete a cdev to complete the logoff of the character device. Cdev_del (&Cdev); //after calling the Cdev_del () function to unregister the character device from the system, unregister_chrdev_region () should be called to release the previously requested device number.unregister_chrdev_region (MKDEV (Demo_major, Demo_minor), demo_count);} Module_init (Demo_init); Module_exit (Demo_exit); Module_author ("libra13179"); Module_license ("GPL v2");
Kvers = $ (Shell uname-R) # Kernel Modulesobj-M + = for the module compilation. #EXTRA_CFLAGS =-g-o0build:kernel_moduleskernel_modules: -c/lib/modules/$ (kvers)/build m=$ (CURDIR) modules# @echo $ (kvers) Clean: -c/lib/modules/$ (kvers)/build m=$ (CURDIR) Clean
View Code
#include <sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<stdio.h>intMainintargcConst Char*argv[]) { intFD; intval =1; FD= Open ("/dev/demo0", O_RDWR); if(FD <0) {printf ("can ' t open!\n"); return-1; } Else{printf ("Open success.\n"); } getchar (); Close (FD); return 0;}
View Code
Linux Driver Development (iii) character device driver framework (Automatic device node creation)