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