1 |
1026 |
ivang |
@c
|
2 |
|
|
@c COPYRIGHT (c) 1988-2002.
|
3 |
|
|
@c On-Line Applications Research Corporation (OAR).
|
4 |
|
|
@c All rights reserved.
|
5 |
|
|
@c
|
6 |
|
|
@c intr.t,v 1.21 2002/03/28 02:26:44 joel Exp
|
7 |
|
|
@c
|
8 |
|
|
|
9 |
|
|
@chapter Interrupt Manager
|
10 |
|
|
|
11 |
|
|
@section Introduction
|
12 |
|
|
|
13 |
|
|
Any real-time executive must provide a mechanism for
|
14 |
|
|
quick response to externally generated interrupts to satisfy the
|
15 |
|
|
critical time constraints of the application. The interrupt
|
16 |
|
|
manager provides this mechanism for RTEMS. This manager permits
|
17 |
|
|
quick interrupt response times by providing the critical ability
|
18 |
|
|
to alter task execution which allows a task to be preempted upon
|
19 |
|
|
exit from an ISR. The interrupt manager includes the following
|
20 |
|
|
directive:
|
21 |
|
|
|
22 |
|
|
@itemize @bullet
|
23 |
|
|
@item @code{@value{DIRPREFIX}interrupt_catch} - Establish an ISR
|
24 |
|
|
@item @code{@value{DIRPREFIX}interrupt_disable} - Disable Interrupts
|
25 |
|
|
@item @code{@value{DIRPREFIX}interrupt_enable} - Enable Interrupts
|
26 |
|
|
@item @code{@value{DIRPREFIX}interrupt_flash} - Flash Interrupt
|
27 |
|
|
@item @code{@value{DIRPREFIX}interrupt_is_in_progress} - Is an ISR in Progress
|
28 |
|
|
@end itemize
|
29 |
|
|
|
30 |
|
|
@section Background
|
31 |
|
|
|
32 |
|
|
@subsection Processing an Interrupt
|
33 |
|
|
|
34 |
|
|
@cindex interrupt processing
|
35 |
|
|
|
36 |
|
|
The interrupt manager allows the application to
|
37 |
|
|
connect a function to a hardware interrupt vector. When an
|
38 |
|
|
interrupt occurs, the processor will automatically vector to
|
39 |
|
|
RTEMS. RTEMS saves and restores all registers which are not
|
40 |
|
|
preserved by the normal @value{LANGUAGE} calling convention
|
41 |
|
|
for the target
|
42 |
|
|
processor and invokes the user's ISR. The user's ISR is
|
43 |
|
|
responsible for processing the interrupt, clearing the interrupt
|
44 |
|
|
if necessary, and device specific manipulation.
|
45 |
|
|
|
46 |
|
|
@findex rtems_vector_number
|
47 |
|
|
|
48 |
|
|
The @code{@value{DIRPREFIX}interrupt_catch}
|
49 |
|
|
directive connects a procedure to
|
50 |
|
|
an interrupt vector. The vector number is managed using
|
51 |
|
|
the @code{@value{DIRPREFIX}vector_number} data type.
|
52 |
|
|
|
53 |
|
|
The interrupt service routine is assumed
|
54 |
|
|
to abide by these conventions and have a prototype similar to
|
55 |
|
|
the following:
|
56 |
|
|
|
57 |
|
|
@ifset is-C
|
58 |
|
|
@findex rtems_isr
|
59 |
|
|
|
60 |
|
|
@example
|
61 |
|
|
rtems_isr user_isr(
|
62 |
|
|
rtems_vector_number vector
|
63 |
|
|
);
|
64 |
|
|
@end example
|
65 |
|
|
@end ifset
|
66 |
|
|
|
67 |
|
|
@ifset is-Ada
|
68 |
|
|
@example
|
69 |
|
|
procedure User_ISR (
|
70 |
|
|
vector : in RTEMS.Vector_Number
|
71 |
|
|
);
|
72 |
|
|
@end example
|
73 |
|
|
@end ifset
|
74 |
|
|
|
75 |
|
|
The vector number argument is provided by RTEMS to
|
76 |
|
|
allow the application to identify the interrupt source. This
|
77 |
|
|
could be used to allow a single routine to service interrupts
|
78 |
|
|
from multiple instances of the same device. For example, a
|
79 |
|
|
single routine could service interrupts from multiple serial
|
80 |
|
|
ports and use the vector number to identify which port requires
|
81 |
|
|
servicing.
|
82 |
|
|
|
83 |
|
|
To minimize the masking of lower or equal priority
|
84 |
|
|
level interrupts, the ISR should perform the minimum actions
|
85 |
|
|
required to service the interrupt. Other non-essential actions
|
86 |
|
|
should be handled by application tasks. Once the user's ISR has
|
87 |
|
|
completed, it returns control to the RTEMS interrupt manager
|
88 |
|
|
which will perform task dispatching and restore the registers
|
89 |
|
|
saved before the ISR was invoked.
|
90 |
|
|
|
91 |
|
|
The RTEMS interrupt manager guarantees that proper
|
92 |
|
|
task scheduling and dispatching are performed at the conclusion
|
93 |
|
|
of an ISR. A system call made by the ISR may have readied a
|
94 |
|
|
task of higher priority than the interrupted task. Therefore,
|
95 |
|
|
when the ISR completes, the postponed dispatch processing must
|
96 |
|
|
be performed. No dispatch processing is performed as part of
|
97 |
|
|
directives which have been invoked by an ISR.
|
98 |
|
|
|
99 |
|
|
Applications must adhere to the following rule if
|
100 |
|
|
proper task scheduling and dispatching is to be performed:
|
101 |
|
|
|
102 |
|
|
@itemize @b{ }
|
103 |
|
|
|
104 |
|
|
@item @b{The interrupt manager must be used for all ISRs which
|
105 |
|
|
may be interrupted by the highest priority ISR which invokes an
|
106 |
|
|
RTEMS directive.}
|
107 |
|
|
|
108 |
|
|
@end itemize
|
109 |
|
|
|
110 |
|
|
Consider a processor which allows a numerically low
|
111 |
|
|
interrupt level to interrupt a numerically greater interrupt
|
112 |
|
|
level. In this example, if an RTEMS directive is used in a
|
113 |
|
|
level 4 ISR, then all ISRs which execute at levels 0 through 4
|
114 |
|
|
must use the interrupt manager.
|
115 |
|
|
|
116 |
|
|
Interrupts are nested whenever an interrupt occurs
|
117 |
|
|
during the execution of another ISR. RTEMS supports efficient
|
118 |
|
|
interrupt nesting by allowing the nested ISRs to terminate
|
119 |
|
|
without performing any dispatch processing. Only when the
|
120 |
|
|
outermost ISR terminates will the postponed dispatching occur.
|
121 |
|
|
|
122 |
|
|
@subsection RTEMS Interrupt Levels
|
123 |
|
|
|
124 |
|
|
@cindex interrupt levels
|
125 |
|
|
|
126 |
|
|
Many processors support multiple interrupt levels or
|
127 |
|
|
priorities. The exact number of interrupt levels is processor
|
128 |
|
|
dependent. RTEMS internally supports 256 interrupt levels which
|
129 |
|
|
are mapped to the processor's interrupt levels. For specific
|
130 |
|
|
information on the mapping between RTEMS and the target
|
131 |
|
|
processor's interrupt levels, refer to the Interrupt Processing
|
132 |
|
|
chapter of the Applications Supplement document for a specific
|
133 |
|
|
target processor.
|
134 |
|
|
|
135 |
|
|
@subsection Disabling of Interrupts by RTEMS
|
136 |
|
|
|
137 |
|
|
@cindex disabling interrupts
|
138 |
|
|
|
139 |
|
|
During the execution of directive calls, critical
|
140 |
|
|
sections of code may be executed. When these sections are
|
141 |
|
|
encountered, RTEMS disables all maskable interrupts before the
|
142 |
|
|
execution of the section and restores them to the previous level
|
143 |
|
|
upon completion of the section. RTEMS has been optimized to
|
144 |
|
|
insure that interrupts are disabled for a minimum length of
|
145 |
|
|
time. The maximum length of time interrupts are disabled by
|
146 |
|
|
RTEMS is processor dependent and is detailed in the Timing
|
147 |
|
|
Specification chapter of the Applications Supplement document
|
148 |
|
|
for a specific target processor.
|
149 |
|
|
|
150 |
|
|
Non-maskable interrupts (NMI) cannot be disabled, and
|
151 |
|
|
ISRs which execute at this level MUST NEVER issue RTEMS system
|
152 |
|
|
calls. If a directive is invoked, unpredictable results may
|
153 |
|
|
occur due to the inability of RTEMS to protect its critical
|
154 |
|
|
sections. However, ISRs that make no system calls may safely
|
155 |
|
|
execute as non-maskable interrupts.
|
156 |
|
|
|
157 |
|
|
@section Operations
|
158 |
|
|
|
159 |
|
|
@subsection Establishing an ISR
|
160 |
|
|
|
161 |
|
|
The @code{@value{DIRPREFIX}interrupt_catch}
|
162 |
|
|
directive establishes an ISR for
|
163 |
|
|
the system. The address of the ISR and its associated CPU
|
164 |
|
|
vector number are specified to this directive. This directive
|
165 |
|
|
installs the RTEMS interrupt wrapper in the processor's
|
166 |
|
|
Interrupt Vector Table and the address of the user's ISR in the
|
167 |
|
|
RTEMS' Vector Table. This directive returns the previous
|
168 |
|
|
contents of the specified vector in the RTEMS' Vector Table.
|
169 |
|
|
|
170 |
|
|
@subsection Directives Allowed from an ISR
|
171 |
|
|
|
172 |
|
|
Using the interrupt manager insures that RTEMS knows
|
173 |
|
|
when a directive is being called from an ISR. The ISR may then
|
174 |
|
|
use system calls to synchronize itself with an application task.
|
175 |
|
|
The synchronization may involve messages, events or signals
|
176 |
|
|
being passed by the ISR to the desired task. Directives invoked
|
177 |
|
|
by an ISR must operate only on objects which reside on the local
|
178 |
|
|
node. The following is a list of RTEMS system calls that may be
|
179 |
|
|
made from an ISR:
|
180 |
|
|
|
181 |
|
|
@itemize @bullet
|
182 |
|
|
@item Task Management
|
183 |
|
|
|
184 |
|
|
@itemize -
|
185 |
|
|
@item task_get_note, task_set_note, task_suspend, task_resume
|
186 |
|
|
@end itemize
|
187 |
|
|
|
188 |
|
|
@item Clock Management
|
189 |
|
|
|
190 |
|
|
@itemize -
|
191 |
|
|
@item clock_get, clock_tick
|
192 |
|
|
@end itemize
|
193 |
|
|
|
194 |
|
|
@item Message, Event, and Signal Management
|
195 |
|
|
|
196 |
|
|
@itemize -
|
197 |
|
|
@item message_queue_send, message_queue_urgent
|
198 |
|
|
@item event_send
|
199 |
|
|
@item signal_send
|
200 |
|
|
@end itemize
|
201 |
|
|
|
202 |
|
|
@item Semaphore Management
|
203 |
|
|
|
204 |
|
|
@itemize -
|
205 |
|
|
@item semaphore_release
|
206 |
|
|
@end itemize
|
207 |
|
|
|
208 |
|
|
@item Dual-Ported Memory Management
|
209 |
|
|
|
210 |
|
|
@itemize -
|
211 |
|
|
@item port_external_to_internal, port_internal_to_external
|
212 |
|
|
@end itemize
|
213 |
|
|
|
214 |
|
|
@item IO Management
|
215 |
|
|
|
216 |
|
|
@itemize -
|
217 |
|
|
@item io_initialize, io_open, io_close, io_read, io_write, io_control
|
218 |
|
|
@end itemize
|
219 |
|
|
|
220 |
|
|
@item Fatal Error Management
|
221 |
|
|
|
222 |
|
|
@itemize -
|
223 |
|
|
@item fatal_error_occurred
|
224 |
|
|
@end itemize
|
225 |
|
|
|
226 |
|
|
@item Multiprocessing
|
227 |
|
|
|
228 |
|
|
@itemize -
|
229 |
|
|
@item multiprocessing_announce
|
230 |
|
|
@end itemize
|
231 |
|
|
@end itemize
|
232 |
|
|
|
233 |
|
|
@section Directives
|
234 |
|
|
|
235 |
|
|
This section details the interrupt manager's
|
236 |
|
|
directives. A subsection is dedicated to each of this manager's
|
237 |
|
|
directives and describes the calling sequence, related
|
238 |
|
|
constants, usage, and status codes.
|
239 |
|
|
|
240 |
|
|
@c
|
241 |
|
|
@c
|
242 |
|
|
@c
|
243 |
|
|
@page
|
244 |
|
|
@subsection INTERRUPT_CATCH - Establish an ISR
|
245 |
|
|
|
246 |
|
|
@cindex establish an ISR
|
247 |
|
|
@cindex install an ISR
|
248 |
|
|
|
249 |
|
|
@subheading CALLING SEQUENCE:
|
250 |
|
|
|
251 |
|
|
@ifset is-C
|
252 |
|
|
@findex rtems_interrupt_catch
|
253 |
|
|
@example
|
254 |
|
|
rtems_status_code rtems_interrupt_catch(
|
255 |
|
|
rtems_isr_entry new_isr_handler,
|
256 |
|
|
rtems_vector_number vector,
|
257 |
|
|
rtems_isr_entry *old_isr_handler
|
258 |
|
|
);
|
259 |
|
|
@end example
|
260 |
|
|
@end ifset
|
261 |
|
|
|
262 |
|
|
@ifset is-Ada
|
263 |
|
|
@example
|
264 |
|
|
procedure Interrupt_Catch (
|
265 |
|
|
New_ISR_handler : in RTEMS.Address;
|
266 |
|
|
Vector : in RTEMS.Vector_Number;
|
267 |
|
|
Old_ISR_Handler : out RTEMS.Address;
|
268 |
|
|
Result : out RTEMS.Status_Codes
|
269 |
|
|
);
|
270 |
|
|
@end example
|
271 |
|
|
@end ifset
|
272 |
|
|
|
273 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
274 |
|
|
@code{@value{RPREFIX}SUCCESSFUL} - ISR established successfully@*
|
275 |
|
|
@code{@value{RPREFIX}INVALID_NUMBER} - illegal vector number@*
|
276 |
|
|
@code{@value{RPREFIX}INVALID_ADDRESS} - illegal ISR entry point or invalid @code{old_isr_handler}
|
277 |
|
|
|
278 |
|
|
@subheading DESCRIPTION:
|
279 |
|
|
|
280 |
|
|
This directive establishes an interrupt service
|
281 |
|
|
routine (ISR) for the specified interrupt vector number. The
|
282 |
|
|
@code{new_isr_handler} parameter specifies the entry point of the ISR.
|
283 |
|
|
The entry point of the previous ISR for the specified vector is
|
284 |
|
|
returned in @code{old_isr_handler}.
|
285 |
|
|
|
286 |
|
|
To release an interrupt vector, pass the old handler's address obtained
|
287 |
|
|
when the vector was first capture.
|
288 |
|
|
|
289 |
|
|
@subheading NOTES:
|
290 |
|
|
|
291 |
|
|
This directive will not cause the calling task to be preempted.
|
292 |
|
|
|
293 |
|
|
@c
|
294 |
|
|
@c
|
295 |
|
|
@c
|
296 |
|
|
@page
|
297 |
|
|
@subsection INTERRUPT_DISABLE - Disable Interrupts
|
298 |
|
|
|
299 |
|
|
@cindex disable interrupts
|
300 |
|
|
|
301 |
|
|
@subheading CALLING SEQUENCE:
|
302 |
|
|
|
303 |
|
|
@ifset is-C
|
304 |
|
|
@findex rtems_interrupt_disable
|
305 |
|
|
@example
|
306 |
|
|
void rtems_interrupt_disable(
|
307 |
|
|
rtems_interrupt_level level
|
308 |
|
|
);
|
309 |
|
|
|
310 |
|
|
/* this is implemented as a macro and sets level as a side-effect */
|
311 |
|
|
@end example
|
312 |
|
|
@end ifset
|
313 |
|
|
|
314 |
|
|
@ifset is-Ada
|
315 |
|
|
@example
|
316 |
|
|
function Interrupt_Disable
|
317 |
|
|
return RTEMS.ISR_Level;
|
318 |
|
|
@end example
|
319 |
|
|
@end ifset
|
320 |
|
|
|
321 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
322 |
|
|
|
323 |
|
|
NONE
|
324 |
|
|
|
325 |
|
|
@subheading DESCRIPTION:
|
326 |
|
|
|
327 |
|
|
This directive disables all maskable interrupts and returns
|
328 |
|
|
the previous @code{level}. A later invocation of the
|
329 |
|
|
@code{@value{DIRPREFIX}interrupt_enable} directive should be used to
|
330 |
|
|
restore the interrupt level.
|
331 |
|
|
|
332 |
|
|
@subheading NOTES:
|
333 |
|
|
|
334 |
|
|
This directive will not cause the calling task to be preempted.
|
335 |
|
|
|
336 |
|
|
@ifset is-C
|
337 |
|
|
@b{This directive is implemented as a macro which modifies the @code{level}
|
338 |
|
|
parameter.}
|
339 |
|
|
@end ifset
|
340 |
|
|
|
341 |
|
|
@c
|
342 |
|
|
@c
|
343 |
|
|
@c
|
344 |
|
|
@page
|
345 |
|
|
@subsection INTERRUPT_ENABLE - Enable Interrupts
|
346 |
|
|
|
347 |
|
|
@cindex enable interrupts
|
348 |
|
|
|
349 |
|
|
@subheading CALLING SEQUENCE:
|
350 |
|
|
|
351 |
|
|
@ifset is-C
|
352 |
|
|
@findex rtems_interrupt_enable
|
353 |
|
|
@example
|
354 |
|
|
void rtems_interrupt_enable(
|
355 |
|
|
rtems_interrupt_level level
|
356 |
|
|
);
|
357 |
|
|
@end example
|
358 |
|
|
@end ifset
|
359 |
|
|
|
360 |
|
|
@ifset is-Ada
|
361 |
|
|
@example
|
362 |
|
|
procedure Interrupt_Enable (
|
363 |
|
|
Level : in RTEMS.ISR_Level
|
364 |
|
|
);
|
365 |
|
|
@end example
|
366 |
|
|
@end ifset
|
367 |
|
|
|
368 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
369 |
|
|
|
370 |
|
|
NONE
|
371 |
|
|
|
372 |
|
|
@subheading DESCRIPTION:
|
373 |
|
|
|
374 |
|
|
This directive enables maskable interrupts to the @code{level}
|
375 |
|
|
which was returned by a previous call to
|
376 |
|
|
@code{@value{DIRPREFIX}interrupt_disable}.
|
377 |
|
|
Immediately prior to invoking this directive, maskable interrupts should
|
378 |
|
|
be disabled by a call to @code{@value{DIRPREFIX}interrupt_disable}
|
379 |
|
|
and will be enabled when this directive returns to the caller.
|
380 |
|
|
|
381 |
|
|
@subheading NOTES:
|
382 |
|
|
|
383 |
|
|
This directive will not cause the calling task to be preempted.
|
384 |
|
|
|
385 |
|
|
|
386 |
|
|
@c
|
387 |
|
|
@c
|
388 |
|
|
@c
|
389 |
|
|
@page
|
390 |
|
|
@subsection INTERRUPT_FLASH - Flash Interrupts
|
391 |
|
|
|
392 |
|
|
@cindex flash interrupts
|
393 |
|
|
|
394 |
|
|
@subheading CALLING SEQUENCE:
|
395 |
|
|
|
396 |
|
|
@ifset is-C
|
397 |
|
|
@findex rtems_interrupt_flash
|
398 |
|
|
@example
|
399 |
|
|
void rtems_interrupt_flash(
|
400 |
|
|
rtems_interrupt_level level
|
401 |
|
|
);
|
402 |
|
|
@end example
|
403 |
|
|
@end ifset
|
404 |
|
|
|
405 |
|
|
@ifset is-Ada
|
406 |
|
|
@example
|
407 |
|
|
procedure Interrupt_Flash (
|
408 |
|
|
Level : in RTEMS.ISR_Level
|
409 |
|
|
);
|
410 |
|
|
@end example
|
411 |
|
|
@end ifset
|
412 |
|
|
|
413 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
414 |
|
|
|
415 |
|
|
NONE
|
416 |
|
|
|
417 |
|
|
@subheading DESCRIPTION:
|
418 |
|
|
|
419 |
|
|
This directive temporarily enables maskable interrupts to the @code{level}
|
420 |
|
|
which was returned by a previous call to
|
421 |
|
|
@code{@value{DIRPREFIX}interrupt_disable}.
|
422 |
|
|
Immediately prior to invoking this directive, maskable interrupts should
|
423 |
|
|
be disabled by a call to @code{@value{DIRPREFIX}interrupt_disable}
|
424 |
|
|
and will be redisabled when this directive returns to the caller.
|
425 |
|
|
|
426 |
|
|
@subheading NOTES:
|
427 |
|
|
|
428 |
|
|
This directive will not cause the calling task to be preempted.
|
429 |
|
|
|
430 |
|
|
@c
|
431 |
|
|
@c
|
432 |
|
|
@c
|
433 |
|
|
@page
|
434 |
|
|
@subsection INTERRUPT_IS_IN_PROGRESS - Is an ISR in Progress
|
435 |
|
|
|
436 |
|
|
@cindex is interrupt in progress
|
437 |
|
|
|
438 |
|
|
@subheading CALLING SEQUENCE:
|
439 |
|
|
|
440 |
|
|
@ifset is-C
|
441 |
|
|
@findex rtems_interrupt_is_in_progress
|
442 |
|
|
@example
|
443 |
|
|
rtems_boolean rtems_interrupt_is_in_progress( void );
|
444 |
|
|
@end example
|
445 |
|
|
@end ifset
|
446 |
|
|
|
447 |
|
|
@ifset is-Ada
|
448 |
|
|
@example
|
449 |
|
|
function Interrupt_Is_In_Progress
|
450 |
|
|
return RTEMS.Boolean;
|
451 |
|
|
@end example
|
452 |
|
|
@end ifset
|
453 |
|
|
|
454 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
455 |
|
|
|
456 |
|
|
NONE
|
457 |
|
|
|
458 |
|
|
@subheading DESCRIPTION:
|
459 |
|
|
|
460 |
|
|
This directive returns @code{TRUE} if the processor is currently
|
461 |
|
|
servicing an interrupt and @code{FALSE} otherwise. A return value
|
462 |
|
|
of @code{TRUE} indicates that the caller is an interrupt service
|
463 |
|
|
routine, @b{NOT} a task. The directives available to an interrupt
|
464 |
|
|
service routine are restricted.
|
465 |
|
|
|
466 |
|
|
@subheading NOTES:
|
467 |
|
|
|
468 |
|
|
This directive will not cause the calling task to be preempted.
|
469 |
|
|
|