Fall 2009
Links to all files referenced in the lab and prelab can be found in the Files section at the end of this document.
Interrupts
There are typically two methods by which a microcontroller can gather data from a device connected to it - polling and interrupts. Polling is the process of periodically reading the device to see if it has any information or if an event has occurred. Using interrupts is slightly more complicated. Whenever new data is collected or an event occurs at the device, the device can generate a signal to notify the microcontroller that it should read from the device. When the microcontroller receives an interrupt, it suspends its current processing and passes control to a special subroutine called an interrupt service routine (ISR). The ISR is responsible for acknowledging the interrupt (e.g. clearing a flag) and doing some processing (i.e. reading and storing some new data, incrementing a counter, etc.) based on the interrupt before it returns control to the code that was executing when the interrupt occurred.
For the microcontroller used in the lab, there are on-chip peripherals which are interfaced to the CPU through various control registers. Many of these devices (timers, A/D converters, UARTs, etc) can generate interrupts. It is also possible to allow external devices to generate interrupts via some of the I/O pins, but this goes beyond the scope of this lab.
When an interrupt occurs, the microcontroller stores the current value of the PC to the stack and transfers control to the ISR. The location of the ISR code is stored in a table called the interrupt vector table. The vector table is located at a fixed location in the system. The actual ISR code can reside anywhere in addressable program memory. The processor references this vector table to find the starting address of the ISR. The ISR should always terminate with an RTI instruction, which properly restores the stack and any other register values to the original value before the interrupt occurred.
For any further information on interrupts, please refer to the
lecture notes
or Chapter 5 of the
MC9S12
data
sheet.
Task Scheduling
In this pre-lab, you will answer questions regarding a given schedule. The following terminology is used in this lab:
In previous labs, you have used the APS12C128 to communicate with
hardware
devices such as the timer and the serial communications interface (SCI)
through
polling. In this lab, you will learn how to set-up the chip and these
devices
so that they can communicate using interrupts. For parts 1 and 2,
determine the correct control register settings. For part 3,
analyze task response times.
Part 1: Timer Interrupts
Use the interrupt vector table in Section 1.6.1 of the
MC9S12
data
sheet and the Timer register information in section 15.3.2 of the
MC9S12
data
sheet.
Complete the following table so that the Timer peripheral:
| Register bits |
Value |
| TSCR1: 7 | |
| TSCR2: 7 | |
| TSCR2: 2:0 |
Table 1.1: Timer control register values
Part 2: UART
Interrupts
Use the interrupt vector table in Section 1.6.1 of the data sheet and
the SCI
register information in section 13.3.2 of the data sheet. Complete the
following table so that:
| Register Bits |
Value |
| SCIBDH: [4:0] |
|
| SCIBDL: [7:0] |
|
| SCICR2: 7 |
|
| SCICR2: 6 | |
| SCICR2: 5 | |
| SCICR2: 4 | |
| SCICR2: 3 | |
| SCICR2: 2 |
Table 2.1: SCI control register values
Part 3: Task Scheduling
Complete the following tables and answer the corresponding questions. In the tables below, an empty row or column with a "..." symbol indicates you should add as many rows/columns as are appropriate to complete the calculation.
Review lectures 14 and 15 for more details on scheduling theory.
Part 3.1: Main Loop Schedule
| Task # | Type | Priority | Period (ms) | Execution Time (ms) |
| 1 | main loop | n/a | n/a | 100 ms |
| 2 | main loop | n/a | n/a | 150 ms |
| 3 | ISR | 1 | 50 ms | 3 ms |
| 4 | ISR | 2 | 50 ms | 3 ms |
| 5 | ISR | 3 | 50 ms | 6 ms |
| 6 | ISR | 4 | 50 ms | 6 ms |
Table 3.1: Task Schedule Data
Q1. Compute the worst-case latency for the main loop using the data from Table 3.1. Fill the iterative values into a table like Table 3.2 below. Complete enough iterations for the value of the main loop latency to converge.
| Iteration | 0 | 1 | 2 | ... |
| Main loop contribution | |
|
|
|
| ISR1 latency contribution | |
|
|
|
| ISR2 latency contribution | |
|
|
|
| ... | |
|
|
|
| Total latency | |
|
|
|
Table 3.2: Template for main loop latency calculation.
Q2: The system requirements for a system with the workload in Table 3.1 dictate that tasks 1 and 2 must be executed at least every 500 ms. Can this requirement be met given your calculations from Table 2?
Q3: What must the main loop task periods be changed to in order to be schedulable with 10% margin?
Part 3.2: Non-preemptive ISR
| Task # | ISR Priority | Period (ms) | Execution Time (ms) |
| 1 | 1 | 50 ms | 3 ms |
| 2 | 2 | 50 ms | 3 ms |
| 3 | 3 | 50 ms | 6 ms |
| 4 | 4 | 50 ms | 6 ms |
| 5 | 5 | 100 ms | 30 ms |
| 6 | 6 | 100 ms | 30 ms |
| 7 | 7 | 100 ms | 45 ms |
| 8 | 8 | 130 ms | 45 ms |
Table 3.3: ISR Task Data for Part 3.2
Q4: Suppose a system has the ISR tasks shown in Table
3.3. Assume
that interrupts are never disabled in the main program and that all
ISRs run to
completion (e.g. no preemption).
Complete Table 3.4 to show the iterative calculation for the worst-case
latency
for ISR 6.
| Iteration | 0 | 1 | 2 | ... |
| Worst case lower priority task | |
|
|
|
| ISR1 latency contribution | |
|
|
|
| ISR2 latency contribution | |
|
|
|
| .... | |
|
|
|
| Total latency | |
|
|
|
Table 3.4: Template for ISR6 latency calculation
Q5: What is the worst-case latency for ISR6?
Q6: Does the result in question 5 depend on whether or not there is a main-loop (non-ISR code)? Assume that no part of the (hypothetical) main loop disables interrupts.
Part 3.3: Non-preemptive ISR with Blocking Tasks
Now assume that there are blocking tasks in the main loop that DO disable interrupts, according to the values given Table 3.5:
| Main |
Blocking Time (ms) |
| 1 | 45 ms |
| 2 | 15 ms |
| 3 | 77 ms |
Table 3.5: Main-loop tasks
Q7: Repeat the computation for worst case latency of ISR6. Complete Table 3.6 with the iterative values for your solution
| Iteration | 0 | 1 | 2 | ... |
| Worst case lower priority task | |
|
|
|
| ISR1 latency contribution | |
|
|
|
| ISR2 latency contribution | |
|
|
|
| .... | |
|
|
|
| Total latency | |
|
|
|
Table 3.6: Template for ISR6 latency calculation
Q8: What is the worst-case latency of ISR6 given the blocking tasks in Table 6?
Part 3.4: Preemptive ISR
For this part, assume that the hardware is capable of preempting an ISR when a higher priority interrupt occurs. For this part, assume there are no blocking tasks.
Q9: Using the data in Table 3.3 above, compute the worst case latency for ISR6. Complete Table 3.9 with the iterative values for the computation.
| Iteration | 0 | 1 | 2 | ... |
| Worst case lower priority task | |
|
|
|
| ISR1 latency contribution | |
|
|
|
| ISR2 latency contribution | |
|
|
|
| .... | |
|
|
|
| Total latency | |
|
|
|
Table 3.9: Template for ISR6 latency calculation
Q10: What is the worst-case latency for ISR6 under this system, assuming preemption.
All non-code submissions shall be in a single PDF document.
Part 1: Timer Interrupts
| Blocking
time = 4 |
||
| Task | Period
(Pi) |
Execution
Time (Ci) |
| ISR 1 |
10 |
1 |
| ISR 2 |
15 |
3 |
| ISR 3 |
50 |
8 |
| Main task 4 |
100 |
27 |
| Main task 5 |
200 |
35 |
Refer to the LAB FAQ for more information on lab handin procedures and file type requirements. You MUST follow these procedures or we will not accept your submissions.
In this lab you will build a cyclic executive with two interrupt
service routines. The cyclic executive will combine both C code and
assembly. You will implement interrupt functions in both assembly
and C.
Interrupts
Interrupts can be used to allow multiple tasks to run concurrently on the chip. The code that executes normally (i.e., once main() has started executing) can be considered a foreground task because it runs continuously. The code in an ISR can be considered a background task because it only executes when an interrupt is received and does not execute again until another interrupt is received. Full-scale operating systems are of course much more complex than this, but for many embedded systems this simple approach to tasking does just fine.
Cyclic Executive and ISRs
In the lab, you will use an oscilloscope to measure the performance of the a system which combines main-loop operations with the interrupt service routines (ISRs).
The program shall perform the following:
You have implemented a majority of this functionality in previous
labs. We encourage you to re-use that code for this lab.
In addition to the behaviors described above, the digital outputs on Port B are used to indicate the activity of the processor. For example, while the timer overflow ISR, bit 7 of Port B is set high and is set low otherwise. Refer to the "defines" section of the code to see which bit corresponds to which activity. The relative brightness and frequency of the LEDs connected to port B gives you a sense of which parts of the code are being executed more often. In addition to observing them visually, you will use the oscilloscope monitor these outputs with the oscilloscope to make measurements of the program activity.
The oscilloscopes in the lab are HP 54645. The manual is available here: HP 54600 Series Oscilloscopes User and Service Guide.
In this lab, you make use of a program called RateSender. You can get the command-line syntax by running the program with no arguments. Use Ctrl-C to terminate the program. Note that the program may consume significant resources on your PC, so you may have to stop it in order to record data or use other programs.
Wiring:
Part 1 - Cyclic Executive:
Download the lab 8 skeleton project. Rename your project folder to lab_8_gXX. You will modify the C and assembly files to implement the foreground tasks.Note that some manipulation of the data might be required in moving
it from
the buffer to the UART.
Also note, that the skeleton function has a 5 ms delay at the end of
it. The serial interrupt does not require this delay. It is
used for illustrating timing in Part 4 below.
Once you complete the serial interrupt handler you can test this
functionality using the RateSender.exe
program.
Part 3 - Timer Interrupt:
;foreground task |
;interrupt service routine RTI |
Listing 1.
Listing 1 shows part of a foreground task and part of an
ISR.
Consider this code for the following questions:
Q5: What is the worst-case execution time for the timer ISR?
Q6: How much time elapsed between the two pulses? Compute the theoretical time that it should take the timer to overflow (based on the timer settings in the code) and compare this to your measured value.
Q7: What is the minimum time from one timer ISR to the
next
one? What is the maximum time? How do you explain the fact
that the
maximum time is longer than the timer overflow period.? How do
you
explain that the minimum time is shorter than the overflow
period?
Hint: The explanation for the timing of the min/max period
compared to
the nominal may make more sense in light of your measurement in
Question 9
below.
Part 4.2:
In this part, you will observe the effect interrupt task frequency can have on the operation of the main loop. The procedure for this section assumes you have already loaded the code and connected the serial port as in Part 1.
Q8: fill out Table 4 below per above procedure.
| Send rate (RateSender argument in ms) | Serial receive frequency (Hz) | Cursor measurement (s) | # of main loops | Main loop execution time (s) | Apparent effect on the chasing LED. |
| none (RateSender not running) | 0 |
1.592 | 5 |
0.3184 | Run normally |
| 1000 | 1 |
1.600 | 5 |
0.3200 |
LEDs run more slowly |
| 500 | |
|
|
|
|
| 200 | |
|
|
|
|
| 100 | |
|
|
|
|
| 50 | |
|
|
|
|
| 20 | |
|
|
|
|
| 15 | |
|
|
|
|
| 10 | |
|
|
|
|
| 8 | |
|
|
|
|
| 7 | |
|
|
|
|
| 6 | |
|
|
|
|
| 5 | |
|
|
|
|
| 4 | |
|
|
|
|
| 3 | |
|
|
|
|
Table 4 - Main loop execution time measurements. Some sample values have been filled in to help you understand the meaning of the columns. Note that the data in the samples is NOT accurate and MUST be replaced with your own data.
Q9: Plot the data for Main loop execution time (col 5) vs the Serial receive frequency (col 2) of the data you recorded in table 4. Do not plot the rows you marked as non-functional.
Part 4.3:
In this section, you will measure the response time of the receive interrupt. The procedure for this section assumes you have already loaded the code and connected the serial port as in Part 1.
Q10: What is the time between the beginning of the stop bit and the beginning of the RDRF pulse? How does this compare to the width of one baud (symbol) at the baud rate being used in the code?
Q11: How long does it take the receive ISR to execute?
Part 4.4:
In this section, you will see the effect of blocking tasks on interrupt latency.
#define BLOCK_DURING_LCD"
compiler directive. With this modification, interrupts are masked
during the LCD write sequence, making it a blocking task.Q12: What is the maximum latency of the receive ISR? What can you infer about the length of the blocking task from this information?
Bonus: Q13: The cloud in the measurements you took for part 4.4 indicates that the ISR latency can be any value from a few microseconds to the maximum value you computed in question 6. Explain why the latency can be any value in this range (as opposed to only being the maximum value). (100 words maximum)
All non-code submissions shall be in a single PDF document.
Refer to the LAB FAQ for more information on lab handin procedures and file type requirements. You MUST follow these procedures or we will not accept your submissions.
Also, see the course materials repository page.