diff -r 48780e181b38 -r 578be2adaf3e Symbian3/PDK/Source/GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita --- a/Symbian3/PDK/Source/GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita Tue Jul 20 12:00:49 2010 +0100 +++ b/Symbian3/PDK/Source/GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita Fri Aug 13 16:47:46 2010 +0100 @@ -9,45 +9,44 @@ --> -Interrupt -DispatcherAn interrupt is a condition that causes the CPU to suspend normal -execution, enter interrupt handling state and jump to a section of code called -an interrupt handler. The ASSP/variant part of the base port must implement -an interrupt dispatcher to manage interrupts. -

An interrupt source is a hardware device or software action that can force -the CPU to enter interrupt handling state.

+Interrupt DispatcherThe ASSP/Variant part of the base port must implement an +interrupt dispatcher to manage interrupts. +

An interrupt source is a hardware device or software action that +can force the CPU to suspend normal execution, enter interrupt handling +state and jump to a section of code called an interrupt handler.

Typically, a number of interrupt sources are monitored by an interrupt controller. This is hardware that generates a single interrupt notification -to the CPU, and provides information about which interrupts are pending, i.e. -which interrupts require action to be taken.

-
ISR

An -interrupt service routine, or ISR, is code that deals with a pending interrupt. -The Symbian platform kernel responds to an interrupt notification by calling -an ISR for each pending interrupt. The process of calling ISRs is called interrupt -dispatch.

The ISR is a single bare function. It is not a class member.

Each -ISR takes a single 32-bit parameter that is, typically, a pointer to an owning -class, although it can be any value that is appropriate. The parameter is -defined as a TAny * type, so a cast is almost always necessary.

ISRs -are usually kept in an ISR table.

-
Interrupt ID

An -interrupt source is identified by number, defined as a TInt type. -Typically, the ASSP layer defines this number for each interrupt in a header -file and exports it so that it can be included and used by device drivers.

Where -the ASSP layer is split into a common layer and a variant (device specific) -layer, then the variant layer may also define its own set of interrupt IDs.

This -number is usually referred to as the interrupt ID.

-
Binding and -unbinding

Only one ISR can be associated with each possible interrupt -source. Making this association is known as binding. ISRs can be bound and -unbound during normal operation, but only one ISR can be bound to an interrupt -source at any one time.

A device driver binds an ISR by calling Interrupt::Bind(), -passing the interrupt source ID; similarly, the device driver can unbind the -ISR by calling Interrupt::Unbind(), also passing the interrupt -ID.

+to the CPU, and provides information about which interrupts are pending, +i.e. which interrupts require action to be taken.

+
ISR

An interrupt service routine, or ISR, is code that deals with +a pending interrupt. The Symbian platform kernel responds to an interrupt +notification by calling an ISR for each pending interrupt. The process +of calling ISRs is called interrupt dispatch.

The ISR is a +single bare function. It is not a class member.

Each ISR takes +a single 32-bit parameter that is, typically, a pointer to an owning +class, although it can be any value that is appropriate. The parameter +is defined as a TAny * type, so a cast is almost +always necessary.

ISRs are usually kept in an ISR table.

+
Interrupt +ID

An interrupt source is identified by number, defined +as a TInt type. Typically, the ASSP layer defines +this number for each interrupt in a header file and exports it so +that it can be included and used by device drivers.

Where +the ASSP layer is split into a common layer and a variant (device +specific) layer, then the variant layer may also define its own set +of interrupt IDs.

This number is usually referred to as the +interrupt ID.

+
Binding +and unbinding

Only one ISR can be associated with each +possible interrupt source. Making this association is known as binding. +ISRs can be bound and unbound during normal operation, but only one +ISR can be bound to an interrupt source at any one time.

A +device driver binds an ISR by calling Interrupt::Bind(), passing the interrupt source ID; similarly, the device driver can +unbind the ISR by calling Interrupt::Unbind(), +also passing the interrupt ID.

Dispatching -interrupts

At its simplest, this is the process of deciding which -interrupts are pending and calling the ISR for each.

The following -pseudo code shows the general principle:

+interrupts

At its simplest, this is the process of deciding +which interrupts are pending and calling the ISR for each.

The following pseudo code shows the general principle:

{ FOREVER { @@ -59,136 +58,141 @@ call ISR for the pending interrupt; } } -

In practice the dispatcher may have to do some more work to -communicate with the interrupt controller hardware.

-
Chained interrupts

A -system may have multiple interrupt controllers to handle a large number of -interrupt sources. These are usually prioritised by connecting the interrupt -output of a lower-priority controller to an interrupt input of a higher-priority -controller. This is called chaining.

- -

An interrupt from a lower priority controller will appear as an -interrupt on the highest-priority controller.

When the interrupt dispatcher -of the higher-priority controller detects that it is the chained interrupt -that is pending, the usual way of dealing with this is to run a secondary -dispatcher to determine which interrupt on the chained controller is pending.

There -may be further levels of chaining before the true source of the interrupt -has been identified.

-
Multiple interrupt -sources and pseudo interrupt sources

It is possible that a single -input to an interrupt controller is shared by several interrupt sources.

- +

In practice the dispatcher may have to do some more +work to communicate with the interrupt controller hardware.

+
Chained +interrupts

A system may have multiple interrupt controllers +to handle a large number of interrupt sources. These are usually prioritised +by connecting the interrupt output of a lower-priority controller +to an interrupt input of a higher-priority controller. This is called +chaining.

+Chained interrupts + +

An interrupt from a lower priority controller will appear +as an interrupt on the highest-priority controller.

When the +interrupt dispatcher of the higher-priority controller detects that +it is the chained interrupt that is pending, the usual way of dealing +with this is to run a secondary dispatcher to determine which interrupt +on the chained controller is pending.

There may be further +levels of chaining before the true source of the interrupt has been +identified.

+
Multiple +interrupt sources and pseudo interrupt sources

It is possible +that a single input to an interrupt controller is shared by several +interrupt sources.

+Multiple interrupt sources +

It appears necessary to bind multiple ISRs to the same interrupt. -However, this is not possible. There are two ways of dealing with this:

    -
  • Maintain a list of all -ISRs that are bound to this single interrupt source, and call all the ISRs -in the list when the interrupt is dispatched. This is most conveniently implemented -by binding a single ISR to the interrupt, which then calls all the real ISRs -bound to this interrupt

  • -
  • Create pseudo interrupts. -These are extra interrupt IDs that do not exist in the interrupt controller, -but represent each of the interrupt sources connected to the single shared -interrupt source. An ISR can then be bound to each pseudo interrupt. The interrupt -dispatcher can then determine which of the sources are actually signalling -and call the appropriate ISR via that pseudo interrupt ID. This is effectively -an implementation of a chained -interrupt, and assumes that the interrupt dispatcher can identify which -of the sources is signalling.

  • +However, this is not possible. There are two ways of dealing with +this:

      +
    • Maintain a list +of all ISRs that are bound to this single interrupt source, and call +all the ISRs in the list when the interrupt is dispatched. This is +most conveniently implemented by binding a single ISR to the interrupt, +which then calls all the real ISRs bound to this interrupt

    • +
    • Create pseudo +interrupts. These are extra interrupt IDs that do not exist in the +interrupt controller, but represent each of the interrupt sources +connected to the single shared interrupt source. An ISR can then be +bound to each pseudo interrupt. The interrupt dispatcher can then +determine which of the sources are actually signalling and call the +appropriate ISR via that pseudo interrupt ID. This is effectively +an implementation of a chained interrupt, and assumes that the interrupt dispatcher +can identify which of the sources is signalling.

Interrupts -in the split ASSP/Variant Configuration

When a common ASSP extension -is used, a device may have additional peripherals external to the ASSP, and -there needs to be a way of allowing extra interrupt binding and dispatch functions -to be added later by the variant layer. This must be handled by the port as -Symbian platform does not provide any additional API to support this.

Device -drivers should be able to use the Interrupt class functions -without having to know where the interrupt is actually implemented. This implies -that all requests should go to the core implementation of functions like Interrupt::Bind(), Interrupt::Enable() etc.

To enable the core implementation of these functions to decide -whether an interrupt ID refers to a core interrupt or device specific interrupt, -a common technique is to "tag" the interrupt ID. A simple way is to use positive -numbers to identify core interrupts and negative numbers to identify device -specific interrupts. The ISRs for device specific interrupts are not stored -in the core ISR table, instead the device specific layer provides its own -ISR table.

The general pattern for creating the core-device specific -split is that the core derives an implementation from class Asic, -and the device specific part further derives from this core implementation. -The usual technique is to add a set of virtual functions to the core class -that can be derived by the device specific part. The core can provide default -implementations for these functions that would just return KErrArgument to -trap illegal ID numbers. This API would need functions equivalent to each -of the functions defined by the Interrupt class.

As -an example, the core layer for the template reference board defines a class TemplateAssp that -is derived from Asic. TemplateAssp defines -the pure virtual functions: InterruptBind(), InterruptUnbind(), InterruptEnable() etc, -all with signatures that are the same for the comparable functions defined -by Interrupt, and which are implemented by the Template class.

- +in the split ASSP/Variant Configuration

When a common ASSP +extension is used, a device may have additional peripherals external +to the ASSP, and there needs to be a way of allowing extra interrupt +binding and dispatch functions to be added later by the variant layer. +This must be handled by the port as Symbian platform does not provide +any additional API to support this.

Device drivers should +be able to use the Interrupt class functions without +having to know where the interrupt is actually implemented. This implies +that all requests should go to the core implementation of functions +like Interrupt::Bind(), Interrupt::Enable() etc.

To enable the core implementation of these functions +to decide whether an interrupt ID refers to a core interrupt or device +specific interrupt, a common technique is to "tag" the interrupt ID. +A simple way is to use positive numbers to identify core interrupts +and negative numbers to identify device specific interrupts. The ISRs +for device specific interrupts are not stored in the core ISR table, +instead the device specific layer provides its own ISR table.

The general pattern for creating the core-device specific split +is that the core derives an implementation from class Asic, and the device specific part further derives from this core implementation. +The usual technique is to add a set of virtual functions to the core +class that can be derived by the device specific part. The core can +provide default implementations for these functions that would just +return KErrArgument to trap illegal ID numbers. +This API would need functions equivalent to each of the functions +defined by the Interrupt class.

As an example, +the core layer for the template reference board defines a class TemplateAssp that is derived from Asic. TemplateAssp defines the pure virtual functions: InterruptBind(), InterruptUnbind(), InterruptEnable() etc, all with signatures that are the +same for the comparable functions defined by Interrupt, and which are implemented by the Template class.

+Interrupt binding +
-
Spurious interrupts

In -the Kernel Architecture 2, it is a convention that unbound interrupts should -be bound to a "spurious" interrupt handler, i.e. an interrupt handler that -faults the system indicating the number of the interrupt. This aids debugging -by identifying interrupts that are enabled without corresponding ISRs.

-
Interrupt priority

The -interrupt architecture supports the concept of adjustable interrupt priorities. -Symbian platform defines the Interrupt::SetPriority() function -that can implement this. The function is passed the ID of the interrupt source -to be adjusted together with a priority value. The meaning of the priority -value is hardware and implementation dependent, and is defined by the port.

-
The ISR table

The -Variant must provide a table where each entry defines which ISR is bound to which interrupt source. The table must have enough -space for entries for each interrupt source that is known to the Variant.

When -the Variant is split into an ASSP layer and a Variant layer, the ISR table -is put in the ASSP layer and will not normally include ISRs for the Variant -interrupt sources - these will be handled by separate chained dispatchers -in the Variant layer.

Symbian platform provides the SInterruptHandler structure, -defined in the header file ...\e32\include\kernel\arm\assp.h to -encapsulate the entry for an ISR. The ISR table is, therefore, just an array -of SInterruptHandler items. For example, if a system has -32 possible interrupt sources, then the ISR table would be defined as:

... +
Spurious +interrupts

In the Kernel Architecture 2, it is a convention +that unbound interrupts should be bound to a "spurious" interrupt +handler, i.e. an interrupt handler that faults the system indicating +the number of the interrupt. This aids debugging by identifying interrupts +that are enabled without corresponding ISRs.

+
Interrupt +priority

The interrupt architecture supports the concept +of adjustable interrupt priorities. Symbian platform defines the Interrupt::SetPriority() function that can implement this. +The function is passed the ID of the interrupt source to be adjusted +together with a priority value. The meaning of the priority value +is hardware and implementation dependent, and is defined by the port.

+
The +ISR table

The Variant must provide a table where each entry +defines which ISR is bound to which interrupt source. The table must have +enough space for entries for each interrupt source that is known to +the Variant.

When the Variant is split into an ASSP layer +and a Variant layer, the ISR table is put in the ASSP layer and will +not normally include ISRs for the Variant interrupt sources - these +will be handled by separate chained dispatchers in the Variant layer.

Symbian platform provides the SInterruptHandler structure, defined in the header file ...\e32\include\kernel\arm\assp.h to encapsulate the entry for an ISR. The ISR table is, therefore, +just an array of SInterruptHandler items. For example, +if a system has 32 possible interrupt sources, then the ISR table +would be defined as:

... const TInt KInterruptSourceCount = 32; SInterruptHandler IsrHandlers[KInterruptSourceCount]; -...

Interrupts are identified in the system by their interrupt -ID number, which is used to index into the ISR table. You are free to allocate -these numbers any way that is convenient for you.

On the template -reference board, for example, the ISR table is defined as a static data member -of the VariantASSPInterrupt class, which is derived from TemplateInterrupt. -The class is defined in ...\template_assp\template_assp_priv.h.

class TemplateInterrupt : public Interrupt +...

Interrupts are identified in the system by their +interrupt ID number, which is used to index into the ISR table. You +are free to allocate these numbers any way that is convenient for +you.

On the template reference board, for example, the ISR +table is defined as a static data member of the VariantASSPInterrupt class, which is derived from TemplateInterrupt. The class is defined in ...\template_assp\template_assp_priv.h.

class TemplateInterrupt : public Interrupt { ... // functions public: static SInterruptHandler Handlers[KNumTemplateInts]; ... - };

where KNumTemplateInts is defined in the same header -file.

Factors -that decide the size of the ISR table

The number of entries to -be reserved in the ISR table depends on the following factors:

    -
  • Where the ASSP is targeted -at only a single device, the number of possible interrupts is usually known, -and the table can include an entry for each one.

  • -
  • If any pseudo sources exist, they should be included in the main table for -efficiency, but note that this is not strictly necessary.

  • -

Other -factors affecting the ISR table

IRQs and FIQs may need to be distinguished, -although the exact requirement is hardware dependent. Although the table has -one entry for each possible interrupt source, a possible scheme may be to -group IRQs at the start of the table, and FIQs at the end of the table. If -the hardware has separate interrupt controller hardware for IRQs and FIQs -(or at least, different registers) then you will need to arrange the table -so that you can determine from the interrupt -ID whether the interrupt is an IRQ or FIQ.

For example:

- + };

where KNumTemplateInts is defined in the same +header file.

Factors that decide the size of the ISR table

The number of entries to be reserved in the ISR table depends +on the following factors:

    +
  • Where the ASSP +is targeted at only a single device, the number of possible interrupts +is usually known, and the table can include an entry for each one.

  • +
  • If any pseudo sources exist, they should be included in the main +table for efficiency, but note that this is not strictly necessary.

  • +

Other factors affecting the ISR table

IRQs +and FIQs may need to be distinguished, although the exact requirement +is hardware dependent. Although the table has one entry for each possible +interrupt source, a possible scheme may be to group IRQs at the start +of the table, and FIQs at the end of the table. If the hardware has +separate interrupt controller hardware for IRQs and FIQs (or at least, +different registers) then you will need to arrange the table so that +you can determine from the interrupt ID whether the interrupt is an IRQ or FIQ.

For example:

+ISR table +
-
Location of -interrupt handling code

Most of the interrupt dispatching code -is implemented in the ASSP layer. This includes a list of ISRs, code for adding -and removing ISRs, enabling and disabling interrupt sources, and dispatching -ISRs. The kernel only provides a pre-amble and post-amble.

The kernel -defines, but does not implement, a class called Interrupt that -exports interrupt functionality to device drivers and other kernel code. The -class provides the public API for using interrupts (but not for dispatching -them). The port must provide an implementation for each function defined by -the class.

The class is defined in the header files ...\e32\include\kernel\arm\assp.h, -which is exported to ...\epoc32\include\kernel\arm.

See -Symbian OS Internals Book, Chapter 6 - Interrupts and Exceptions

+
Location +of interrupt handling code

Most of the interrupt dispatching +code is implemented in the ASSP layer. This includes a list of ISRs, +code for adding and removing ISRs, enabling and disabling interrupt +sources, and dispatching ISRs. The kernel only provides a pre-amble +and post-amble.

The kernel defines, but does not implement, +a class called Interrupt that exports interrupt +functionality to device drivers and other kernel code. The class provides +the public API for using interrupts (but not for dispatching them). +The port must provide an implementation for each function defined +by the class.

The class is defined in the header files ...\e32\include\kernel\arm\assp.h, which is exported to ...\epoc32\include\kernel\arm.

See Symbian OS +Internals Book, Chapter 6 - Interrupts and Exceptions

\ No newline at end of file