source: rtems-docs/c_user/interrupt_manager.rst @ b8d3f6b

4.115
Last change on this file since b8d3f6b was b8d3f6b, checked in by Chris Johns <chrisj@…>, on 01/24/16 at 10:37:53

C user guide clean up. Up to timer manager.

  • Property mode set to 100644
File size: 18.0 KB
Line 
1.. COMMENT: COPYRIGHT (c) 1988-2008.
2.. COMMENT: On-Line Applications Research Corporation (OAR).
3.. COMMENT: All rights reserved.
4
5Interrupt Manager
6#################
7
8Introduction
9============
10
11Any real-time executive must provide a mechanism for quick response to
12externally generated interrupts to satisfy the critical time constraints of the
13application.  The interrupt manager provides this mechanism for RTEMS.  This
14manager permits quick interrupt response times by providing the critical
15ability to alter task execution which allows a task to be preempted upon exit
16from an ISR.  The interrupt manager includes the following directive:
17
18- rtems_interrupt_catch_ - Establish an ISR
19
20- rtems_interrupt_disable_ - Disable Interrupts
21
22- rtems_interrupt_enable_ - Enable Interrupts
23
24- rtems_interrupt_flash_ - Flash Interrupt
25
26- rtems_interrupt_local_disable_ - Disable Interrupts on Current Processor
27
28- rtems_interrupt_local_enable_ - Enable Interrupts on Current Processor
29
30- rtems_interrupt_lock_initialize_ - Initialize an ISR Lock
31
32- rtems_interrupt_lock_acquire_ - Acquire an ISR Lock
33
34- rtems_interrupt_lock_release_ - Release an ISR Lock
35
36- rtems_interrupt_lock_acquire_isr_ - Acquire an ISR Lock from ISR
37
38- rtems_interrupt_lock_release_isr_ - Release an ISR Lock from ISR
39
40- rtems_interrupt_is_in_progress_ - Is an ISR in Progress
41
42Background
43==========
44
45Processing an Interrupt
46-----------------------
47.. index:: interrupt processing
48
49The interrupt manager allows the application to connect a function to a
50hardware interrupt vector.  When an interrupt occurs, the processor will
51automatically vector to RTEMS.  RTEMS saves and restores all registers which
52are not preserved by the normal C calling convention for the target processor
53and invokes the user's ISR.  The user's ISR is responsible for processing the
54interrupt, clearing the interrupt if necessary, and device specific
55manipulation.
56
57.. index:: rtems_vector_number
58
59The ``rtems_interrupt_catch`` directive connects a procedure to an interrupt
60vector.  The vector number is managed using the ``rtems_vector_number`` data
61type.
62
63The interrupt service routine is assumed to abide by these conventions and have
64a prototype similar to the following:
65
66.. index:: rtems_isr
67
68.. code:: c
69
70    rtems_isr user_isr(
71        rtems_vector_number vector
72    );
73
74The vector number argument is provided by RTEMS to allow the application to
75identify the interrupt source.  This could be used to allow a single routine to
76service interrupts from multiple instances of the same device.  For example, a
77single routine could service interrupts from multiple serial ports and use the
78vector number to identify which port requires servicing.
79
80To minimize the masking of lower or equal priority level interrupts, the ISR
81should perform the minimum actions required to service the interrupt.  Other
82non-essential actions should be handled by application tasks.  Once the user's
83ISR has completed, it returns control to the RTEMS interrupt manager which will
84perform task dispatching and restore the registers saved before the ISR was
85invoked.
86
87The RTEMS interrupt manager guarantees that proper task scheduling and
88dispatching are performed at the conclusion of an ISR.  A system call made by
89the ISR may have readied a task of higher priority than the interrupted task.
90Therefore, when the ISR completes, the postponed dispatch processing must be
91performed.  No dispatch processing is performed as part of directives which
92have been invoked by an ISR.
93
94Applications must adhere to the following rule if proper task scheduling and
95dispatching is to be performed:
96
97.. note::
98
99  The interrupt manager must be used for all ISRs which may be interrupted by
100  the highest priority ISR which invokes an RTEMS directive.
101
102Consider a processor which allows a numerically low interrupt level to
103interrupt a numerically greater interrupt level.  In this example, if an RTEMS
104directive is used in a level 4 ISR, then all ISRs which execute at levels 0
105through 4 must use the interrupt manager.
106
107Interrupts are nested whenever an interrupt occurs during the execution of
108another ISR.  RTEMS supports efficient interrupt nesting by allowing the nested
109ISRs to terminate without performing any dispatch processing.  Only when the
110outermost ISR terminates will the postponed dispatching occur.
111
112RTEMS Interrupt Levels
113----------------------
114.. index:: interrupt levels
115
116Many processors support multiple interrupt levels or priorities.  The exact
117number of interrupt levels is processor dependent.  RTEMS internally supports
118256 interrupt levels which are mapped to the processor's interrupt levels.  For
119specific information on the mapping between RTEMS and the target processor's
120interrupt levels, refer to the Interrupt Processing chapter of the Applications
121Supplement document for a specific target processor.
122
123Disabling of Interrupts by RTEMS
124--------------------------------
125.. index:: disabling interrupts
126
127During the execution of directive calls, critical sections of code may be
128executed.  When these sections are encountered, RTEMS disables all maskable
129interrupts before the execution of the section and restores them to the
130previous level upon completion of the section.  RTEMS has been optimized to
131ensure that interrupts are disabled for a minimum length of time.  The maximum
132length of time interrupts are disabled by RTEMS is processor dependent and is
133detailed in the Timing Specification chapter of the Applications Supplement
134document for a specific target processor.
135
136Non-maskable interrupts (NMI) cannot be disabled, and ISRs which execute at
137this level MUST NEVER issue RTEMS system calls.  If a directive is invoked,
138unpredictable results may occur due to the inability of RTEMS to protect its
139critical sections.  However, ISRs that make no system calls may safely execute
140as non-maskable interrupts.
141
142Operations
143==========
144
145Establishing an ISR
146-------------------
147
148The ``rtems_interrupt_catch`` directive establishes an ISR for the system.  The
149address of the ISR and its associated CPU vector number are specified to this
150directive.  This directive installs the RTEMS interrupt wrapper in the
151processor's Interrupt Vector Table and the address of the user's ISR in the
152RTEMS' Vector Table.  This directive returns the previous contents of the
153specified vector in the RTEMS' Vector Table.
154
155Directives Allowed from an ISR
156------------------------------
157
158Using the interrupt manager ensures that RTEMS knows when a directive is being
159called from an ISR.  The ISR may then use system calls to synchronize itself
160with an application task.  The synchronization may involve messages, events or
161signals being passed by the ISR to the desired task.  Directives invoked by an
162ISR must operate only on objects which reside on the local node.  The following
163is a list of RTEMS system calls that may be made from an ISR:
164
165- Task Management
166  Although it is acceptable to operate on the RTEMS_SELF task (e.g.  the
167  currently executing task), while in an ISR, this will refer to the
168  interrupted task.  Most of the time, it is an application implementation
169  error to use RTEMS_SELF from an ISR.
170  - rtems_task_suspend
171  - rtems_task_resume
172
173- Interrupt Management
174  - rtems_interrupt_enable
175  - rtems_interrupt_disable
176  - rtems_interrupt_flash
177  - rtems_interrupt_lock_acquire
178  - rtems_interrupt_lock_release
179  - rtems_interrupt_lock_acquire_isr
180  - rtems_interrupt_lock_release_isr
181  - rtems_interrupt_is_in_progress
182  - rtems_interrupt_catch
183
184- Clock Management
185  - rtems_clock_set
186  - rtems_clock_get
187  - rtems_clock_get_tod
188  - rtems_clock_get_tod_timeval
189  - rtems_clock_get_seconds_since_epoch
190  - rtems_clock_get_ticks_per_second
191  - rtems_clock_get_ticks_since_boot
192  - rtems_clock_get_uptime
193  - rtems_clock_set_nanoseconds_extension
194  - rtems_clock_tick
195
196- Timer Management
197  - rtems_timer_cancel
198  - rtems_timer_reset
199  - rtems_timer_fire_after
200  - rtems_timer_fire_when
201  - rtems_timer_server_fire_after
202  - rtems_timer_server_fire_when
203
204- Event Management
205  - rtems_event_send
206  - rtems_event_system_send
207  - rtems_event_transient_send
208
209- Semaphore Management
210  - rtems_semaphore_release
211
212- Message Management
213  - rtems_message_queue_send
214  - rtems_message_queue_urgent
215
216- Signal Management
217  - rtems_signal_send
218
219- Dual-Ported Memory Management
220  - rtems_port_external_to_internal
221  - rtems_port_internal_to_external
222
223- IO Management
224  The following services are safe to call from an ISR if and only if
225  the device driver service invoked is also safe.  The IO Manager itself
226  is safe but the invoked driver entry point may or may not be.
227  - rtems_io_initialize
228  - rtems_io_open
229  - rtems_io_close
230  - rtems_io_read
231  - rtems_io_write
232  - rtems_io_control
233
234- Fatal Error Management
235  - rtems_fatal
236  - rtems_fatal_error_occurred
237
238- Multiprocessing
239  - rtems_multiprocessing_announce
240
241Directives
242==========
243
244This section details the interrupt manager's directives.  A subsection is
245dedicated to each of this manager's directives and describes the calling
246sequence, related constants, usage, and status codes.
247
248.. _rtems_interrupt_catch:
249
250INTERRUPT_CATCH - Establish an ISR
251----------------------------------
252.. index:: establish an ISR
253.. index:: install an ISR
254
255**CALLING SEQUENCE:**
256
257.. index:: rtems_interrupt_catch
258
259.. code:: c
260
261    rtems_status_code rtems_interrupt_catch(
262        rtems_isr_entry      new_isr_handler,
263        rtems_vector_number  vector,
264        rtems_isr_entry     *old_isr_handler
265    );
266
267**DIRECTIVE STATUS CODES:**
268
269``RTEMS_SUCCESSFUL``
270  ISR established successfully
271
272``RTEMS_INVALID_NUMBER``
273  illegal vector number
274
275``RTEMS_INVALID_ADDRESS``
276  illegal ISR entry point or invalid ``old_isr_handler``
277
278**DESCRIPTION:**
279
280This directive establishes an interrupt service routine (ISR) for the specified
281interrupt vector number.  The ``new_isr_handler`` parameter specifies the entry
282point of the ISR.  The entry point of the previous ISR for the specified vector
283is returned in ``old_isr_handler``.
284
285To release an interrupt vector, pass the old handler's address obtained when
286the vector was first capture.
287
288**NOTES:**
289
290This directive will not cause the calling task to be preempted.
291
292.. _rtems_interrupt_disable:
293
294INTERRUPT_DISABLE - Disable Interrupts
295--------------------------------------
296.. index:: disable interrupts
297
298**CALLING SEQUENCE:**
299
300.. index:: rtems_interrupt_disable
301
302.. code:: c
303
304    void rtems_interrupt_disable(
305        rtems_interrupt_level  level
306    );
307
308**DIRECTIVE STATUS CODES:**
309
310NONE
311
312**DESCRIPTION:**
313
314.. sidebar:: *Macro*
315
316  This directive is implemented as a macro which modifies the ``level``
317  parameter.
318
319This directive disables all maskable interrupts and returns the previous
320``level``.  A later invocation of the ``rtems_interrupt_enable`` directive
321should be used to restore the interrupt level.
322
323**NOTES:**
324
325This directive will not cause the calling task to be preempted.
326
327This directive is only available on uni-processor configurations.  The
328directive ``rtems_interrupt_local_disable`` is available on all configurations.
329
330.. _rtems_interrupt_enable:
331
332INTERRUPT_ENABLE - Enable Interrupts
333------------------------------------
334.. index:: enable interrupts
335
336**CALLING SEQUENCE:**
337
338.. index:: rtems_interrupt_enable
339
340.. code:: c
341
342    void rtems_interrupt_enable(
343       rtems_interrupt_level  level
344    );
345
346**DIRECTIVE STATUS CODES:**
347
348NONE
349
350**DESCRIPTION:**
351
352This directive enables maskable interrupts to the ``level`` which was returned
353by a previous call to ``rtems_interrupt_disable``.  Immediately prior to
354invoking this directive, maskable interrupts should be disabled by a call to
355``rtems_interrupt_disable`` and will be enabled when this directive returns to
356the caller.
357
358**NOTES:**
359
360This directive will not cause the calling task to be preempted.
361
362This directive is only available on uni-processor configurations.  The
363directive ``rtems_interrupt_local_enable`` is available on all configurations.
364
365.. _rtems_interrupt_flash:
366
367INTERRUPT_FLASH - Flash Interrupts
368----------------------------------
369.. index:: flash interrupts
370
371**CALLING SEQUENCE:**
372
373.. index:: rtems_interrupt_flash
374
375.. code:: c
376
377    void rtems_interrupt_flash(
378        rtems_interrupt_level level
379    );
380
381**DIRECTIVE STATUS CODES:**
382
383NONE
384
385**DESCRIPTION:**
386
387This directive temporarily enables maskable interrupts to the ``level`` which
388was returned by a previous call to ``rtems_interrupt_disable``.  Immediately
389prior to invoking this directive, maskable interrupts should be disabled by a
390call to ``rtems_interrupt_disable`` and will be redisabled when this directive
391returns to the caller.
392
393**NOTES:**
394
395This directive will not cause the calling task to be preempted.
396
397This directive is only available on uni-processor configurations.  The
398directives ``rtems_interrupt_local_disable``
399and``rtems_interrupt_local_enable`` is available on all configurations.
400
401.. _rtems_interrupt_local_disable:
402
403INTERRUPT_LOCAL_DISABLE - Disable Interrupts on Current Processor
404-----------------------------------------------------------------
405.. index:: disable interrupts
406
407**CALLING SEQUENCE:**
408
409.. index:: rtems_interrupt_local_disable
410
411.. code:: c
412
413    void rtems_interrupt_local_disable(
414        rtems_interrupt_level  level
415    );
416
417**DIRECTIVE STATUS CODES:**
418
419NONE
420
421**DESCRIPTION:**
422
423.. sidebar:: *Macro*
424
425  This directive is implemented as a macro which modifies the ``level``
426  parameter.
427
428This directive disables all maskable interrupts and returns the previous
429``level``.  A later invocation of the ``rtems_interrupt_local_enable`` directive
430should be used to restore the interrupt level.
431
432**NOTES:**
433
434This directive will not cause the calling task to be preempted.
435
436On SMP configurations this will not ensure system wide mutual exclusion.  Use
437interrupt locks instead.
438
439.. _rtems_interrupt_local_enable:
440
441INTERRUPT_LOCAL_ENABLE - Enable Interrupts on Current Processor
442---------------------------------------------------------------
443.. index:: enable interrupts
444
445**CALLING SEQUENCE:**
446
447.. index:: rtems_interrupt_local_enable
448
449.. code:: c
450
451    void rtems_interrupt_local_enable(
452        rtems_interrupt_level  level
453    );
454
455**DIRECTIVE STATUS CODES:**
456
457NONE
458
459**DESCRIPTION:**
460
461This directive enables maskable interrupts to the ``level`` which was returned
462by a previous call to ``rtems_interrupt_local_disable``.  Immediately prior to
463invoking this directive, maskable interrupts should be disabled by a call to
464``rtems_interrupt_local_disable`` and will be enabled when this directive
465returns to the caller.
466
467**NOTES:**
468
469This directive will not cause the calling task to be preempted.
470
471.. _rtems_interrupt_lock_initialize:
472
473INTERRUPT_LOCK_INITIALIZE - Initialize an ISR Lock
474--------------------------------------------------
475
476**CALLING SEQUENCE:**
477
478.. index:: rtems_interrupt_lock_initialize
479
480.. code:: c
481
482    void rtems_interrupt_lock_initialize(
483        rtems_interrupt_lock *lock
484    );
485
486**DIRECTIVE STATUS CODES:**
487
488NONE
489
490**DESCRIPTION:**
491
492Initializes an interrupt lock.
493
494**NOTES:**
495
496Concurrent initialization leads to unpredictable results.
497
498.. _rtems_interrupt_lock_acquire:
499
500INTERRUPT_LOCK_ACQUIRE - Acquire an ISR Lock
501--------------------------------------------
502
503**CALLING SEQUENCE:**
504
505.. index:: rtems_interrupt_lock_acquire
506
507.. code:: c
508
509    void rtems_interrupt_lock_acquire(
510        rtems_interrupt_lock *lock,
511        rtems_interrupt_level level
512    );
513
514**DIRECTIVE STATUS CODES:**
515
516NONE
517
518**DESCRIPTION:**
519
520Interrupts will be disabled.  On SMP configurations this directive acquires a
521SMP lock.
522
523**NOTES:**
524
525This directive will not cause the calling thread to be preempted.  This
526directive can be used in thread and interrupt context.
527
528.. _rtems_interrupt_lock_release:
529
530INTERRUPT_LOCK_RELEASE - Release an ISR Lock
531--------------------------------------------
532
533**CALLING SEQUENCE:**
534
535.. index:: rtems_interrupt_lock_release
536
537.. code:: c
538
539    void rtems_interrupt_lock_release(
540        rtems_interrupt_lock *lock,
541        rtems_interrupt_level level
542    );
543
544**DIRECTIVE STATUS CODES:**
545
546NONE
547
548**DESCRIPTION:**
549
550The interrupt status will be restored.  On SMP configurations this directive
551releases a SMP lock.
552
553**NOTES:**
554
555This directive will not cause the calling thread to be preempted.  This
556directive can be used in thread and interrupt context.
557
558.. _rtems_interrupt_lock_acquire_isr:
559
560INTERRUPT_LOCK_ACQUIRE_ISR - Acquire an ISR Lock from ISR
561---------------------------------------------------------
562
563**CALLING SEQUENCE:**
564
565.. index:: rtems_interrupt_lock_acquire_isr
566
567.. code:: c
568
569    void rtems_interrupt_lock_acquire_isr(
570        rtems_interrupt_lock *lock,
571        rtems_interrupt_level level
572    );
573
574**DIRECTIVE STATUS CODES:**
575
576NONE
577
578**DESCRIPTION:**
579
580The interrupt status will remain unchanged.  On SMP configurations this
581directive acquires a SMP lock.
582
583In case the corresponding interrupt service routine can be interrupted by
584higher priority interrupts and these interrupts enter the critical section
585protected by this lock, then the result is unpredictable.
586
587**NOTES:**
588
589This directive should be called from the corresponding interrupt service
590routine.
591
592.. _rtems_interrupt_lock_release_isr:
593
594INTERRUPT_LOCK_RELEASE_ISR - Release an ISR Lock from ISR
595---------------------------------------------------------
596
597**CALLING SEQUENCE:**
598
599.. index:: rtems_interrupt_lock_release_isr
600
601.. code:: c
602
603    void rtems_interrupt_lock_release_isr(
604        rtems_interrupt_lock *lock,
605        rtems_interrupt_level level
606    );
607
608**DIRECTIVE STATUS CODES:**
609
610NONE
611
612**DESCRIPTION:**
613
614The interrupt status will remain unchanged.  On SMP configurations this
615directive releases a SMP lock.
616
617**NOTES:**
618
619This directive should be called from the corresponding interrupt service
620routine.
621
622.. _rtems_interrupt_is_in_progress:
623
624INTERRUPT_IS_IN_PROGRESS - Is an ISR in Progress
625------------------------------------------------
626.. index:: is interrupt in progress
627
628**CALLING SEQUENCE:**
629
630.. index:: rtems_interrupt_is_in_progress
631
632.. code:: c
633
634    bool rtems_interrupt_is_in_progress(void);
635
636**DIRECTIVE STATUS CODES:**
637
638NONE
639
640**DESCRIPTION:**
641
642This directive returns ``TRUE`` if the processor is currently servicing an
643interrupt and ``FALSE`` otherwise.  A return value of ``TRUE`` indicates that
644the caller is an interrupt service routine, *NOT* a task.  The directives
645available to an interrupt service routine are restricted.
646
647**NOTES:**
648
649This directive will not cause the calling task to be preempted.
Note: See TracBrowser for help on using the repository browser.