Can interrupt handler




















Add a comment. Active Oldest Votes. There's several different types of "interrupt handlers". The second, the software interrupt handlers, are used to call OS level services in modern OSes. Improve this answer. Sign up or log in Sign up using Google.

Sign up using Facebook. Sign up using Email and Password. Post as a guest Name. Email Required, but never shown. The Overflow Blog. Does ES6 make JavaScript frameworks obsolete? Podcast Do polyglots have an edge when it comes to mastering programming Because such values are automatically changed after every interrupt, the IRQ signals are, in most cases, fairly distributed among all CPUs.

No other CPUs are notified of the event. All this is magically done by the hardware, so it should be of no concern for the kernel after multi-APIC system initialization. Unfortunately, in some cases the hardware fails to distribute the interrupts among the microprocessors in a fair way for instance, some Pentium 4-based SMP motherboards have this problem. Therefore, Linux 2. The exception stack is used when handling exceptions including system calls.

The hard IRQ stack is used when handling interrupts. As with other context switches, the need to save registers leaves the kernel developer with a somewhat messy coding job, because the registers have to be saved and restored using assembly language code. However, within those operations, the processor is expected to call and return from a C function. In this section, we describe the assembly language task of handling registers; in the next, we show some of the acrobatics required in the C function that is subsequently invoked.

Saving registers is the first task of the interrupt handler. As already mentioned, the address of the interrupt handler for IRQ n is initially stored in the interrupt[n] entry and then copied into the interrupt gate included in the proper IDT entry. S file. The element at index n in the array stores the address of the following two assembly language instructions:. The result is to save on the stack the IRQ number associated with the interrupt minus The kernel represents all IRQs through negative numbers, because it reserves positive interrupt numbers to identify system calls see Chapter The same code for all interrupt handlers can then be executed while referring to this number.

The macro then loads the selector of the user data segment into ds and es. It is declared as follows:. In particular, the function performs the following substeps:. If the two addresses are equal, the kernel is already using the hard IRQ stack, thus jumps to step 3. This happens when an IRQ is raised while the kernel is still handling another interrupt. Here the Kernel Mode stack has to be switched. This is done so that the current macro works as expected while the kernel is using the hard IRQ stack see the section " Identifying a Process " in Chapter 3.

If the hard IRQ stack has been effectively switched in step 2e above, the function copies the original stack pointer from the ebx register into the esp register, thus switching back to the exception stack or soft IRQ stack that were in use before. Before accessing the main IRQ descriptor, the kernel acquires the corresponding spin lock. This spin lock is necessary in a multiprocessor system, because other interrupts of the same kind may be raised, and other CPUs might take care of the new interrupt occurrences.

After acquiring the spin lock, the function invokes the ack method of the main IRQ descriptor. Masking the IRQ line ensures that the CPU does not accept further occurrences of this type of interrupt until the handler terminates. Depending on the type of interrupt, acknowledging the interrupt could either be done by the ack method or delayed until the interrupt handler terminates that is, acknowledgement could be done by the end method.

There are three cases in which nothing has to be done. These are discussed in the following list. In a multiprocessor system, another CPU might be handling a previous occurrence of the same interrupt.

Why not defer the handling of this occurrence to that CPU? This is exactly what is done by Linux. Moreover, the freed CPU can quickly return to what it was doing, without dirtying its hardware cache; this is beneficial to system performance. This case occurs when there is no interrupt service routine associated with the interrupt. Normally, this happens only when the kernel is probing a hardware device.

If it is clear, no further occurrence of the interrupt has been delivered to another CPU, so the loop ends. The function invokes the end method of the main IRQ descriptor.

However, things may not work so smoothly in a multiprocessor system. Therefore, even though the interrupt occurred before the IRQ line was disabled, it gets lost. If so, the function forces the hardware to generate a new occurrence of the lost interrupt:. These guidelines have their exceptions, of course.

If you are not using your RTOS, it is likely that your program flow is either a run loop or entirely interrupt driven. For both of these cases, you may need to use heavier operations inside of the interrupt handler. In the past i had supported the technical issue from customer. They have designed to handle simply the both edges of data as gpio interrupt with other interrupts in single ISR. Due to too many input stream data, sometimes ISR lost some bits data. In our example above, the function serint is the ISR.

In general, an ISR is responsible for:. Depending on the complexity of the hardware device, the ISR, and the application, some of the above steps may be omitted.

Depending on your hardware configuration, there may actually be multiple hardware sources associated with an interrupt. This issue is a function of your specific hardware and bus type. This characteristic plus good programming style mandates that your ISR ensure that the hardware associated with it actually caused the interrupt.

Most PIC Programmable Interrupt Controller chips can be programmed to respond to interrupts in either an edge-sensitive or level-sensitive manner. Depending on this programming, interrupts may be sharable.

In the above scenario, if the PIC is operating in a level-sensitive mode, the IRQ is considered active whenever it's high. In this configuration, while the second assertion step 2 doesn't itself cause a new interrupt, the interrupt is still considered active even when the original cause of the interrupt is removed step 3.

Not until the last assertion is cleared step 4 will the interrupt be considered inactive. Only when the interrupt line is cleared, and then reasserted, does the PIC consider another interrupt to have occurred. The impact of this is that each handler in the chain must look at its associated hardware and determine if it caused the interrupt. This works reliably in a level-sensitive environment, but not an edge-triggered environment. To illustrate this, consider the case where two hardware devices are sharing an interrupt.

Now, suppose HW-B asserts the interrupt line first. Neutrino detects the interrupt and dispatches the two handlers in order — ISR-A runs first and decides correctly that its hardware did not cause the interrupt. Then ISR-B runs and decides correctly that its hardware did cause the interrupt; it then starts servicing the interrupt.

Since ISR-A already ran, it can't possibly run again to actually clear the source of the interrupt. Since ISR-A clears the source of the interrupt and ISR-B doesn't do anything, because its associated hardware doesn't require servicing , everything functions as expected.

In a level-sensitive environment, your ISR must clear the source of the interrupt or at least mask it via InterruptMask before it completes. In an edge-triggered environment, there's no such requirement, because the interrupt won't be noticed again until it transits from clear to asserted. In general, to actually service the interrupt, your ISR has to do very little; the minimum it can get away with is to clear the source of the interrupt and then schedule a thread to actually do the work of handling the interrupt.

This is the recommended approach, for a number of reasons:. When the ISR is servicing the interrupt, it can't make any kernel calls except for the few that we'll talk about shortly. This means that you need to be careful about the library functions that you call in an ISR, because their underlying implementation may use kernel calls.



0コメント

  • 1000 / 1000