a networking approach

7
A Networking Approach Second Edition Rob Williams

Upload: others

Post on 28-Mar-2022

1 views

Category:

Documents


0 download

TRANSCRIPT

strongest educational materials in computing,
bringing cutting-edge thinking and best learning
practice to a global market.
Under a range of well-known imprints, including
Prentice Hall, we craft high quality print and
electronic publications which help readers
to understand and apply their content,
whether studying or at work.
To find out more about the complete range of our
publishing please visit us on the World Wide Web
at: www.pearsoned.co.uk
9.4 Interrupt processing – service on demand 203
On entering an ISR the first job to be done is to protect those CPU registers that will be used in the ISR from corruption. This simply involves PUSHing the contents onto the stack, from where they will be restored at the completion of interrupt pro- cessing. Then the source of the interrupt has to be verified, perhaps by testing a pe- ripheral device flag bit, and the cause of the interrupt removed. Until this is done there is the danger of suffering a repeated interrupt from the same source, even though all the processing has been completed. It may then be necessary to reinitial-
ize the peripheral device to ready it for another interrupt request, although some- times this is not required. The end of the ISR is marked by POPping the saved registers and the execution of an rte instruction to restore the PC value.
The 8086 required the IVT to start at 0000. But the facility to relocate the IVT any- where in main memory was introduced with the 80386 through the provision of the Interrupt Descriptor Table Register (IDTR). To move the IVT you simply copy the con- tents, with any needed revisions, into the new position and point the IDTR to the base of the new table.
If a device requires only occasional attention then the interrupt method works fine: the peripheral just demands CPU help when it needs it. Using interrupts does require special hardware to be installed, and the changeover from main program to ISR and back again is a wasteful activity which often takes several microseconds each time to complete.
Most peripheral devices can be configured to use the CPU interrupt facility, but if there are many such devices triggering interrupt requests there will be extra problems to be considered. When several requests arrive at the same time there is a need to pri- oritize the devices and queue the requests until they can be serviced. The identifica- tion of the source of the interrupt may require explicit device polling if the hardware is unable to return an interrupt vector. Locating the appropriate interrupt routine in memory is normally straightforward using the VBR and the IVT.
The various sources of interrupts may be put into six categories, listed in Table 9.4. Some small microcontrollers do not allow interrupt processing itself to be inter-
rupted. The ability to accept and honour interrupts at any time is known as interrupt nesting. In this situation, a high-priority device, such as a hard disk, could break into a low-priority service routine without delay.
A further important use of modern interrupt facilities has been introduced by the implementation of access modes. By allocating CPU facilities and memory seg- ments either ‘User’ or ‘Privileged’ status, the system can protect its core functions from ordinary users, reserving the more risky capabilities for ‘root’ (or super-user).
Table 9.4 Possible sources of interrupts.
1. IO data transfer request
2. Software TRAP (SVC)
204 Chapter 9 Simple input and output
This is illustrated in Fig. 9.16, with the privilege levels represented as concentric spheres. Such access control is essential for modern multi-user operating systems and depends on all interrupts switching the CPU into Privileged Mode.
Thus interrupts provide a small entry window to the system facilities which can be policed by ISR code, which is now included as part of the operating system. This could be seen as the most significant use of the software interrupt or TRAP instruction.
There is an extra problem when trying to debug systems running interrupt rou- tines. With ordinary subroutines, the programmer should be able to tell exactly when each subroutine will run, taking into account the variation from moment to moment of IF-THEN-ELSE statements which may test changeable environmental conditions. In fact, some subroutines may never run at all because it happens to be a leap year, or Sweden doesn’t recognize Euro-travel Passes, or whatever. The role of interrupt rou- tines is to run when the CPU interrupt signal gets activated by a circumstance which is not always under the control of the programmer. Thus we say that subroutines are predictable and synchronous, while interrupt routines are asynchronous and unpre- dictable. This makes debugging software systems where several interrupts are likely to fire at any time much more demanding, especially when the debugger software confuses the situation by using the trace interrupt for its own ends!
Using the interrupts on digital computers has been criticized as dangerous because of the unpredictability of their occurrence and the resulting difficulty in thoroughly testing the system. Thus programmers building embedded computer systems for life- critical applications often try to avoid relying on interrupt facilities. But when consid- ering less risky areas, hardware interrupts can offer an efficient technique to introduce some measure of responsive multitasking to the system. Windows and Unix provide helpful viewer tools which enable you to watch the rate of interrupt processing as it occurs on your machine. Unix has perfmeter, which was introduced in Section 3.2, while Windows offers Performance Meter which is illustrated in Fig. 9.17.
This useful administration tool allows you to inspect the IRQ allocation, as well as some other interesting parameters. To fire it up select:
StartS ProgramsS Administrative Tools 1Common 2 S
Performance MonitorS EditS Add to ChartS Interrupts>sec
Fig. 9.16 How interrupts assist operating system security.
9.5 Critical data protection – how to communicate with interrupts 205
Mouse
activity
Fig. 9.17 Displaying interrupt activity on Windows NT.
In Fig. 9.17 the interrupt activity is displayed as a running average taken during 0.1 s intervals. When the mouse is oscillated from side to side it generates a burst of in- terrupts which show up as a rise in the average value. Such an increase would also re- sult if the keyboard were to be used, or any other device which is tied into the PC interrupt system.
Critical data protection – how to communicate with interrupts
As we started to discuss in Section 8.8, there is a particular problem with passing data back from an ISR. Consider the situation shown in Fig. 9.18 of a time-of-day (TOD) program which has two parts. There is a real-time clock (RTC) ISR being triggered every 10 ms to increment the seconds, minutes and hours values, and there is a dis- play routine to refresh a set of front panel digits showing the TOD. The msecs, secs,
9.5
206 Chapter 9 Simple input and output
Fig. 9.18 Real-time clock and time-of-day display.
mins and hrs data is held in memory. The routine which refreshes the display runs regularly, about twice a second as a low priority task, perhaps in the main processing loop. It takes the current seconds value, converts it to seven-segment format and writes it to the display. Then it does the same for minutes and then for hours.
The RTC ISR is more urgent and will break into any main process so that it can update the clock data in main memory. Now, what happens if the display is being refreshed when an RTC interrupt occurs? Consider the situation 01:59:59, with the display refresh having just written new values for secs and mins, and being poised to
9.5 Critical data protection – how to communicate with interrupts 207
1. Disable interrupts
Table 9.5 Alternative solu- tions to protecting a critical resource.
read the hrs from memory – and just then the RTC ISR occurs. It will rollover incre- ment msecs to 00, then secs to 00, then mins to 00, then hrs to 02. Having completed the ‘tick’ it returns control to the main program. This happens to be right on the point of refreshing the hrs display. This it does, leaving the incorrect value 02:59:59 for all to see. The false value will remain visible until the next display refresh occurs to correct it. In this example, the clock values in memory have not been corrupted, so no lasting damage is done (unless you missed your train). If the display update rou- tine also served a network connection, there would be scope for a larger disaster.
The problem described arises from the complexity of the data being processed and the need for simultaneous unsynchronized access by two or more processes. In a more general form you may encounter the same problem when programming a multitasking application for Unix or Windows. It is known as the critical resource problem. In this case, it is worth noting that if time was simply stored as a 32 bit integer there would be no problem, because the value would always be valid: interleaved update and display op- erations could not result in corrupted data unless the computer had multiple processors!
There are several solutions which can be tried to clear up the difficulty, as listed in Table 9.5.
If the interrupts were disabled to block the RTC interrupt request on entry to the display update routines, and then re-enabled at the completion of the display refresh, the display would remain coherent but would progressively go wrong. When the sys- tem receives an RTC interrupt its response would be delayed if the interrupts were disabled, so there is a risk that the TOD would become out of true. This is a more sig- nificant issue when the ticks occur more rapidly than 100 Hz. In fact, turning off all of the interrupts is far too drastic, because it would interfere with other interrupt- driven activity, such as IO transfers. This solution is only acceptable for small micro- controller systems, where interrupt deferment would not be too disruptive.
A better solution in this clock example would be to serialize access to the critical data region, as presented in Fig. 9.19. This means moving all the code across from the RTC ISR to the main program flow, just before the display refresh routines. This makes it impossible to read partly updated data. But now the RTC ISR must indicate to the main program through a flag or simple integer that a tick has occurred since the last display update. A check on the value of the RTC flag will determine whether a clock increment needs to take place.