Difference between revisions of "Embedded-Linux-Device-Driver/C3/Interrupt-Handling/English"
Nancyvarkey (Talk | contribs) |
Nancyvarkey (Talk | contribs) |
||
Line 13: | Line 13: | ||
Learning objectives: | Learning objectives: | ||
− | || In this tutorial, we will learn how to handle the software interrupt in the driver. | + | || In this tutorial, we will learn how to handle the '''software interrupt''' in the '''driver'''. |
|- | |- | ||
|| Slide 3: | || Slide 3: | ||
Line 28: | Line 28: | ||
Prerequisites: | Prerequisites: | ||
|| To follow this tutorial, you should be familiar with: | || To follow this tutorial, you should be familiar with: | ||
− | * '''C programming language | + | * '''C programming language''' and |
* '''Basics of Linux kernel''' | * '''Basics of Linux kernel''' | ||
Line 37: | Line 37: | ||
|| | || | ||
− | * The '''function''' that runs in response to a specific '''interrupt''' is called an '''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'''. | * Different '''devices''' can be associated with different '''interrupts'''. | ||
* A '''driver''' needs to handle the '''interrupts''' properly for its '''device'''. | * A '''driver''' needs to handle the '''interrupts''' properly for its '''device'''. | ||
Line 44: | Line 44: | ||
Working - '''Interrupt Handling.''' | Working - '''Interrupt Handling.''' | ||
− | || In this tutorial, a user program will '''open''' and '''close''' the '''device file'''. | + | || |
+ | *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 '''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'''. | + | *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 folder and file in '''desktop''' | ||
Line 96: | Line 97: | ||
Highlight '''irqreturn_t irq_handler()''' | Highlight '''irqreturn_t irq_handler()''' | ||
− | || We have defined the''' IRQ line number | + | || 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. | The '''devices''' can send '''interrupts''' to the '''processor''' using these '''IRQ''' lines. | ||
Line 147: | Line 148: | ||
|| Let us see some important '''flags''' that can be used by '''request_irq function'''. | || 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_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_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_TIMER''' - It is used to mark this '''interrupt''' as '''timer interrupt''' |
− | '''IRQF_SHARED''' - It allows sharing the '''irq''' among several '''devices'''. | + | *'''IRQF_SHARED''' - It allows sharing the '''irq''' among several '''devices'''. |
|- | |- | ||
|| | || |
Latest revision as of 14:57, 12 February 2021
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,
|
Slide 4:
Prerequisites: |
To follow this tutorial, you should be familiar with:
If not, then go through the C/C++ and Linux spoken tutorials on this website |
Slide 6 :
Interrupt handler |
|
Slide :
Working - Interrupt Handling. |
|
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: |
|
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.
|
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.
|
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
|
Slide 12:
Assignment : |
As an assignment:
|
Slide 13:
About Spoken Tutorial Project: |
|
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 : |
|
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. |