42 unbound during normal operation, but only one ISR can be bound to an interrupt |
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>, |
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 |
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 |
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> |
46 ID</xref>. </p> </section> |
47 <section id="GUID-DDA62ABB-9CC6-44DC-B08D-FEE5AC505858"><title>Dispatching interrupts</title> <p>At its simplest, this is |
47 <section id="GUID-DDA62ABB-9CC6-44DC-B08D-FEE5AC505858"><title>Dispatching |
48 the process of deciding which interrupts are pending and calling the ISR for |
48 interrupts</title> <p>At its simplest, this is the process of deciding which |
49 each. </p> <p>The following pseudo code shows the general principle: </p> <codeblock id="GUID-9C971C66-BB26-5A07-9373-3542B95A16FD" xml:space="preserve"> |
49 interrupts are pending and calling the ISR for each. </p> <p>The following |
|
50 pseudo code shows the general principle: </p> <codeblock id="GUID-9C971C66-BB26-5A07-9373-3542B95A16FD" xml:space="preserve"> |
50 { |
51 { |
51 FOREVER |
52 FOREVER |
52 { |
53 { |
53 Get next pending interrupt; |
54 Get next pending interrupt; |
54 if None |
55 if None |
63 <section id="GUID-9026A4AC-57AF-545D-887C-AF43E0B37EDC"><title>Chained interrupts</title> <p>A |
64 <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 system may have multiple interrupt controllers to handle a large number of |
65 interrupt sources. These are usually prioritised by connecting the interrupt |
66 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 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 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 <image href="GUID-0DB79535-E4E6-50BD-852D-B2F177202C9C_d0e387035_href.png" placement="inline"/> |
69 </fig> <p>An interrupt from a lower priority controller will appear as an |
70 </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 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 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 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 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 may be further levels of chaining before the true source of the interrupt |
75 has been identified. </p> </section> |
76 has been identified. </p> </section> |
76 <section id="GUID-ED6F2F47-7A16-5AE6-8E5B-B2475F6EDEAA"><title>Multiple interrupt |
77 <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 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 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 <image href="GUID-DCBBDFA7-1E6C-5B00-A13E-A25794668E12_d0e387057_href.png" placement="inline"/> |
80 </fig> <p>It appears necessary to bind multiple ISRs to the same interrupt. |
81 </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 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 <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 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 in the list when the interrupt is dispatched. This is most conveniently implemented |
97 <section id="GUID-A87DE0F9-2095-5CA6-BE88-3A2EAABB0D33"><title>Interrupts |
98 <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 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 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 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 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 Symbian platform 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 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 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 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 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 a common technique is to "tag" the interrupt ID. A simple way is to use positive |
119 an example, the core layer for the template reference board defines a class <codeph>TemplateAssp</codeph> that |
120 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 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 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 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 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 <image href="GUID-B7E7E6D6-7824-505C-BA0B-B7861897E78F_d0e387151_href.png" placement="inline"/> |
125 </fig> </section> |
126 </fig> </section> |
126 <section id="GUID-9D98586F-AD1D-5C50-9AD8-F81D72135382"><title>Spurious interrupts</title> <p>In |
127 <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 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 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 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 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 <section id="GUID-109C6250-DC5B-48EC-B1A0-24E2E9731B38"><title>Interrupt priority</title> <p>The |
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 interrupt architecture supports the concept of adjustable interrupt priorities. |
|
134 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 |
135 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 |
136 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> |
137 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 |
138 <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 |
139 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 |
173 group IRQs at the start of the table, and FIQs at the end of the table. If |
175 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 |
176 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 |
177 (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 |
178 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"> |
179 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"/> |
180 <image href="GUID-60949ACD-AAA9-540E-85AE-BB173382D548_d0e387267_href.png" placement="inline"/> |
179 </fig> </section> |
181 </fig> </section> |
180 <section id="GUID-EACCBDFD-46CD-4D67-B60C-D705867C9116"><title>Location of interrupt handling code</title> <p>Most of the |
182 <section id="GUID-EACCBDFD-46CD-4D67-B60C-D705867C9116"><title>Location of |
181 interrupt dispatching code is implemented in the ASSP layer. This includes |
183 interrupt handling code</title> <p>Most of the interrupt dispatching code |
182 a list of ISRs, code for adding and removing ISRs, enabling and disabling |
184 is implemented in the ASSP layer. This includes a list of ISRs, code for adding |
183 interrupt sources, and dispatching ISRs. The kernel only provides a pre-amble |
185 and removing ISRs, enabling and disabling interrupt sources, and dispatching |
184 and post-amble. </p> <p>The kernel defines, but does not implement, a class |
186 ISRs. The kernel only provides a pre-amble and post-amble. </p> <p>The kernel |
185 called <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita"><apiname>Interrupt</apiname></xref> that exports interrupt functionality to |
187 defines, but does not implement, a class called <xref href="GUID-E7A7083C-97B9-39B9-A147-4A6E314EE3A3.dita"><apiname>Interrupt</apiname></xref> that |
186 device drivers and other kernel code. The class provides the public API for |
188 exports interrupt functionality to device drivers and other kernel code. The |
187 using interrupts (but not for dispatching them). The port must provide an |
189 class provides the public API for using interrupts (but not for dispatching |
188 implementation for each function defined by the class. </p> <p>The class is |
190 them). The port must provide an implementation for each function defined by |
189 defined in the header files <filepath>...\e32\include\kernel\arm\assp.h</filepath>, |
191 the class. </p> <p>The class is 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 |
192 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> |
193 Symbian OS Internals Book, Chapter 6 - Interrupts and Exceptions</p> </section> |
192 </conbody></concept> |
194 </conbody></concept> |