Linux Kernel programming (Interrupt Processing Program) 9-Linux general technology-Linux programming and kernel information. The following is a detailed description. Author: Ori Pomerantz
Translation: Xu hui
11. interrupt handling program
In addition to the last chapter, what we are currently doing in the kernel is to respond to a process request, possibly by processing a special file, sending an ioctl, or making a system call. However, the kernel does not only respond to process requests, but also publishes commands or messages to the hardware connected to the machine.
There are two types of interaction between CPU and other hardware. First, the CPU sends commands to the hardware. The other is that the hardware needs to tell the CPU something. The second type of interaction is called interruption, which is hard to implement because it needs to process hardware instead of CPU. Hardware devices are usually made up of a very small ram, and they will be lost if you read them when they are not available in this ram.
In Linux, hardware interruption is called IRQ (abbreviated as Interrupt Requests ). There are two types of IRQ: Short Type and long type. Short IRQ takes a short time, during which other parts of the machine are locked and no other interruptions are processed. A long IRQ takes a long time, during which other interruptions may occur (but not from the same device ). If possible, it is best to declare a middle section as a long type.
If the CPU receives an interrupt, it stops all operations (unless it is dealing with a more important interrupt, in this case, the interrupt will not be processed until the more important interrupt processing is completed.) store the relevant parameters in the stack and call the interrupt processing program. This means that some tasks in the interrupt handler itself are not allowed, because the system is in an unknown state. The solution to this problem is to let the interrupt handler do what needs to be done immediately, usually reading information from the hardware or sending information to the hardware, then, schedule the processing of new information to the Future (this is called the half bottom) and return it. The kernel ensures that the half base is called as soon as possible. During the call, anything that can be done in the kernel module can be done.
The method is to call the interrupt handler when it is connected to the related IRQ (16 IRQ on the Intel platform. This function is connected to the IRQ Number, function name, flag, a/proc/interrupts name, and a parameter passed to the interrupt handler. The flag can include SA_SHIRQ to indicate that you want to share this IRQ with other processing programs (usually many devices share an IRQ), or a SA_INTERRUPT to indicate that this is an emergency interrupt. This function runs only when IRQ does not have any other handler or shares all the handlers.
With the interrupt processing program, we can communicate with the hardware, and use queue_task_irq and tq_immediate and mark_bh (BH_IMMEDIATE) to schedule the half-bottom. Standard queue_task cannot be used in version 2.0 because the interruption may occur in the middle of a queue_task. We need mark_bh because in earlier Linux versions, there was only one half-bottom queue with a length of 32. Now one of them (BH_IMMEDIATE) is used for the semi-bottom Chain List of drivers that are not allocated to them.
11.1 Intel keyboard
Note: The content below this chapter is completely for the Intel structure. If you are not on the Intel Platform, the program will not work and there is no need to compile it.
I encountered a problem when I wrote the program in this chapter. On the one hand, as a useful example, it needs to run on every machine and get the correct result. On the other hand, the kernel already contains drivers for all common devices. These drivers and the code I want to write may not necessarily coexist. I found a way to write something for a keyboard interrupt, and first make the normal keyboard interrupt invalid. Because it is defined as a static symbol in the kernel source file (drivers/char/keyboard. c), there is no way to restore it. Run the insmod code on sleep 120 on another terminal. If you want to evaluate the file system, reboot is required.
This code binds itself to IRQ1. In the Interl structure, this is the keyboard-controlled IRQ. Then, when it is disconnected from a keyboard, it reads the keyboard status (this is the purpose of inb (0x64) and scan code returned by the keyboard. Then, as long as the kernel thinks it is OK, it runs got_char to give the key encoding (the first 7 digits of the scan code) and whether the information is pressed (if the 8th-bit value is 0, it indicates the press, is 1 indicates release ).
Ex intrpt. c
/* Intrpt. c-An interrupt handler .*/
/* Copy right (C) 1998 by Ori Pomerantz */
/* The necessary header files */
/* Standard in kernel modules */
# Include/* Were doing kernel work */
# Include/* Specifically, a module */
/* Deal with CONFIG_MODVERSIONS */
# If CONFIG_MODVERSIONS = 1
# Define MODVERSIONS
# Include
# Endif
# Include
# Include
/* We want an interrupt */
# Include
# Include
/* In 2.2.3/usr/include/linux/version. h between des
* Macro for this, but 2.0.35 doesnt-so I add it
* Here if necessary .*/
# Ifndef KERNEL_VERSION
# Define KERNEL_VERSION (a, B, c) (a) x 65536 + (B) * 256 + (c ))
# Endif
/* Bottom Half-this will get called by the kernel
* As soon as its safe to do everything normally
* Allowed by kernel modules .*/
Static void got_char (void * scancode)
{
Printk ("" Scan Code % x % s ."",
(Int) * (char *) scancode) & 0x7F,
* (Char *) scancode) & 0x80? "" Released "": "" Pressed "");
}
/* This function services keyboard interrupts. It reads
* The relevant information from the keyboard and then
* Scheduales the bottom half to run when the kernel
* Considers it safe .*/
Void irq_handler (int irq,
Void * dev_id,
Struct pt_regs * regs)
{
/* This variables are static because they need to be
* Accessible (through pointers) to the bottom
* Half routine .*/
Static unsigned char scancode;
Static struct tq_struct task =
{NULL, 0, got_char, & scancode };
Unsigned char status;
/* Read keyboard status */
Status = inb (0x64 );
Scancode = inb (0x60 );
/* Initialize the module-register the IRQ handler */
Int init_module ()
{
/* Since the keyboard handler wont co-exist
* Another handler, such as us, we have to disable
* It (free its IRQ) before we do anything. Since we
* Dont know where it is, theres no way
* Reinstate it later-so the computer will have
* Be rebooted when were done.
*/
Free_irq (1, NULL );
/* Request IRQ 1, the keyboard IRQ, to go to our
* Irq_handler .*/
Return request_irq (
1,/* The number of the keyboard IRQ on PCs */
Irq_handler,/* our handler */
SA_SHIRQ,
/* SA_SHIRQ means were willing to have othe
* Handlers on this IRQ.
*
* SA_INTERRUPT can be used to make
* Handler into a fast interrupt.
*/
"" Test_keyboard_irq_handler "", NULL );
}
/* Cleanup */
Void cleanup_module ()
{
/* This is only here for completeness. Its totally
* Irrelevant, since we dont have a way to restore
* The normal keyboard interrupt so the computer
* Is completely useless and has to be rebooted .*/
Free_irq (1, NULL );
}
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