Lab 4: Using External Interrupts - Design Microprocessor Systems | EECS 373, Lab Reports of Electrical and Electronics Engineering

Material Type: Lab; Class: Des Microproc Syst; Subject: Electrical Engineering And Computer Science; University: University of Michigan - Ann Arbor; Term: Fall 1998;

Typology: Lab Reports

Pre 2010

Uploaded on 09/02/2009

koofers-user-q6i
koofers-user-q6i 🇺🇸

10 documents

1 / 5

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
1
EECS 373 Fall 1998
Lab 4: Using External Interrupts
(revised Oct. 15 1:30 PM)
Introduction:
In this lab, you will modify your code from Lab 3 to use external interrupts from the
UART device to notify the CPU when characters can be transmitted or received. The use
of interrupts eliminates the need to poll the UART in the main program, freeing the CPU
for other tasks. You will have the CPU run your LED-flashing program from Lab 2
while it uses interrupts to handle the communications tasks from Lab 3. As in Lab 3 you
will use a device-driver interface to make your program independent of UART details;
you will write the device-driver functions for the simulated UART and we will supply the
functions for the target board UART.
Goals:
1. To understand the behavior of interrupts.
2. To write and debug an interrupt service routine.
3. To understand the advantages and disadvantages of interrupts relative to polling.
4. To further deepen your understanding of the UART device operation.
Prelab questions:
1. What address does a PowerPC processor branch to on an external interrupt? (Hint:
Table 7-1 of the MPC823 book gives offsets for the various interrupt types. If the IP
bit in the MSR is 0, these offsets are added to a base address of 0; if MSR[IP] is 1, the
offsets are added to 0xFFF00000. See pp. 6-20 and 6-21 for a brief description of the
MSR and the IP bit. Assume that MSR[IP] is 0.)
2. How many instructions can you put at this address? What would happen if you put
more than this number there? How can you get around this restriction?
3. Which registers must your interrupt service routine save and restore if it is a leaf
routine (i.e., it calls no other functions)? If your ISR uses no registers itself but calls
other functions written according to the ABI, which registers must it save and restore?
4. Read the description of the UART interrupt capabilities below. Assume that you
have enabled receiver-full interrupts on the UART and enabled the PowerPC external
interrupt (set MSR[EE] to 1). However, your ISR does nothing (it is simply an rfi).
What will happen when the first character is received at the UART?
5. When (under what circumstances) will you want receiver-full interrupts enabled?
When will you want transmitter-empty interrupts enabled?
pf3
pf4
pf5

Partial preview of the text

Download Lab 4: Using External Interrupts - Design Microprocessor Systems | EECS 373 and more Lab Reports Electrical and Electronics Engineering in PDF only on Docsity!

EECS 373 Fall 1998

Lab 4: Using External Interrupts

(revised Oct. 15 1:30 PM)

Introduction:

In this lab, you will modify your code from Lab 3 to use external interrupts from the UART device to notify the CPU when characters can be transmitted or received. The use of interrupts eliminates the need to poll the UART in the main program, freeing the CPU for other tasks. You will have the CPU run your LED-flashing program from Lab 2 while it uses interrupts to handle the communications tasks from Lab 3. As in Lab 3 you will use a device-driver interface to make your program independent of UART details; you will write the device-driver functions for the simulated UART and we will supply the functions for the target board UART.

Goals:

  1. To understand the behavior of interrupts.
  2. To write and debug an interrupt service routine.
  3. To understand the advantages and disadvantages of interrupts relative to polling.
  4. To further deepen your understanding of the UART device operation.

Prelab questions:

  1. What address does a PowerPC processor branch to on an external interrupt? (Hint: Table 7-1 of the MPC823 book gives offsets for the various interrupt types. If the IP bit in the MSR is 0, these offsets are added to a base address of 0; if MSR[IP] is 1, the offsets are added to 0xFFF00000. See pp. 6-20 and 6-21 for a brief description of the MSR and the IP bit. Assume that MSR[IP] is 0.)
  2. How many instructions can you put at this address? What would happen if you put more than this number there? How can you get around this restriction?
  3. Which registers must your interrupt service routine save and restore if it is a “leaf” routine (i.e., it calls no other functions)? If your ISR uses no registers itself but calls other functions written according to the ABI, which registers must it save and restore?
  4. Read the description of the UART interrupt capabilities below. Assume that you have enabled receiver-full interrupts on the UART and enabled the PowerPC external interrupt (set MSR[EE] to 1). However, your ISR does nothing (it is simply an rfi). What will happen when the first character is received at the UART?
  5. When (under what circumstances) will you want receiver-full interrupts enabled? When will you want transmitter-empty interrupts enabled?
  1. Rewrite your blocking ser_getchar and ser_putchar functions from Lab 3 in C using only calls to ser_getchar_nb, ser_putchar_nb, ser_checkrcv, and ser_checkxmit.
  2. Write out a high-level description of how your terminal interface program will work using the interrupt handling modifications. Remember that all of your code other than initialization should be executed as part of an interrupt service routine. You should not nest interrupts for this lab.

Program specification:

The functional program specification from Lab 3 is unchanged. You are to modify your program from Lab 3 to be completely interrupt-driven. This means that all processing (other than initialization) will occur as part of an interrupt service routine. In addition, your interrupt service routine should never block (wait) for the UART. (That is, you should not use the blocking ser_getchar and ser_putchar functions from Lab 3.) In any situation where you are waiting for the UART to be ready to transmit or receive, your ISR should resume the main program. Of course, you must make sure that an interrupt will occur (re-invoking the ISR) when the UART becomes ready.

Interrupt-driven I/O allows the CPU to perform other tasks instead of busy-waiting for the I/O device. Use your Lab 2 LED-flashing program as the main program. Other than adding some initialization code to the beginning, you should not have to change your Lab 2 code at all.

The simulated UART (like most UARTs) is capable of interrupting the CPU under two conditions: when the receiver data buffer is full and/or when the transmitter data buffer is empty. Note that these are the exact conditions under which the UART sets the RF bit of the RSTAT register and the TE bit of the TSTAT register, respectively (see the Lab 3 handout). Whether or not the interrupt line is actually asserted under these conditions is controlled by the IR (interrupt on receiver full) and IT (interrupt on transmitter empty) bits of the IRQCTRL UART control register (see the Details section below). In C notation, the UART will assert the CPU’s external interrupt signal if:

(RSTAT[RF] && IRQCTRL[IR]) || (TSTAT[TE] && IRQCTRL[IT])

Of course, asserting the external interrupt signal will interrupt the CPU only if the CPU’s MSR[EE] bit is set. Since both receiver-full and transmitter-empty conditions assert the same external interrupt signal, your ISR will have to determine which condition caused the interrupt.

The additional device-driver functions that you need to write for the simulated UART are as follows:

Function Name Parameters Return Value Function

ser_enable_tx_int none none enable transmitter-empty interrupts

ser_disable_tx_int none none disable transmitter-empty interrupts

  1. The linker is in charge of assigning specific addresses to your instructions and data. It does this on the basis of sections (a.k.a. segments ), which are contiguous memory regions that you define in the assembler. The linker command file (e.g., lab2-lnk.txt) tells the linker where to put each section that you define. To set up your interrupt handlers, put each handler in a new section using the “.section” directive. For example, .section ext_int_vec, text will put the following code in a section named “ext_int_vec” of type text. Then edit the linker command file, adding a line like: ext_int_vec ADDRESS 0x nnnn : which will place the section “ext_int_vec” at address 0x nnnn. Note that the “.data” and “.text” directives you’ve used already are just shorthand for “.section .data, data” and “.section .text, text”, respectively.
  2. To tell the simulator that it’s OK to simulate external interrupts, you need to go to the Run menu, select Exception Simulation, select “external interrupts” and click OK.
  3. Because of an apparent bug in the simulator, it will complain if you don’t also simulate “decrementer” interrupts. Therefore you must also select “decrementer” in the same dialog box and click OK, and provide an interrupt service routine for decrementer interrupts. This ISR can be just a single instruction (rfi). The offset for decrementer interrupts is 0x700.
  4. See the notes and hints sections from Labs 2 and 3.

Procedure (in the lab):

  1. If you have not thoroughly tested your program under the simulator, do so before trying to run the code on the target board.
  2. After you have verified the operation as completely as possible on the simulator, start the SingleStep OnChip debugger and download your program to the target board.
  3. Set a breakpoint in your ISR after the instructions that save SRR0 and SRR1. Single- step through your ISR to verify its behavior. Observe the values of SRR0 and SRR1. Are these always the same, or do they differ from interrupt to interrupt? What instruction(s) in your main program typically get interrupted? Make sure you observe both receiver-full and transmitter-empty interrupts.
  4. Set a breakpoint on the very first instruction of your ISR and resume the program. After you reach this breakpoint, single-step until you save SRR0 and SRR1. What values have you saved for SRR0 and SRR1? What will happen if you continue the program? Try it and verify your prediction.
  5. Use the oscilloscope or the logic analyzer to monitor both RS-232 signals (transmit and receive) simultaneously (i.e., on different channels). Adjust the time and voltage scales so that you can see both the character transmitted from HyperTerminal and the echoed character from the target board. What is the delay from the first edge of the

transmitted character to the first edge of the echoed character? Repeat this measurement for several characters.

  1. Run your (non-interrupt-driven) Lab 3 program and repeat the previous step. What is the echo delay now? Again, repeat this measurement for several characters.
  2. Print a listing file of your complete program and demonstrate it to the TA. The TA will sign your listing. Turn the signed copy in with your lab report.

Lab report: (due at the beginning of your next lab section)

  1. Briefly summarize the function of your program.
  2. Describe how your program operates: the individual steps and algorithms involved. Be thorough but not verbose; two or three paragraphs should be sufficient.
  3. Include a well-commented listing of your program. Comments should include register usage (i.e. which variables are kept in which registers), descriptions of all symbols, and explanation of all derived expressions. If you add comments after you demonstrate to the TA, be sure to include both the commented listing and the signed listing.
  4. Discuss any difficulties you may have had in getting your program to work correctly: what parts of the program were hard to write initially, what types of bugs did you have to fix, etc. Be sure to discuss any problems or potential problems in debugging caused by using interrupts.
  5. Did you see a difference in the echo delay of your Lab 4 program compared to your Lab 3 program? If yes, discuss possible reasons for this difference.
  6. Another way to revise your Lab 3 program using interrupts is to leave the command- line processing in the main program, and use interrupts only to add characters to the line buffer and send characters from a transmit buffer. That is, the ISR would read characters from the UART as in your current program. However, when “enter” was received, the ISR would set a flag which would tell the main program to process the line. Would this be simpler or more complex than your current program? Why? What are the potential advantages of this approach? (Consider adding other commands that may take a long time to process.)
  7. Discuss any limitations or inaccuracies your program may have. How do the interrupts affect the execution of your Lab 2 program?