Home |
RTKernel-32 Programming Manual Multitasking, Real-Time, and RTKernel-32 Alternate APIs for RTKernel-32 Interrupt Handling Installing Shared Interrupt Handlers Interrupt Handler for RTKSetIRQHandler Preemptive or Cooperative Multitasking? Starting Objects' Methods as Tasks Performance and Interrupt Response Times Task Switches in Cooperative Scheduling Using the FPU in Interrupt Handlers |
Interrupt HandlingOne of the central tasks of real-time software is the processing of interrupts. As soon as several tasks run in a program, it is virtually impossible to achieve good response times by polling (continuous enquiry of an event). Continuous polling would prevent tasks with lower priorities from running and thus waste precious CPU time. Therefore, it should always be attempted to replace polling by interrupts. This leads to the best response times and optimal use of the hardware available. RTKernel-32 uses the timer interrupt to activate tasks waiting for a certain point in time. Module RTCom provide interrupt support for serial ports. This section discusses how to implement a handler for any interrupt source. An interrupt handler may be thought of as a task running with a priority higher than all other tasks. However, there are some important considerations to keep in mind. Interrupt handlers usually have little stack space. Therefore, interrupt handlers should be very economical in their stack usage (e.g., refrain from using functions like sprintf by all means). While an interrupt handler is active, no other interrupts with lower priorities can be processed. Therefore, it is important to minimize the execution times of interrupt handlers, because otherwise the interrupt response time for other interrupts might suffer. The handler should avoid any processing not immediately required and delegate it to a task. Interrupt handlers under RTKernel-32 are never directly addressed by the hardware; instead, they are called by the low-level handlers or dispatchers of the kernel (see section Module RTKernel-32, Interrupt Handling). While the handler is being executed, the scheduler is disabled; thus, the handler need not consider being disrupted by a task switch (it can, however, be interrupted by interrupts of higher priority). Since the scheduler is disabled, interrupt handlers must not force blocking task switches. An interrupt handler may:
An interrupt handler must not:
The reason for the last restriction is that an interrupt handler runs in the context of the task it has interrupted. An interrupt handler that blocks itself (e.g., by calling RTKDelay or RTKWait at a semaphore with no events) actually blocks the task it has interrupted, even though this task could very well continue running. This results in a task with a low priority running, although another task with a higher priority is ready; this situation will sooner or later crash the scheduler. For this reason, only the functions RTKSignal and RTKWaitCond (for semaphores), RTKPutCond and RTKGetCond (for mailboxes), and RTKSendCond and RTKReceiveCond (for message passing) can be used by interrupt handlers. These operations can lead to activating but not to blocking task switches. RTKernel-32's Win32 emulation routines can also be used by interrupt handlers (although this is not possible under Win32 itself). The following functions may be used: GetTickCount, SetEvent, ResetEvent, PulseEvent, ReleaseSemaphore. It should be noted that a call to any of these functions can change the value returned by GetLastError of the interrupted task. To avoid interfering with error handling, the error code should be saved and restored in the interrupt handler. RTKernel-32 has two interrupt handling APIs. The recommended API consists of only two functions: RTInstallSharedIRQHandlerEx and RTRemoveSharedIRQHandlerEx. It is more powerful and simpler to use than the API based on RTKSetIRQHandler and related functions. The following sections describe the basic structure of a handler for each API. Demo program RTKInt shows how hardware interrupts are handled with RTKernel-32. In addition, the handlers of supplemental module RTCom may serve as further examples. Programs which must share global data accessed in interrupt service routines and tasks must take care to maintain such data in a consistent state. As blocking task switches are not allows in interrupt handlers, spinlocks are the recommended mechanism here. For applications which will never run on a multiprocessor system, merely disabling interrupts while a task is accessing the shared data is also possible. Installing Shared Interrupt Handlers Interrupt Handler for RTKSetIRQHandler
|