Symbian3/PDK/Source/GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita
changeset 1 25a17d01db0c
child 3 46218c8b8afa
equal deleted inserted replaced
0:89d6a7a84779 1:25a17d01db0c
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-76A30EC4-4B99-5471-9E80-F853C91485BC" xml:lang="en"><title>Interrupt
       
    13 Dispatcher</title><shortdesc>An interrupt is a condition that causes the CPU to suspend normal
       
    14 execution, enter interrupt handling state and jump to a section of code called
       
    15 an interrupt handler. The ASSP/variant part of the base port must implement
       
    16 an interrupt dispatcher to manage interrupts. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    17 <p>An interrupt source is a hardware device or software action that can force
       
    18 the CPU to enter interrupt handling state. </p>
       
    19 <p>Typically, a number of interrupt sources are monitored by an interrupt
       
    20 controller. This is hardware that generates a single interrupt notification
       
    21 to the CPU, and provides information about which interrupts are pending, i.e.
       
    22 which interrupts require action to be taken. </p>
       
    23 <section id="GUID-1FAA26F5-BFB2-55A0-977C-1538EBF3C82A"><title>ISR</title> <p>An
       
    24 interrupt service routine, or ISR, is code that deals with a pending interrupt.
       
    25 The Symbian platform kernel responds to an interrupt notification by calling
       
    26 an ISR for each pending interrupt. The process of calling ISRs is called interrupt
       
    27 dispatch. </p> <p>The ISR is a single bare function. It is not a class member. </p> <p>Each
       
    28 ISR takes a single 32-bit parameter that is, typically, a pointer to an owning
       
    29 class, although it can be any value that is appropriate. The parameter is
       
    30 defined as a <xref href="GUID-6D079976-9119-31FA-8E21-C3B815F94648.dita"><apiname>TAny</apiname></xref> * type, so a cast is almost always necessary. </p> <p>ISRs
       
    31 are usually kept in an ISR table. </p> </section>
       
    32 <section id="GUID-8E58F4C9-0290-55E0-A4FD-B6C2361BE205"><title>Interrupt ID</title> <p>An
       
    33 interrupt source is identified by number, defined as a <xref href="GUID-7A2A43EC-6125-3BFE-834B-23C37F7B40D5.dita"><apiname>TInt</apiname></xref> type.
       
    34 Typically, the ASSP layer defines this number for each interrupt in a header
       
    35 file and exports it so that it can be included and used by device drivers. </p> <p>Where
       
    36 the ASSP layer is split into a common layer and a variant (device specific)
       
    37 layer, then the variant layer may also define its own set of interrupt IDs. </p> <p>This
       
    38 number is usually referred to as the interrupt ID. </p> </section>
       
    39 <section id="GUID-A8C9C079-D043-5A5F-9F08-CD8656F6702A"><title>Binding and
       
    40 unbinding</title> <p>Only one ISR can be associated with each possible interrupt
       
    41 source. Making this association is known as binding. ISRs can be bound and
       
    42 unbound during normal operation, but only one ISR can be bound to an interrupt
       
    43 source at any one time. </p> <p>A device driver binds an ISR by calling <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita#GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3/GUID-4E3CB472-3525-32F8-9BC4-8ECFEE931E7B"><apiname>Interrupt::Bind()</apiname></xref>,
       
    44 passing the interrupt source ID; similarly, the device driver can unbind the
       
    45 ISR by calling <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita#GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3/GUID-CCC9A397-608C-3EAF-830F-A59800C2E8E5"><apiname>Interrupt::Unbind()</apiname></xref>, also passing the <xref href="GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita#GUID-76A30EC4-4B99-5471-9E80-F853C91485BC/GUID-8E58F4C9-0290-55E0-A4FD-B6C2361BE205">interrupt
       
    46 ID</xref>. </p> </section>
       
    47 <section id="GUID-DDA62ABB-9CC6-44DC-B08D-FEE5AC505858"><title>Dispatching interrupts</title> <p>At its simplest, this is
       
    48 the process of deciding which interrupts are pending and calling the ISR for
       
    49 each. </p> <p>The following pseudo code shows the general principle: </p> <codeblock id="GUID-9C971C66-BB26-5A07-9373-3542B95A16FD" xml:space="preserve">
       
    50     {
       
    51        FOREVER
       
    52               {
       
    53         Get next pending interrupt;
       
    54         if None
       
    55             {
       
    56                return;
       
    57             }
       
    58         call ISR for the pending interrupt;
       
    59         }
       
    60     }
       
    61 </codeblock> <p>In practice the dispatcher may have to do some more work to
       
    62 communicate with the interrupt controller hardware. </p> </section>
       
    63 <section id="GUID-9026A4AC-57AF-545D-887C-AF43E0B37EDC"><title>Chained interrupts</title> <p>A
       
    64 system may have multiple interrupt controllers to handle a large number of
       
    65 interrupt sources. These are usually prioritised by connecting the interrupt
       
    66 output of a lower-priority controller to an interrupt input of a higher-priority
       
    67 controller. This is called chaining. </p> <fig id="GUID-49264B94-DF6D-5F11-8815-D42CDBF94E39">
       
    68 <image href="GUID-0DB79535-E4E6-50BD-852D-B2F177202C9C_d0e365802_href.png" placement="inline"/>
       
    69 </fig> <p>An interrupt from a lower priority controller will appear as an
       
    70 interrupt on the highest-priority controller. </p> <p>When the interrupt dispatcher
       
    71 of the higher-priority controller detects that it is the chained interrupt
       
    72 that is pending, the usual way of dealing with this is to run a secondary
       
    73 dispatcher to determine which interrupt on the chained controller is pending. </p> <p>There
       
    74 may be further levels of chaining before the true source of the interrupt
       
    75 has been identified. </p> </section>
       
    76 <section id="GUID-ED6F2F47-7A16-5AE6-8E5B-B2475F6EDEAA"><title>Multiple interrupt
       
    77 sources and pseudo interrupt sources</title> <p>It is possible that a single
       
    78 input to an interrupt controller is shared by several interrupt sources. </p> <fig id="GUID-DC96E3A8-9820-5CD4-8020-3B55398388D9">
       
    79 <image href="GUID-DCBBDFA7-1E6C-5B00-A13E-A25794668E12_d0e365824_href.png" placement="inline"/>
       
    80 </fig> <p>It appears necessary to bind multiple ISRs to the same interrupt.
       
    81 However, this is not possible. There are two ways of dealing with this: </p> <ul>
       
    82 <li id="GUID-0D954444-C2C3-51CC-8E1D-7EB063CDACAA"><p>Maintain a list of all
       
    83 ISRs that are bound to this single interrupt source, and call all the ISRs
       
    84 in the list when the interrupt is dispatched. This is most conveniently implemented
       
    85 by binding a single ISR to the interrupt, which then calls all the real ISRs
       
    86 bound to this interrupt </p> </li>
       
    87 <li id="GUID-C5EFE907-26A5-568D-8CF0-DE5E89ED5CBB"><p>Create pseudo interrupts.
       
    88 These are extra interrupt IDs that do not exist in the interrupt controller,
       
    89 but represent each of the interrupt sources connected to the single shared
       
    90 interrupt source. An ISR can then be bound to each pseudo interrupt. The interrupt
       
    91 dispatcher can then determine which of the sources are actually signalling
       
    92 and call the appropriate ISR via that pseudo interrupt ID. This is effectively
       
    93 an implementation of a <xref href="GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita#GUID-76A30EC4-4B99-5471-9E80-F853C91485BC/GUID-9026A4AC-57AF-545D-887C-AF43E0B37EDC">chained
       
    94 interrupt</xref>, and assumes that the interrupt dispatcher can identify which
       
    95 of the sources is signalling. </p> </li>
       
    96 </ul> </section>
       
    97 <section id="GUID-A87DE0F9-2095-5CA6-BE88-3A2EAABB0D33"><title>Interrupts
       
    98 in the split ASSP/Variant Configuration</title> <p>When a common ASSP extension
       
    99 is used, a device may have additional peripherals external to the ASSP, and
       
   100 there needs to be a way of allowing extra interrupt binding and dispatch functions
       
   101 to be added later by the variant layer. This must be handled by the port as
       
   102 Symbian OS does not provide any additional API to support this. </p> <p>Device
       
   103 drivers should be able to use the <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita"><apiname>Interrupt</apiname></xref> class functions
       
   104 without having to know where the interrupt is actually implemented. This implies
       
   105 that all requests should go to the core implementation of functions like <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita#GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3/GUID-4E3CB472-3525-32F8-9BC4-8ECFEE931E7B"><apiname>Interrupt::Bind()</apiname></xref>, <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita#GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3/GUID-BB169E6E-D8F9-3762-899D-6DBA4B29CF87"><apiname>Interrupt::Enable()</apiname></xref> etc. </p> <p>To enable the core implementation of these functions to decide
       
   106 whether an interrupt ID refers to a core interrupt or device specific interrupt,
       
   107 a common technique is to "tag" the interrupt ID. A simple way is to use positive
       
   108 numbers to identify core interrupts and negative numbers to identify device
       
   109 specific interrupts. The ISRs for device specific interrupts are not stored
       
   110 in the core ISR table, instead the device specific layer provides its own
       
   111 ISR table. </p> <p>The general pattern for creating the core-device specific
       
   112 split is that the core derives an implementation from class <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita"><apiname>Asic</apiname></xref>,
       
   113 and the device specific part further derives from this core implementation.
       
   114 The usual technique is to add a set of virtual functions to the core class
       
   115 that can be derived by the device specific part. The core can provide default
       
   116 implementations for these functions that would just return <xref href="GUID-0BEA3647-7888-3612-A2D3-7E27AC405E29.dita"><apiname>KErrArgument</apiname></xref> to
       
   117 trap illegal ID numbers. This API would need functions equivalent to each
       
   118 of the functions defined by the <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita"><apiname>Interrupt</apiname></xref> class. </p> <p>As
       
   119 an example, the core layer for the template reference board defines a class <codeph>TemplateAssp</codeph> that
       
   120 is derived from <xref href="GUID-A83A7C3C-7DC0-3B9C-842F-70FCC751365D.dita"><apiname>Asic</apiname></xref>. <codeph>TemplateAssp</codeph> defines
       
   121 the pure virtual functions: <codeph>InterruptBind()</codeph>, <codeph>InterruptUnbind()</codeph>, <codeph>InterruptEnable()</codeph> etc,
       
   122 all with signatures that are the same for the comparable functions defined
       
   123 by <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita"><apiname>Interrupt</apiname></xref>, and which are implemented by the <codeph>Template</codeph> class. </p> <fig id="GUID-458C7825-5B35-583C-BDF6-7DCD21DAE670">
       
   124 <image href="GUID-B7E7E6D6-7824-505C-BA0B-B7861897E78F_d0e365918_href.png" placement="inline"/>
       
   125 </fig> </section>
       
   126 <section id="GUID-9D98586F-AD1D-5C50-9AD8-F81D72135382"><title>Spurious interrupts</title> <p>In
       
   127 the Kernel Architecture 2, it is a convention that unbound interrupts should
       
   128 be bound to a "spurious" interrupt handler, i.e. an interrupt handler that
       
   129 faults the system indicating the number of the interrupt. This aids debugging
       
   130 by identifying interrupts that are enabled without corresponding ISRs. </p> </section>
       
   131 <section id="GUID-109C6250-DC5B-48EC-B1A0-24E2E9731B38"><title>Interrupt priority</title> <p>The interrupt architecture supports
       
   132 the concept of adjustable interrupt priorities. Symbian platform defines the <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita#GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3/GUID-FA4CFED7-D694-399C-8F84-FA9FE3C3A171"><apiname>Interrupt::SetPriority()</apiname></xref> function
       
   133 that can implement this. The function is passed the ID of the interrupt source
       
   134 to be adjusted together with a priority value. The meaning of the priority
       
   135 value is hardware and implementation dependent, and is defined by the port. </p> </section>
       
   136 <section id="GUID-77E83634-BBF6-5190-9434-9FB700547CD0"><title>The ISR table</title> <p>The
       
   137 Variant must provide a table where each entry defines which <xref href="GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita#GUID-76A30EC4-4B99-5471-9E80-F853C91485BC/GUID-1FAA26F5-BFB2-55A0-977C-1538EBF3C82A">ISR</xref> is bound to which interrupt source. The table must have enough
       
   138 space for entries for each interrupt source that is known to the Variant. </p> <p>When
       
   139 the Variant is split into an ASSP layer and a Variant layer, the ISR table
       
   140 is put in the ASSP layer and will not normally include ISRs for the Variant
       
   141 interrupt sources - these will be handled by separate chained dispatchers
       
   142 in the Variant layer. </p> <p>Symbian platform provides the <xref href="GUID-2C9B6510-D045-3FA1-AD65-B544E30D34C7.dita"><apiname>SInterruptHandler</apiname></xref> structure,
       
   143 defined in the header file <filepath>...\e32\include\kernel\arm\assp.h</filepath> to
       
   144 encapsulate the entry for an ISR. The ISR table is, therefore, just an array
       
   145 of <xref href="GUID-2C9B6510-D045-3FA1-AD65-B544E30D34C7.dita"><apiname>SInterruptHandler</apiname></xref> items. For example, if a system has
       
   146 32 possible interrupt sources, then the ISR table would be defined as: </p> <codeblock id="GUID-6C95C2EF-A882-565A-8718-07BF7E4A7AC5" xml:space="preserve">...
       
   147 const TInt KInterruptSourceCount = 32;
       
   148 SInterruptHandler IsrHandlers[KInterruptSourceCount];
       
   149 ...</codeblock> <p>Interrupts are identified in the system by their interrupt
       
   150 ID number, which is used to index into the ISR table. You are free to allocate
       
   151 these numbers any way that is convenient for you. </p> <p>On the template
       
   152 reference board, for example, the ISR table is defined as a static data member
       
   153 of the <codeph>VariantASSPInterrupt</codeph> class, which is derived from <xref href="GUID-5E593C59-BA22-3B70-AAFB-BFE19E22538A.dita"><apiname>TemplateInterrupt</apiname></xref>.
       
   154 The class is defined in <filepath>...\template_assp\template_assp_priv.h</filepath>. </p> <codeblock id="GUID-59D7A629-353C-5117-84B7-15CD425481C6" xml:space="preserve">class TemplateInterrupt : public Interrupt
       
   155     {
       
   156     ... // functions
       
   157 public:
       
   158     static SInterruptHandler Handlers[KNumTemplateInts];
       
   159     ...
       
   160     };</codeblock> <p>where KNumTemplateInts is defined in the same header
       
   161 file. </p> <p><b>Factors
       
   162 that decide the size of the ISR table</b> </p> <p>The number of entries to
       
   163 be reserved in the ISR table depends on the following factors: </p> <ul>
       
   164 <li id="GUID-05AE4B19-AA29-56E4-842A-CC65546EFB54"><p>Where the ASSP is targeted
       
   165 at only a single device, the number of possible interrupts is usually known,
       
   166 and the table can include an entry for each one. </p> </li>
       
   167 <li id="GUID-C62B31BD-FAD7-5A76-9E43-2387FD8AFCC8"><p>If any <xref href="GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita#GUID-76A30EC4-4B99-5471-9E80-F853C91485BC/GUID-ED6F2F47-7A16-5AE6-8E5B-B2475F6EDEAA">pseudo sources</xref> exist, they should be included in the main table for
       
   168 efficiency, but note that this is not strictly necessary. </p> </li>
       
   169 </ul> <p><b>Other
       
   170 factors affecting the ISR table</b> </p> <p>IRQs and FIQs may need to be distinguished,
       
   171 although the exact requirement is hardware dependent. Although the table has
       
   172 one entry for each possible interrupt source, a possible scheme may be to
       
   173 group IRQs at the start of the table, and FIQs at the end of the table. If
       
   174 the hardware has separate interrupt controller hardware for IRQs and FIQs
       
   175 (or at least, different registers) then you will need to arrange the table
       
   176 so that you can determine from the <xref href="GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita#GUID-76A30EC4-4B99-5471-9E80-F853C91485BC/GUID-8E58F4C9-0290-55E0-A4FD-B6C2361BE205">interrupt
       
   177 ID</xref> whether the interrupt is an IRQ or FIQ. </p> <p>For example: </p> <fig id="GUID-9DD2CC92-A5DB-5C78-A9A6-64402FF04FE2">
       
   178 <image href="GUID-60949ACD-AAA9-540E-85AE-BB173382D548_d0e366034_href.png" placement="inline"/>
       
   179 </fig> </section>
       
   180 <section id="GUID-EACCBDFD-46CD-4D67-B60C-D705867C9116"><title>Location of interrupt handling code</title> <p>Most of the
       
   181 interrupt dispatching code is implemented in the ASSP layer. This includes
       
   182 a list of ISRs, code for adding and removing ISRs, enabling and disabling
       
   183 interrupt sources, and dispatching ISRs. The kernel only provides a pre-amble
       
   184 and post-amble. </p> <p>The kernel defines, but does not implement, a class
       
   185 called <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita"><apiname>Interrupt</apiname></xref> that exports interrupt functionality to
       
   186 device drivers and other kernel code. The class provides the public API for
       
   187 using interrupts (but not for dispatching them). The port must provide an
       
   188 implementation for each function defined by the class. </p> <p>The class is
       
   189 defined in the header files <filepath>...\e32\include\kernel\arm\assp.h</filepath>,
       
   190 which is exported to <filepath>...\epoc32\include\kernel\arm</filepath>. </p><p>See
       
   191 Symbian OS Internals Book, Chapter 6  - Interrupts and Exceptions</p> </section>
       
   192 </conbody></concept>