Re: Installable ISR - general questions by Valter
Valter
Thu Sep 28 09:11:58 CDT 2006
"Ole" <ole@blabla.com> wrote in
news:#OXsONw4GHA.3600@TK2MSFTNGP03.phx.gbl:
[...]
> Ehh - OK - the interrupt structure and implementation in CE is
> hard for me to understand - so please be patiented with me.
I think that my poor english (I'm Italian) is another factor in
making this seem to complex.
In CE the interrupt is handled at 2 layers:
The ISR (Interrupt Service Routine) is called by the interrupt
handler (or handlers in the case of x86) installed by the OS.
It should "tranlate" the interrupt into a numeric value (the
SYSINTR). On some platforms (x86) this may be straightforward, on
other device this could mean interrogating internal or external
hardware (FPGAs) to understand what generated the interrupt.
Some SYSINTR codes have a special meaning for the OS. For example,
SYSINTR_RESCHEDULE tells the kernel that it should check if a thread
reschedule is needed or SYSINTR_NOP means that the interrupt has
been handled inside the ISR and so no other operation is needed by
the kernel and the OS irq handler should return ASAP.
The ISR it's part of the OAL, the part of the BSP that is linked
with the kernel (in CE 6.0 it will be a DLL) so changing the ISR
requires a rebuild of the kernel (and of the OS image, of course).
ISRs can hadle out interrupt they don't recognize to "external"
handlers using the NKCallIntChain kernel function. A BSP can skip
this call for some or all the interrupt and so the support for
external ISRs is not granted on every CE device.
The external ISR is implemented in a DLL that contains the ISR
routine (called via NkCallIntChain) and also other functions:
- one is called when the DLL is loaded (an application or driver
should call LoadIntChainHandler to do that)
- the other one is invoked when an application/driver (usually the
one who loaded the DLL inside the kernel) calls KernelIOControl,
providing a mean to exchangs informations between the
application/driver layer and the kernel layer.
The ISR function inside the DLL can return a specific SYSINTR,
meaning that it has recognized the interrupt, SYSINTR_NOP if it has
already completed the interrupt handling or SYSINTR_CHAIN to pass
the interrupt to the next installable ISR in chain (this is useful
for devices that shares an IRQ, for example PCI cards).
If the kernel receives a SYSINTR code back from the ISR that is
different than SYSINTR_NOP,SYSINTR_RESCHEDULE or SYSINTR_CHAIN, it
checks if an application has connected an event to that specific
SYSINTR using InterruptInitialize and set the event.
Usually the driver/application that invoked InterruptInitialize has
a thread stopped waiting for the event to be set. When the kernel
set the event two things may happen:
- the currently running thread has a priority lower than that the
thread waiting for the event (don't forget that 0 is the hightest
priority!) and so it suspend the current thread and restarts the one
that was waiting for the interrupt.
- if the currently running thread has an higher priority, it will
continue to run but the IST will be put back in running state and
will be schedule as soon as no other high-priority threads need the
CPU.
> Cuurently I have implemented an IST in a dll that handles the
> interrupt from IRQ 11, but the IST is called on every interrupt.
> The load on the system is quite high and I would like to implement
> my code in an ISR directly, only calling the IST when the buffer
> is ready to be emptied. Therefore I thought that an installable
> ISR could be a solution, but I do not know anything about it yet.
I hope that my explanation helped you to undertand it a little
more...
> From what you wrote I assume that there is a better and a more
> direct/efficient way to do it - right? by reading about the
> OEMInterruptHandler I understand that it is only used in systems
> with one ISR like in ARMs (mine is a X86) so the other option you
> mention (loadable handler - couldn't find any information on it)
Loadable and installable are the same thing, I forgot the term used
in PB docs and called it "loadable" because the function that loads
it is called "LoadIntChainHandler" and not Install... :)
OEMInterruptHandler is specific for the single interrupt vector
platform, on the x86 architecture HookInterrupt allows you to write
an interrupt handler and link it to a specific interrupt inside the
kernel, but the result doesn't change because you need to modify the
OAL to do that and also to add some codes to OEMIOControl inside the
BSP if you need to exchange some data between the kernel and the
high-level code.
IMHO installable handlers are the best option if your BSP support
them. You may loose a little bit of performance (the time needed to
call NKCallIntChain, I think not a noticeable overhead) but your
driver will remain independent from the rest of the BSP, making it
more portable and maintainable.
--
Valter Minute
(the reply address of this message is invalid)
(l'indirizzo di reply di questo messaggio non è valido)