Embedded-Linux-Device-Driver/C3/Kernel-Synchronization/English

From Script | Spoken-Tutorial
Revision as of 01:17, 9 January 2021 by Nancyvarkey (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
Visual cue : Narration :
Slide 1:

Welcome slide:

Welcome to the spoken tutorial on Kernel synchronization.
Slide 2 :

Learning objectives:

In this tutorial, we will learn about
  • Synchronization techniques provided by Linux kernel.
  • Binary semaphore technique and
  • How to control the shared resource from concurrent access
Slide 3 :

System Requirements:

To record this tutorial, I am using,
  • VirtualBox 5.2.
  • Ubuntu Linux 18.04 LTS Operating System.
  • Linux kernel version 5.0.0-31 generic.
  • gedit text editor.
Slide 4 :

Prerequisites:

To follow this tutorial, you should be familiar with:

* C programming language and

  • Basics of Linux kernel

If not, then go through the C/C++ and Linux spoken tutorials on this website.

Slide 5:

Synchronization mechanism

Synchronization mechanism:
  • It is a mechanism used to protect the shared resources from concurrent access.
  • The kernel provides synchronization mechanisms for system and kernel programming
We will see the different types of kernel synchronization techniques.
Slide 6:

Types of Synchronization

Atomic Operations - It occur individually with no other operations occurring concurrently

Spinlock - These are used in code that is not permitted to sleep.

Semaphore - This can be used to lock threads.

Such threads sleep until they are activated again

Mutex - It is the same as binary semaphore

It prevents simultaneous activation of multiple threads

In this tutorial, we will see how to use binary semaphore.
Slide 7 :

Binary Semaphore:

For example, the user program uwrite.c writes the data to the buffer.

At the same time, another process uread.c tries to read the data from the same buffer.

The semaphore will block the uread.c till the write operation is completed.

Point to the folder and file in desktop

Point to the files.

Go to the DeviceDriver folder in the Desktop which we have created earlier.

In this directory, I have created a directory named Synchronization.

Here, I have saved my_driver dot c driver file and Makefile.

uread dot c and uwrite dot c are the user program files.

I’ll use these files for demonstration.

Slide :

Code files:

  • The files used in this tutorial are available in the Code Files link on this tutorial page.
  • Please download and extract them
  • Make a copy and then use them while practising
Open the termin

Type >> cd Desktop/DeviceDriver/ Synchronization

Open the terminal by pressing ALT+Ctrl+T keys simultaneously.

Go to the directory where Synchronization is saved on your system.

Press Enter key after every command.

Let us open my_driver dot c driver file

Type >> gedit my_driver.c

Shown opened file

Type gedit space my_driver dot c.

In this file, I have defined the open, read, write and close functions for new_device.

Highlight #include<linux/semaphore.h> Highlight delay.h

We have to include the semaphore.h header file.

The semaphore related kernel functions are declared in this file.

delay dot h file is included in which the kernel delay functions are defined.

Highlight static struct semaphore lock

Highlight lock

The struct semaphore is a structure that represents semaphores.

We will use a semaphore lock to avoid the concurrent access.

Highlight sema_init(struct semaphore *, int)

Highlight struct semaphore *

Highlight int

In the initialization function of the driver, the function sema_init is declared.

This function is used to initialize the semaphore.

The first parameter is a semaphore structure pointer.

int is the initial value assigned to the semaphore for the number of resources.

Highlight sema_init(lock, 0)

Highlight 0

Lock is the semaphore structure pointer and zero is the initial value of the semaphore.
Let us see the important semaphore related functions provided by the kernel.

down_interruptible(struct semaphore *)

The function down_interruptible() in the read function attempts to acquire the given semaphore.

It acquires the given semaphore with interruptible sleep.

The initial value of semaphore is zero. So down_interruptible function will decrement it.

The value becomes less than zero.

So the user program which will try to read data will get blocked.

up(struct semaphore *)

up(&lock)

The up() function is used in the write function.

It releases the semaphore and wakes a waiting task, if any.

This will release the semaphore after completing the write operation on the resource.

Here, the semaphore structure pointer is passed as a parameter.

Now another user can acquire the semaphore and get access to the shared resource.

Using semaphore, only one process can get the access of a shared resource at a time.

Highlight ssleep(10).

ssleep() function is used, so that the write function sleeps for some time.

Practically drivers should not go into sleep mode.

You should not use ssleep() function in a driver.

For demonstration purposes, I have used ssleep() to show the output.

Save and close the file.

Type >> gedit uread.c

Highlight open, read and close

Save and close the file.

Let us now open the user program uread dot c.

Type gedit space uread dot c.

This program opens the new_device file, reads data and closes the device file.

Now, save and close the program.

Type >> gedit uwrite.c

Highlight open, write and close

Next let us now open the user program uwrite dot c.

Type gedit space uwrite dot c.

This program opens the new_device file, writes data and closes the device file.

Save and close the file.

Clear the screen.

Now, save and close the file.

Clear the screen.

Type gedit space Makefile

Let us create a Makefile to compile the driver.

Type gedit space Makefile

Type the code as shown here or you can use downloaded Makefile.

Save and close the file. Clear the screen.

Type >> sudo su.

Type >> system password

To be a superuser, type sudo space su.

Now type the system password.

Type >> make all

Type >> clear

Type >> insmod my_driver.ko

Type >> clear

Let us compile the driver.

Type make space all. Clear the screen.

Now let’s load the driver into the kernel.

Type insmod space my_driver dot ko.

Clear the screen.

Type >> dmesg | grep my_driver

Highlight the output

Type >> clear

Let us see the loaded printk messages.

Type dmesg command as shown here.

The output shows that the semaphore is initialized successfully.

Clear the screen.

Type gcc -c uread.c uwrite.c

Type gcc -o uread uread.o

Type gcc -o uwrite uwrite.o

Now let us compile the two user programs.

Type gcc hyphen c uread dot c space uwrite dot c.

Type gcc hyphen o uread space uread.o

Type gcc hyphen o uwrite uwrite.o

Clear the screen.


Now let us execute the uwrite and uread user program in two terminals.

Let us name this terminal as A.

Type sudo su and system password

Type >> ./uwrite

Open another terminal by pressing Ctrl+ALT+T keys simultaneously.

Let us name this terminal as B.

Go to the synchronization folder where you have saved the files.

Now, type sudo su and password.

Switch back to terminal A.

Type dot slash uwrite in terminal A.

Type >> ./uread Switch back to terminal B.

Type dot slash uread.

Press the Enter key in both the terminals to execute the program.

Highlight respective outputs Close the terminal B

After waiting for some time, we can see the output on both terminals.

See the output in terminal A.

The output shows that the Linux Device Driver string writes to the device successfully.

Check the output in terminal B.

It shows that the same string is read from the device successfully.

Close the terminal B.

Type >> clear Clear the screen.
Type >> dmesg | grep my_driver

Highlight the output

Highlight printk messages

Type dmesg command as shown.

The output message shows that the semaphore is acquired by the user uread.c.

The user program uread.c is blocked by the unavailable semaphore.

The user program uwrite.c writes data in a buffer and then releases semaphore.

Highlight the printk messages.

Type >> clear

As soon as the semaphore releases, the uread.c acquires it.

The output message shows that the uread.c program reads the data from the buffer.

It indicates that at a time only one process is available to access the shared buffer.

Clear the screen.

Type rmmod my_driver.ko

Now let's unload the driver.

Type rmmod space my_driver dot ko.

With this, we come to the end of this tutorial. Let us summarise.
Slide :

Summary:

In this tutorial, we learnt
  • Synchronization techniques provided by the Linux kernel.
  • Binary semaphore technique and
  • How to control the shared resources from concurrent access
Slide :

Assignment :

As an assignment:
  1. Change the Data in the uwrite.c
  2. Compile, load the driver and execute the user programs.
  3. See the output using dmesg command.
  4. Unload the driver from the kernel.
Slide :

About Spoken Tutorial Project:

  • The video at the following link summarizes the Spoken Tutorial project.
  • Please download and watch it.
Slide :

Spoken Tutorial workshops :

The Spoken Tutorial Project Team conducts workshops and gives certificates.

For more details, please write to us.

Slide :

Forum questions :

Please post your timed queries in this forum.
Slide :

Forum for specific questions :

  • Do you have any general or technical questions on Embedded Linux Device Driver?
  • Please visit the FOSSEE forum and post your question.
Slide :

Acknowledgment:

The Spoken Tutorial Project is funded by MHRD, Government of India.
Slide :

Thank you slide:

This tutorial has been contributed by FOSSEE and Spoken Tutorial Project, IIT Bombay.

This is Usha signing off.Thanks for watching.

Contributors and Content Editors

Nancyvarkey, Nirmala Venkat