Embedded-Linux-Device-Driver/C3/Interrupt-Handling/English

From Script | Spoken-Tutorial
Revision as of 14:57, 12 February 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 Interrupt Handling.
Slide 2:

Learning objectives:

In this tutorial, we will learn how to handle the software interrupt in the driver.
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 6 :

Interrupt handler

  • The function that runs in response to a specific interrupt is called an interrupt handler
  • Different devices can be associated with different interrupts.
  • A driver needs to handle the interrupts properly for its device.
Slide :

Working - Interrupt Handling.

  • In this tutorial, a user program will open and close the device file.
  • When the user program opens a device, the software interrupt will be triggered by the driver.
  • When the kernel receives an interrupt, the registered handler from the driver will be executed.
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 Interrupt.

Here, I have saved an interrupt dot c, Makefile and user dot c files.

I’ll use these files for demonstration.

Slide:5

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 terminal

Type >> cd Desktop/DeviceDriver/Interrupt

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

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

Press Enter key after every command.

Type >> gedit interrupt.c Type gedit space interrupt dot c.
Highlight header files

Highlight <linux/interrupt.h>

We have to include an interrupt dot h kernel header file to register an interrupt.

The purpose of each file is mentioned as shown here.

In this file, I have implemented only open and close file operations for a device.

Highlight IRQ_NUM

Highlight irqreturn_t irq_handler()

We have defined the IRQ line number as 2 which will be used in this driver.

The devices can send interrupts to the processor using these IRQ lines.

We have implemented an interrupt handler as shown here.

When the kernel receives the respective interrupt, it will execute this handler.

Highlight int_function()

Highlight request_irq()

In the initialization function, we have to register the interrupt handler.

Drivers can register an interrupt handler and enable a given interrupt line for handling.

The request_irq function is used to register an interrupt handler.

Highlight IRQ_NUM

Highlight irq_handler

The first parameter specifies the interrupt number to allocate.

This value is typically hard-coded in the kernel.

The second parameter is a function pointer to the actual interrupt handler.

This function is invoked whenever the kernel receives the interrupt.

Highlight flag The third parameter can be either zero or one or any of the flags defined in the interrupt dot h.

The fourth parameter is used to identify the device interrupt name.

The fifth parameter is used for shared interrupt lines.

This parameter is used to identify the handlers on the same interrupt line.

Slide - Important flags :

IRQF_DISABLED - Disables all interrupts when executing this interrupt handler.

IRQF_SAMPLE_RANDOM - Specifies that interrupts should contribute to the kernel entropy pool.

IRQF_TIMER - Used to mark this interrupt as timer interrupt

IRQF_SHARED - Allows sharing the irq among several devices

Let us see some important flags that can be used by request_irq function.
  • IRQF_DISABLED - It disables all interrupts when executing this interrupt handler.
  • IRQF_SAMPLE_RANDOM - It specifies that interrupts should contribute to the kernel entropy pool.
  • IRQF_TIMER - It is used to mark this interrupt as timer interrupt
  • IRQF_SHARED - It allows sharing the irq among several devices.
Switch back to the code.
Highlight request_irq()

Highlight printk

Request_irq function will register the irq_handler with the name my_interrupt.

my_interrupt is used by slash proc slash interrupts for communication with the user.

Here, we have used the IRQF_SHARED flag.

On success, request_irq function returns zero.

A nonzero value indicates an error.

Highlight open() function

Highlight asm("int $50")

In the open() function asm("int $50") instruction will trigger the interrupt.

We are not going to use any hardware interrupt as they can come from anywhere at any time.

Here, we are going to trigger a software interrupt using the int instruction.

Highlight #define IRQ0_VECTOR()

Highlight FIRST_EXTERNAL_VECTOR

Highlight 0x20 + 0x10 + 02 = 50

Highlight 02

Let us see how to calculate the interrupt line number.

In Linux IRQ to vector, mapping is done using FIRST_EXTERNAL_VECTOR macro.

To raise an interrupt IRQ 2, we have to add 2 to a vector of IRQ 0 as shown here.

Highlight asm("int $50") The asm instruction will be executed while opening the device file of our driver.

When this instruction executes, it will raise the interrupt IRQ 2.

Highlight free_irq(IRQ_NUM,(void *)irq_handler)

Highlight IRQ_NUM

When the driver unloads, we need to unregister the interrupt handler.

The free_irq function is used to remove the handler and disable the line if not shared.

If it is shared and no handlers remain on the line, the given interrupt line will be disabled.

Highlight free_irq(). In the exit function, we have used the free function to remove the handler from the kernel.

It will unregister the interrupt handler from the kernel.

Save and close the file Now, save and close the file.

Type >> gedit user.c

Let us now open the user program.

Type gedit space user dot c.

The program will open and close a device using respective system calls.

Save and close the file.

Clear the screen.

Now, 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 >> insmod interrupt.ko

Let’s compile the driver.

Type make space all

Clear the screen.

Now let us load the driver into the kernel.

Type insmod space interrupt dot ko.

Type cat /proc/interrupts | grep my_interrupt

/proc/interrupts

Type >> clear

Type cat space slash proc slash interrupts space pipe space grep space my_interrupt.

Interrupt file in procfs contains the list of registered interrupts in the system.

This command will show the registered interrupt my_interrupt and its IRQ line number.

In the output, we can see our registered interrupt name and IRQ number.

It indicates that our interrupt handler is registered successfully.

Clear the screen.

Type >> gcc -c user.c.


Type >> gcc -o user.out user.o

Now compile the user program.

Type gcc hyphen c user dot c

Type gcc hyphen o user dot out user dot o.

Type >> ./user.out

Highlight output

Type >> clear

Now let us execute the user program.

Type dot slash user dot out

Here, output shows that the device opened and closed successfully.

Clear the screen.

Type >> dmesg | grep my_driver

Type >> clear

Type dmesg space pipe space grep space my_driver.

This message shows that the device open function triggered the interrupt.

It indicates that as soon as the interrupt triggered, its handler got executed.

After the execution of the handler, the remaining code from the open function is executed.

It shows that the driver properly handled the interrupt.

Clear the screen.

Type >> rmmod interrupt.ko

Type >> dmesg | grep my_driver

Type >> clear

Now let's unload the driver.

Type rmmod space interrupt dot ko

Let us see the unloaded printk messages.

Type dmesg space pipe space grep space my_driver.

Here, we can see our interrupt handler is unregistered from the kernel.

Clear the screen.

Type >> make clean. To remove the object files, type make space clean.
With this, we come to the end of this tutorial. Let us summarise.
Slide 11:

Summary:

In this tutorial, we learnt
  • Interrupt Handling in the driver
Slide 12:

Assignment :

As an assignment:
  1. Open the interrupt.c driver file.
  2. Write the interrupt instruction in the release function.
  3. Compile and load the driver.
  4. Compile and execute the user program.
  5. See the output using dmesg command.
Slide 13:

About Spoken Tutorial Project:

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

Spoken Tutorial workshops :

The Spoken Tutorial Project Team conducts workshops and gives certificates.

For more details, please write to us.

Slide 15:

Forum questions :

Please post your timed queries in this forum
Slide 16:

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 17:

Acknowledgment:

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

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