]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - doc/html/ref/hal-interrupt-handling.html
Initial revision
[karo-tx-redboot.git] / doc / html / ref / hal-interrupt-handling.html
1 <!-- Copyright (C) 2003 Red Hat, Inc.                                -->
2 <!-- This material may be distributed only subject to the terms      -->
3 <!-- and conditions set forth in the Open Publication License, v1.0  -->
4 <!-- or later (the latest version is presently available at          -->
5 <!-- http://www.opencontent.org/openpub/).                           -->
6 <!-- Distribution of the work or derivative of the work in any       -->
7 <!-- standard (paper) book form is prohibited unless prior           -->
8 <!-- permission is obtained from the copyright holder.               -->
9 <HTML
10 ><HEAD
11 ><TITLE
12 >Interrupt Handling</TITLE
13 ><meta name="MSSmartTagsPreventParsing" content="TRUE">
14 <META
15 NAME="GENERATOR"
16 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
17 "><LINK
18 REL="HOME"
19 TITLE="eCos Reference Manual"
20 HREF="ecos-ref.html"><LINK
21 REL="UP"
22 TITLE="HAL Interfaces"
23 HREF="hal-interfaces.html"><LINK
24 REL="PREVIOUS"
25 TITLE="Architecture Characterization"
26 HREF="hal-architecture-characterization.html"><LINK
27 REL="NEXT"
28 TITLE="HAL I/O"
29 HREF="hal-input-and-output.html"></HEAD
30 ><BODY
31 CLASS="SECTION"
32 BGCOLOR="#FFFFFF"
33 TEXT="#000000"
34 LINK="#0000FF"
35 VLINK="#840084"
36 ALINK="#0000FF"
37 ><DIV
38 CLASS="NAVHEADER"
39 ><TABLE
40 SUMMARY="Header navigation table"
41 WIDTH="100%"
42 BORDER="0"
43 CELLPADDING="0"
44 CELLSPACING="0"
45 ><TR
46 ><TH
47 COLSPAN="3"
48 ALIGN="center"
49 >eCos Reference Manual</TH
50 ></TR
51 ><TR
52 ><TD
53 WIDTH="10%"
54 ALIGN="left"
55 VALIGN="bottom"
56 ><A
57 HREF="hal-architecture-characterization.html"
58 ACCESSKEY="P"
59 >Prev</A
60 ></TD
61 ><TD
62 WIDTH="80%"
63 ALIGN="center"
64 VALIGN="bottom"
65 >Chapter 9. HAL Interfaces</TD
66 ><TD
67 WIDTH="10%"
68 ALIGN="right"
69 VALIGN="bottom"
70 ><A
71 HREF="hal-input-and-output.html"
72 ACCESSKEY="N"
73 >Next</A
74 ></TD
75 ></TR
76 ></TABLE
77 ><HR
78 ALIGN="LEFT"
79 WIDTH="100%"></DIV
80 ><DIV
81 CLASS="SECTION"
82 ><H1
83 CLASS="SECTION"
84 ><A
85 NAME="HAL-INTERRUPT-HANDLING">Interrupt Handling</H1
86 ><P
87 >These interfaces contain definitions related to interrupt
88 handling. They include definitions of exception and interrupt numbers,
89 interrupt enabling and masking, and realtime clock operations.</P
90 ><P
91 >These definitions are normally found in
92 <TT
93 CLASS="FILENAME"
94 >cyg/hal/hal_intr.h</TT
95 >.  This file is supplied by the
96 architecture HAL.  Any variant or platform specific definitions will
97 be found in <TT
98 CLASS="FILENAME"
99 >cyg/hal/var_intr.h</TT
100 >,
101 <TT
102 CLASS="FILENAME"
103 >cyg/hal/plf_intr.h</TT
104 > or
105 <TT
106 CLASS="FILENAME"
107 >cyg/hal/hal_platform_ints.h</TT
108 > in the variant or platform
109 HAL, depending on the exact target. These files are include
110 automatically by this header, so need not be included explicitly.</P
111 ><DIV
112 CLASS="SECTION"
113 ><H2
114 CLASS="SECTION"
115 ><A
116 NAME="AEN7921">Vector numbers</H2
117 ><TABLE
118 BORDER="5"
119 BGCOLOR="#E0E0F0"
120 WIDTH="70%"
121 ><TR
122 ><TD
123 ><PRE
124 CLASS="PROGRAMLISTING"
125 >CYGNUM_HAL_VECTOR_XXXX
126 CYGNUM_HAL_VSR_MIN
127 CYGNUM_HAL_VSR_MAX
128 CYGNUM_HAL_VSR_COUNT
129
130 CYGNUM_HAL_INTERRUPT_XXXX
131 CYGNUM_HAL_ISR_MIN
132 CYGNUM_HAL_ISR_MAX
133 CYGNUM_HAL_ISR_COUNT
134
135 CYGNUM_HAL_EXCEPTION_XXXX
136 CYGNUM_HAL_EXCEPTION_MIN
137 CYGNUM_HAL_EXCEPTION_MAX
138 CYGNUM_HAL_EXCEPTION_COUNT</PRE
139 ></TD
140 ></TR
141 ></TABLE
142 ><P
143 >All possible VSR, interrupt and exception vectors are specified here,
144 together with maximum and minimum values for range checking. While the
145 VSR and exception numbers will be defined in this file, the interrupt
146 numbers will normally be defined in the variant or platform HAL file
147 that is included by this header. </P
148 ><P
149 >There are two ranges of numbers, those for the vector service
150 routines and those for the interrupt service routines. The relationship
151 between these two ranges is undefined, and no equivalence should
152 be assumed if vectors from the two ranges coincide.</P
153 ><P
154 >The VSR vectors correspond to the set of exception vectors that can be
155 delivered by the CPU architecture, many of these will be internal
156 exception traps. The ISR vectors correspond to the set of external
157 interrupts that can be delivered and are usually determined by extra
158 decoding of the interrupt controller by the interrupt VSR.</P
159 ><P
160 >Where a CPU supports synchronous exceptions, the range of such
161 exceptions allowed are defined by <TT
162 CLASS="LITERAL"
163 >CYGNUM_HAL_EXCEPTION_MIN</TT
164 > and
165 <TT
166 CLASS="LITERAL"
167 >CYGNUM_HAL_EXCEPTION_MAX</TT
168 >. The
169 <TT
170 CLASS="LITERAL"
171 >CYGNUM_HAL_EXCEPTION_XXXX</TT
172 > definitions are
173 standard names used by target independent code to test for the
174 presence of particular exceptions in the architecture. The actual
175 exception numbers will normally correspond to the VSR exception
176 range. In future other exceptions generated by the system software
177 (such as stack overflow) may be added.</P
178 ><P
179 ><TT
180 CLASS="LITERAL"
181 >CYGNUM_HAL_ISR_COUNT</TT
182 >, <TT
183 CLASS="LITERAL"
184 >CYGNUM_HAL_VSR_COUNT</TT
185 > and
186 <TT
187 CLASS="LITERAL"
188 >CYGNUM_HAL_EXCEPTION_COUNT</TT
189 > define the number of
190 ISRs, VSRs and EXCEPTIONs respectively for the purposes of defining
191 arrays etc. There might be a translation from the supplied vector
192 numbers into array offsets. Hence
193 <TT
194 CLASS="LITERAL"
195 >CYGNUM_HAL_XXX_COUNT</TT
196 > may not simply be
197 <TT
198 CLASS="LITERAL"
199 >CYGNUM_HAL_XXX_MAX</TT
200 > - <TT
201 CLASS="LITERAL"
202 >CYGNUM_HAL_XXX_MIN</TT
203 > or <TT
204 CLASS="LITERAL"
205 >CYGNUM_HAL_XXX_MAX</TT
206 >&#0043;1.</P
207 ></DIV
208 ><DIV
209 CLASS="SECTION"
210 ><H2
211 CLASS="SECTION"
212 ><A
213 NAME="AEN7939">Interrupt state control</H2
214 ><TABLE
215 BORDER="5"
216 BGCOLOR="#E0E0F0"
217 WIDTH="70%"
218 ><TR
219 ><TD
220 ><PRE
221 CLASS="PROGRAMLISTING"
222 >CYG_INTERRUPT_STATE
223 HAL_DISABLE_INTERRUPTS( old )
224 HAL_RESTORE_INTERRUPTS( old )
225 HAL_ENABLE_INTERRUPTS()
226 HAL_QUERY_INTERRUPTS( state )</PRE
227 ></TD
228 ></TR
229 ></TABLE
230 ><P
231 >These macros provide control over the state of the CPUs interrupt mask
232 mechanism. They should normally manipulate a CPU status register to
233 enable and disable interrupt delivery. They should not access an
234 interrupt controller.</P
235 ><P
236 ><TT
237 CLASS="LITERAL"
238 >CYG_INTERRUPT_STATE</TT
239 > is a data type that should be
240 used to store the interrupt state returned by
241 <TT
242 CLASS="FUNCTION"
243 >HAL_DISABLE_INTERRUPTS()</TT
244 > and
245 <TT
246 CLASS="FUNCTION"
247 >HAL_QUERY_INTERRUPTS()</TT
248 > and passed to
249 <TT
250 CLASS="FUNCTION"
251 >HAL_RESTORE_INTERRUPTS()</TT
252 >.</P
253 ><P
254 ><TT
255 CLASS="FUNCTION"
256 >HAL_DISABLE_INTERRUPTS()</TT
257 > disables the delivery of
258 interrupts and stores the original state of the interrupt mask in the
259 variable passed in the <TT
260 CLASS="PARAMETER"
261 ><I
262 >old</I
263 ></TT
264 > argument.</P
265 ><P
266 ><TT
267 CLASS="FUNCTION"
268 >HAL_RESTORE_INTERRUPTS()</TT
269 > restores the state of
270 the interrupt mask to that recorded in <TT
271 CLASS="PARAMETER"
272 ><I
273 >old</I
274 ></TT
275 >.</P
276 ><P
277 ><TT
278 CLASS="FUNCTION"
279 >HAL_ENABLE_INTERRUPTS()</TT
280 > simply enables interrupts
281 regardless of the current state of the mask.</P
282 ><P
283 ><TT
284 CLASS="FUNCTION"
285 >HAL_QUERY_INTERRUPTS()</TT
286 > stores the state of the
287 interrupt mask in the variable passed in the <TT
288 CLASS="PARAMETER"
289 ><I
290 >state</I
291 ></TT
292 > argument. The state stored here should also be
293 capable of being passed to
294 <TT
295 CLASS="FUNCTION"
296 >HAL_RESTORE_INTERRUPTS()</TT
297 > at a later point.</P
298 ><P
299 >It is at the HAL implementer&#8217;s discretion exactly
300 which interrupts are masked by this mechanism. Where a CPU has more
301 than one interrupt type that may be masked separately (e.g. the
302 ARM's IRQ and FIQ) only those that can raise DSRs need
303 to be masked here. A separate architecture specific mechanism may
304 then be used to control the other interrupt types.</P
305 ></DIV
306 ><DIV
307 CLASS="SECTION"
308 ><H2
309 CLASS="SECTION"
310 ><A
311 NAME="AEN7961">ISR and VSR management</H2
312 ><TABLE
313 BORDER="5"
314 BGCOLOR="#E0E0F0"
315 WIDTH="70%"
316 ><TR
317 ><TD
318 ><PRE
319 CLASS="PROGRAMLISTING"
320 >HAL_INTERRUPT_IN_USE( vector, state )
321 HAL_INTERRUPT_ATTACH( vector, isr, data, object )
322 HAL_INTERRUPT_DETACH( vector, isr )
323 HAL_VSR_SET( vector, vsr, poldvsr )
324 HAL_VSR_GET( vector, pvsr )
325 HAL_VSR_SET_TO_ECOS_HANDLER( vector, poldvsr )</PRE
326 ></TD
327 ></TR
328 ></TABLE
329 ><P
330 >These macros manage the attachment of interrupt and vector service
331 routines to interrupt and exception vectors respectively.</P
332 ><P
333 ><TT
334 CLASS="FUNCTION"
335 >HAL_INTERRUPT_IN_USE()</TT
336 > tests the state of the
337 supplied interrupt vector and sets the value of the state parameter to
338 either 1 or 0 depending on whether there is already an ISR attached to
339 the vector. The HAL will only allow one ISR to be attached to each
340 vector, so it is a good idea to use this function before using
341 <TT
342 CLASS="FUNCTION"
343 >HAL_INTERRUPT_ATTACH()</TT
344 >.</P
345 ><P
346 ><TT
347 CLASS="FUNCTION"
348 >HAL_INTERRUPT_ATTACH()</TT
349 > attaches
350 the ISR, data pointer and object pointer to the given
351 <TT
352 CLASS="PARAMETER"
353 ><I
354 >vector</I
355 ></TT
356 >. When an interrupt occurs on this
357 vector the ISR is called using the C calling convention and the vector
358 number and data pointer are passed to it as the first and second
359 arguments respectively.</P
360 ><P
361 ><TT
362 CLASS="FUNCTION"
363 >HAL_INTERRUPT_DETACH()</TT
364 > detaches the ISR from the
365 vector.</P
366 ><P
367 ><TT
368 CLASS="FUNCTION"
369 >HAL_VSR_SET()</TT
370 > replaces the VSR attached to the
371 <TT
372 CLASS="PARAMETER"
373 ><I
374 >vector</I
375 ></TT
376 > with the replacement supplied in
377 <TT
378 CLASS="PARAMETER"
379 ><I
380 >vsr</I
381 ></TT
382 >. The old VSR is returned in the location
383 pointed to by <TT
384 CLASS="PARAMETER"
385 ><I
386 >pvsr</I
387 ></TT
388 >.</P
389 ><P
390 ><TT
391 CLASS="FUNCTION"
392 >HAL_VSR_GET()</TT
393 > assigns
394 a copy of the VSR to the location pointed to by <TT
395 CLASS="PARAMETER"
396 ><I
397 >pvsr</I
398 ></TT
399 >.</P
400 ><P
401 ><TT
402 CLASS="FUNCTION"
403 >HAL_VSR_SET_TO_ECOS_HANDLER()</TT
404 > ensures that the
405 VSR for a specific exception is pointing at the eCos exception VSR and
406 not one for RedBoot or some other ROM monitor. The default when
407 running under RedBoot is for exceptions to be handled by RedBoot and
408 passed to GDB. This macro diverts the exception to eCos so that it may
409 be handled by application code. The arguments are the VSR vector to be
410 replaces, and a location in which to store the old VSR pointer, so
411 that it may be replaced at a later point.</P
412 ></DIV
413 ><DIV
414 CLASS="SECTION"
415 ><H2
416 CLASS="SECTION"
417 ><A
418 NAME="AEN7983">Interrupt controller management</H2
419 ><TABLE
420 BORDER="5"
421 BGCOLOR="#E0E0F0"
422 WIDTH="70%"
423 ><TR
424 ><TD
425 ><PRE
426 CLASS="PROGRAMLISTING"
427 >HAL_INTERRUPT_MASK( vector )
428 HAL_INTERRUPT_UNMASK( vector )
429 HAL_INTERRUPT_ACKNOWLEDGE( vector )
430 HAL_INTERRUPT_CONFIGURE( vector, level, up )
431 HAL_INTERRUPT_SET_LEVEL( vector, level )</PRE
432 ></TD
433 ></TR
434 ></TABLE
435 ><P
436 >These macros exert control over any prioritized interrupt
437 controller that is present. If no priority controller exists, then
438 these macros should be empty.</P
439 ><DIV
440 CLASS="NOTE"
441 ><BLOCKQUOTE
442 CLASS="NOTE"
443 ><P
444 ><B
445 >Note: </B
446 >  These macros may not be reentrant, so care should be taken to
447   prevent them being called while interrupts are enabled. This means
448   that they can be safely used in initialization code before
449   interrupts are enabled, and in ISRs. In DSRs, ASRs and thread code,
450   however, interrupts must be disabled before these macros are
451   called. Here is an example for use in a DSR where the interrupt
452   source is unmasked after data processing:
453   </P
454 ><TABLE
455 BORDER="5"
456 BGCOLOR="#E0E0F0"
457 WIDTH="70%"
458 ><TR
459 ><TD
460 ><PRE
461 CLASS="PROGRAMLISTING"
462 > ...
463  HAL_DISABLE_INTERRUPTS(old);
464  HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_ETH);
465  HAL_RESTORE_INTERRUPTS(old);
466  ...</PRE
467 ></TD
468 ></TR
469 ></TABLE
470 ></BLOCKQUOTE
471 ></DIV
472 ><P
473 ><TT
474 CLASS="FUNCTION"
475 >HAL_INTERRUPT_MASK()</TT
476 > causes the interrupt
477 associated with the given vector to be blocked.</P
478 ><P
479 ><TT
480 CLASS="FUNCTION"
481 >HAL_INTERRUPT_UNMASK()</TT
482 > causes the interrupt
483 associated with the given vector to be unblocked.</P
484 ><P
485 ><TT
486 CLASS="FUNCTION"
487 >HAL_INTERRUPT_ACKNOWLEDGE()</TT
488 > acknowledges the
489 current interrupt from the given vector. This is usually executed from
490 the ISR for this vector when it is prepared to allow further
491 interrupts.  Most interrupt controllers need some form of acknowledge
492 action before the next interrupt is allowed through. Executing this
493 macro may cause another interrupt to be delivered. Whether this
494 interrupts the current code depends on the state of the CPU interrupt
495 mask.</P
496 ><P
497 ><TT
498 CLASS="FUNCTION"
499 >HAL_INTERRUPT_CONFIGURE()</TT
500 > provides
501 control over how an interrupt signal is detected. The arguments
502 are:</P
503 ><P
504 ></P
505 ><DIV
506 CLASS="VARIABLELIST"
507 ><DL
508 ><DT
509 >vector</DT
510 ><DD
511 ><P
512 >The interrupt vector to be configured.</P
513 ></DD
514 ><DT
515 >level</DT
516 ><DD
517 ><P
518 >      Set to <TT
519 CLASS="VARNAME"
520 >true</TT
521 > if the interrupt is detected by
522       level, and <TT
523 CLASS="VARNAME"
524 >false</TT
525 > if it is edge triggered.
526       </P
527 ></DD
528 ><DT
529 >up</DT
530 ><DD
531 ><P
532 >      If the interrupt is set to level detect, then if this is
533       <TT
534 CLASS="VARNAME"
535 >true</TT
536 > it is detected by a high signal level,
537       and if <TT
538 CLASS="VARNAME"
539 >false</TT
540 > by a low signal level. If the
541       interrupt is set to edge triggered, then if this is
542       <TT
543 CLASS="VARNAME"
544 >true</TT
545 > it is triggered by a rising edge and if
546       <TT
547 CLASS="VARNAME"
548 >false</TT
549 > by a falling edge.
550       </P
551 ></DD
552 ></DL
553 ></DIV
554 ><P
555 ><TT
556 CLASS="FUNCTION"
557 >HAL_INTERRUPT_SET_LEVEL()</TT
558 > provides control over
559 the hardware priority of the interrupt. The arguments are:</P
560 ><P
561 ></P
562 ><DIV
563 CLASS="VARIABLELIST"
564 ><DL
565 ><DT
566 >vector</DT
567 ><DD
568 ><P
569 >The interrupt whose level is to be set.</P
570 ></DD
571 ><DT
572 >level</DT
573 ><DD
574 ><P
575 >      The priority level to which the interrupt is to set. In some
576       architectures the masking of an interrupt is achieved by
577       changing its priority level. Hence this function,
578       <TT
579 CLASS="FUNCTION"
580 >HAL_INTERRUPT_MASK()</TT
581 > and
582       <TT
583 CLASS="FUNCTION"
584 >HAL_INTERRUPT_UNMASK()</TT
585 > may interfere with
586       each other.
587       </P
588 ></DD
589 ></DL
590 ></DIV
591 ></DIV
592 ><DIV
593 CLASS="SECTION"
594 ><H2
595 CLASS="SECTION"
596 ><A
597 NAME="AEN8030">Clock control</H2
598 ><TABLE
599 BORDER="5"
600 BGCOLOR="#E0E0F0"
601 WIDTH="70%"
602 ><TR
603 ><TD
604 ><PRE
605 CLASS="PROGRAMLISTING"
606 >HAL_CLOCK_INITIALIZE( period )
607 HAL_CLOCK_RESET( vector, period )
608 HAL_CLOCK_READ( pvalue )</PRE
609 ></TD
610 ></TR
611 ></TABLE
612 ><P
613 >These macros provide control over a clock or timer device that may be
614 used by the kernel to provide time-out, delay and scheduling
615 services. The clock is assumed to be implemented by some form of
616 counter that is incremented or decremented by some external source and
617 which raises an interrupt when it reaches a predetermined value.</P
618 ><P
619 ><TT
620 CLASS="FUNCTION"
621 >HAL_CLOCK_INITIALIZE()</TT
622 > initializes the timer
623 device to interrupt at the given period. The period is essentially the
624 value used to initialize the timer counter and must be calculated from
625 the timer frequency and the desired interrupt rate. The timer device
626 should generate an interrupt every <TT
627 CLASS="VARNAME"
628 >period</TT
629 > cycles.</P
630 ><P
631 ><TT
632 CLASS="FUNCTION"
633 >HAL_CLOCK_RESET()</TT
634 > re-initializes the timer to
635 provoke the next interrupt. This macro is only really necessary when
636 the timer device needs to be reset in some way after each interrupt.</P
637 ><P
638 ><TT
639 CLASS="FUNCTION"
640 >HAL_CLOCK_READ()</TT
641 > reads the current value of the
642 timer counter and puts the value in the location pointed to by
643 <TT
644 CLASS="PARAMETER"
645 ><I
646 >pvalue</I
647 ></TT
648 >. The value stored will always be the
649 number of timer cycles since the last interrupt, and hence ranges
650 between zero and the initial period value. If this is a count-down
651 cyclic timer, some arithmetic may be necessary to generate this value.</P
652 ></DIV
653 ><DIV
654 CLASS="SECTION"
655 ><H2
656 CLASS="SECTION"
657 ><A
658 NAME="AEN8042">Microsecond Delay</H2
659 ><TABLE
660 BORDER="5"
661 BGCOLOR="#E0E0F0"
662 WIDTH="70%"
663 ><TR
664 ><TD
665 ><PRE
666 CLASS="PROGRAMLISTING"
667 >HAL_DELAY_US(us)</PRE
668 ></TD
669 ></TR
670 ></TABLE
671 ><P
672 >This is an optional definition. If defined the macro implements a busy
673 loop delay for the given number of microseconds. This is usually
674 implemented by waiting for the required number of hardware timer ticks
675 to pass. </P
676 ><P
677 >This operation should normally be used when a very short delay is
678 needed when controlling hardware, programming FLASH devices and similar
679 situations where a wait/timeout loop would otherwise be used. Since it
680 may disable interrupts, and is implemented by busy waiting, it should
681 not be used in code that is sensitive to interrupt or context switch
682 latencies.</P
683 ></DIV
684 ></DIV
685 ><DIV
686 CLASS="NAVFOOTER"
687 ><HR
688 ALIGN="LEFT"
689 WIDTH="100%"><TABLE
690 SUMMARY="Footer navigation table"
691 WIDTH="100%"
692 BORDER="0"
693 CELLPADDING="0"
694 CELLSPACING="0"
695 ><TR
696 ><TD
697 WIDTH="33%"
698 ALIGN="left"
699 VALIGN="top"
700 ><A
701 HREF="hal-architecture-characterization.html"
702 ACCESSKEY="P"
703 >Prev</A
704 ></TD
705 ><TD
706 WIDTH="34%"
707 ALIGN="center"
708 VALIGN="top"
709 ><A
710 HREF="ecos-ref.html"
711 ACCESSKEY="H"
712 >Home</A
713 ></TD
714 ><TD
715 WIDTH="33%"
716 ALIGN="right"
717 VALIGN="top"
718 ><A
719 HREF="hal-input-and-output.html"
720 ACCESSKEY="N"
721 >Next</A
722 ></TD
723 ></TR
724 ><TR
725 ><TD
726 WIDTH="33%"
727 ALIGN="left"
728 VALIGN="top"
729 >Architecture Characterization</TD
730 ><TD
731 WIDTH="34%"
732 ALIGN="center"
733 VALIGN="top"
734 ><A
735 HREF="hal-interfaces.html"
736 ACCESSKEY="U"
737 >Up</A
738 ></TD
739 ><TD
740 WIDTH="33%"
741 ALIGN="right"
742 VALIGN="top"
743 >HAL I/O</TD
744 ></TR
745 ></TABLE
746 ></DIV
747 ></BODY
748 ></HTML
749 >