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