source: rtems-docs/c-user/interrupt_manager.rst @ 72a62ad

4.115
Last change on this file since 72a62ad was 72a62ad, checked in by Chris Johns <chrisj@…>, on 11/03/16 at 05:58:08

Rename all manuals with an _ to have a -. It helps released naming of files.

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