Linux Device Driven Misc driver Framework Source analysis (II.)

Source: Internet
Author: User
Tags mutex semaphore

1. Misc_open function Analysis

In DRIVER/CHAR/MISC.C, the MISC.C is implemented by the driver framework, which is an interface for the Misc driver framework to open a misc device for the application layer.


1, first we need to know in misc.c in the Misc_init function, misc This kind of device is registered as a character device driver. The code is as follows

static int __init misc_init (void) {int err; #ifdef config_proc_fsproc_create ("misc", 0, NULL, &misc_proc_fops); Endifmisc_class = Class_create (This_module, "misc"); err = Ptr_err (Misc_class); if (Is_err (misc_class)) Goto Fail_remove Err =-eio;if (Register_chrdev (misc_major, "MISC", &misc_fops)) the device of the//misc class is registered as a character device driver, because the Register_chrdev function is used. Goto Fail_printk;misc_class->devnode = Misc_devnode;return 0;FAIL_PRINTK:PRINTK ("Unable to get major%d for misc Devic Es\n ", misc_major); Class_destroy (Misc_class); Fail_remove:remove_proc_entry (" MISC ", NULL); return err;}

As can be seen in the Register_chrdev function parameter in the above code, the Misc_fops is a method structure containing the operation of the driver. The contents of the structure are as follows

static const struct File_operations misc_fops = {. owner= this_module,.open= Misc_open,};

It is therefore known that the Misc_open function in the drive frame is the interface provided by the driver framework for the application layer, and the interface function is the Open function. Normally, the driver framework is not write-driven operation method, it should be left to us to drive the development of the people to write. Write the method in the File_operations structure itself to populate it and register it.


2, Misc_open function code analysis, code and analysis are as follows

Static int misc_open (struct inode * inode, struct file * file) { Int minor = iminor (inode);     //gets the device's secondary device number from the passed in parameter, the Inode is the node of the file in Flash, File is the path of the device file that opens the share struct miscdevice *c;    int err = -enodev; const struct file_operations *old_fops, *new_fops = null; //definition of two File_ Opreation structure, this structure is needless to say, put the interface function, drive                                                                //operation Method Mutex_lock (&MISC_MTX); list_ For_each_entry (c, &misc_list, list)  {    //traverses the list of kernel misc spurious devices, If there is a secondary device number for this device in the list, then the if  in the kernel list (C->minor == minor)  {                 //this device number corresponding to the device's FoPs method to take out, as a new way to operate this device. New_fops = fops_get (c->fops); break;}} if  (!new_fops)  {    //If there is no fops for this secondary device number in the kernel Misc link list, then request_module once, go find it once, If it is not found, then Mutex_unlock (&MISC_MTX);                                      //jumps to the fail position. When registering this device, we will register the device fops                                                                //'s.                                                                //Application layer with open operation of this device, corresponding to the drive layer, is to find the secondary device                    //number, because the registration of this driver, FoPs has been provided, at the same time, the device is also registered, so go to the kernel list to find this secondary device number,                   // Find the second device number and then go to find FoPs method, found after the fops structure, normal is sure to find. Because the driver registration is you provide                    //fops, when the device creates the registration, it also registers the corresponding minor device number. Request_module ("char-major-%d-%d",  misc_major, minor); Mutex_lock (&MISC_MTX); List_for_each_entry ( C, &misc_list, list)  {if (c->minor == minor)  {new_fops = fops_get (c->fops); if  (!new_fops) Goto fail;} err = 0;old_fops = file->f_op;    //will open the FOP of the file as the old Fopfile->f_op  = new_fops;    //will be opened from the Misc kernel list FoPs as the new OPS. if  (File->f_op->open)  {    //If a function method instance of open is obtained file->private_data =  c;err=file->f_op->open (inode,file);     //then calls the Open function, which is the true execution of open. When the upper layer uses open to operate the Misc device, the final execution is this letter                                  The       //number, which is bound to the open under FoPs in the Miscdevice structure, is provided by the writer driver, in x210-buzzer.c                              &nbspopenif  (Err)  {fops_put (FILE->F_OP) in the fops provided by         //; File->f_op = fops_get (Old_fops);}} Fops_put (Old_fops); Fail:mutex_unlock (&misc_mtx); return err;}

So when the application layer uses open to operate the misc device, it maps to the Misc_open function in the driver's/driver/char/misc.c file to execute the File->f_op->open function, which maps the

/drvier/char/buzzer/x210-buzzer.c in the

static struct File_operations Dev_fops = {. Owner = This_module,. Open = X210_pwm_open,. Release = X21 0_pwm_close,. IOCTL = X210_pwm_ioctl,};

The function body of the open bound X210_pwm_open,x210_pwm_open is

static int X210_pwm_open (struct inode *inode, struct file *file) {if (!down_trylock (&lock)) return 0;elsereturn-ebusy ;}

2, misc in proc in the display proc is not very important, because the proc file system is now used more and more less, because too messy, here is mainly to let you know what this code is doing

Cat/proc/misc file, you will see all the devices registered to the MISC device number and name, the contents of this file by traversing the kernel misc_list linked list to display.

The creation of this/proc/misc file is created in the proc_create of the Misc_init function in the/drvier/char/misc.c file, as shown in the following code

static int __init misc_init (void) {int err; #ifdef config_proc_fsproc_create ("misc", 0, NULL, &misc_proc_fops);//                                                Create the Misc file under the proc directory. The MISC_PROC_FOPS structure is the way to manipulate this/proc/misc file. #endif

The contents of the MISC_PROC_FOPS structure are

static const struct File_operations misc_proc_fops = {. Owner = This_module,.open = Misc_seq_open,.read = Seq_read,.l Lseek = Seq_lseek,.release = Seq_release,};

The corresponding method for Cat/proc/misc files should be

static const struct Seq_operations misc_seq_ops = {. Start = Misc_seq_start,.next = Misc_seq_next,.stop = Misc_seq_stop,. Show = Misc_seq_show,};

In the Misc_seq_show method, the contents are as follows

static int misc_seq_show (struct seq_file *seq, void *v) {const struct Miscdevice *p = list_entry (V, struct miscdevice, list ); seq_printf (seq, "%3i%s\n", P->minor, P->name p->name: ""); return 0;}



3, the kernel mutual exclusion lock

(1) What is a mutual exclusion lock?

And the mutex in the application is actually the same. I can not access when others visit, access when others visit, need to lock and unlock, not to say more,

(2) Mutual exclusion lock defined in kernel: Define_mutex

(3) Lock: Mutex_lock and Unlock: Mutex_unlock

(4) The means of the kernel to prevent competitive state: Atomic access, spin lock, mutex, semaphore

(5) Atomic access is mainly used to count (access process can not be interrupted), spin Lock said, mutual exclusion lock and semaphore is very similar (in fact, the count value is 1 of the semaphore), the occurrence of mutexes than the signal volume of the late, to achieve better than the signal volume, try to use mutexes.


Atomic operation:

For example, you define a variable count, and then count++, in fact, this count++ can be interrupted, because count++ is converted to a possible three lines of code, when the execution of two sentences suddenly interrupted (possibly time-chip time), was interrupted to change the value of this count, So this time the value of this count++ is definitely wrong, so in order to prevent this phenomenon there is atomic operation, the count of atomic operations can not be interrupted.


Spin locks: Spin locks are fundamentally different from atomic operations and are used more and more in the current drive. is invented in the age of multicore CPUs, specifically dealing with this multiprocessor CPU, so the spin lock will be used more and more, will be detailed later.


Signal Volume: and mutual exclusion lock basically similar, semaphore used to count, for example, a device can only be opened 7 times, each open this device will remember the number of times, when the eighth opened, the number is greater than 7, you can not open this device. This is a means of using semaphores to do an open count.


Mutex: A mutex is a special signal that can only be opened once. A person opens, the value may be 1, another person can not open, when the person unlocked, this value is 0, another person can open or access. So the difference between the mutex and the semaphore is the number of times. When you can use a mutex lock, do not signal the amount of the mutex. Tiger on the line. If the driver is your own writing, you have to choose to use mutual exclusion lock and semaphore, this time you will not be entangled, because you have not to follow other people's Drive writing drive skills, you already know when to use mutual exclusion lock when using the semaphore.


MISC.C This kernel person writes, writes the driver frame person to write the code has already analyzed almost, this part of the code as long as understands the line, not the driver engineer needs to write, we want to write is the driver, but is not to drive the framework code.

The driver code of the buzzer behind the analysis, this part of the code is the driver engineers need to write.

This article from "Whylinux" blog, declined reprint!

Linux Device Driven Misc driver Framework Source analysis (II.)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.