Pages

21 Jun 2012

Cs401 4th assignment soltuion spring 2012

Short this in your own words..

Solution:

In computing and in embedded systems, a programmable interval timer (PIT) is a counter which triggers an interrupt when it reaches the programmed count
PITs counters may be one-shot or periodic. One-shot timers interrupt only once, and then stop counting. Periodic timers interrupt every time they reach a specific value. This interrupt is received at regular intervals from the programmable interval timer. This interrupt is used to invoke kernel activities that must be performed on a regular basis. Counters are usually programmed with fixed increment intervals which determine how long the counter counts before it triggers an interrupt. The interval increments therefore determine the resolution for which the counter may be programmed to generate its one-shot or periodic interrupt
IBM PC compatible
The Intel 8253 PIT was the original timing device used on IBM PC compatibles. It used a 1.193182 MHz clock signal (one third of the color burst frequency used by NTSC, one twelfth of the system clock crystal oscillator) and contains three timers. Timer 0 is used by Microsoft Windows (uniprocessor) and Linux as a system timer, timer 1 was historically used for dynamic random access memory refreshes and timer 2 for the PC speaker.

Programmable Interval Timer (PIT)
Besides the Real Time Clock and the Time Stamp Counter, IBM-compatible PCs include another type of time-measuring device called Programmable Interval Timer(PIT). The role of a PIT is similar to the alarm clock of a microwave oven: it makes the user aware that the cooking time interval has elapsed. Instead of ringing a bell, this device issues a special interrupt called timer interrupt, which notifies the kernel that one more time interval has elapsed.[] Another difference from the alarm clock is that the PIT goes on issuing interrupts forever at some fixed frequency established by the kernel. Each IBM-compatible PC includes at least one PIT, which is usually implemented by an 8254 CMOS chip using the 0x40-0x43 I/O ports.
[] The PIT is also used to drive an audio amplifier connected to the computer's internal speaker.
As we'll see in detail in the next paragraphs, Linux programs the PIT of IBM-compatible PCs to issue timer interrupts on the IRQ 0 at a (roughly) 1000-Hz frequency that is, once every 1 millisecond. This time interval is called a tick, and its length in nanoseconds is stored in the tick_nsec variable. On a PC, tick_nsec is initialized to 999,848 nanoseconds (yielding a clock signal frequency of about 1000.15 Hz), but its value may be automatically adjusted by the kernel if the computer is synchronized with an external clock (see the later section "The adjtimex( ) System Call"). The ticks beat time for all activities in the system; in some sense, they are like the ticks sounded by a metronome while a musician is rehearsing.
Generally speaking, shorter ticks result in higher resolution timers, which help with smoother multimedia playback and faster response time when performing synchronous I/O multiplexing (poll( ) and select( ) system calls). This is a trade-off however: shorter ticks require the CPU to spend a larger fraction of its time in Kernel Mode that is, a smaller fraction of time in User Mode. As a consequence, user programs run slower.
The frequency of timer interrupts depends on the hardware architecture. The slower machines have a tick of roughly 10 milliseconds (100 timer interrupts per second), while the faster ones have a tick of roughly 1 millisecond (1000 or 1024 timer interrupts per second).
A few macros in the Linux code yield some constants that determine the frequency of timer interrupts. These are discussed in the following list.
HZ yields the approximate number of timer interrupts per second that is, their frequency. This value is set to 1000 for IBM PCs.
CLOCK_TICK_RATE yields the value 1,193,182, which is the 8254 chip's internal oscillator frequency.
LATCH yields the ratio between CLOCK_TICK_RATE and HZ, rounded to the nearest integer. It is used to program the PIT.
The PIT is initialized by setup_pit_timer( ) as follows:
spin_lock_irqsave(&i8253_lock, flags);
outb_p(0x34,0x43);
udelay(10);
outb_p(LATCH & 0xff, 0x40);
udelay(10);
outb
(LATCH >> 8, 0x40);
spin_unlock_irqrestore(&i8253_lock, flags);
The outb( ) C function is equivalent to the outb assembly language instruction: it copies the first operand into the I/O port specified as the second operand. The outb_p( ) function is similar to outb( ), except that it introduces a pause by executing a no-op instruction to keep the hardware from getting confused. The udelay() macro introduces a further small delay (see the later section "Delay Functions"). The first outb_ p( ) invocation is a command to the PIT to issue interrupts at a new rate. The next two outb_ p( ) and outb( ) invocations supply the new interrupt rate to the device. The 16-bit LATCH constant is sent to the 8-bit 0x40 I/O port of the device as two consecutive bytes. As a result, the PIT issues timer interrupts at a (roughly) 1000-Hz frequency (that is, once every 1 ms).
Solution:

an interrupt is a process or a signal that stops a microprocessor/microcontroller from what it is doing so that something else can happen. Let me give you an every day example. Suppose you are sitting at home, chatting to someone. Suddenly the telephone rings. You stop chatting, and pick up the telephone to speak to the caller. When you have finished your telephone conversation, you go back to chatting to the person before the telephone rang. You can think of the main routine as you chatting to someone, the telephone ringing causes you to interrupt your chatting, and the interrupt routine is the process of talking on the telephone. When the telephone conversation has ended, you then go back to your main routine of chatting. This example is exactly how an interrupt causes a processor to act. The main program is running, performing some function in a circuit, but when an interrupt occurs the main program halts while another routine is carried out. When this routine finishes, the processor goes back to the main routine again.
The PIC has 4 sources of interrupt. They can be split into two groups. Two are sources of interrupts that can be applied externally to the PIC, while the other two are internal processes. We are going to explain the two external ones here. The other two will be explained in other tutorials when we come to look at timers and storing data.
If you look at the pin-out of the PIC, you will see that pin 6 shows it is RB0/INT. Now, RB0 is obviously Port B bit 0. The INT symbolizes that it can also be configures as an external interrupt pin. Also, Port B bits 4 to 7 (pins 10 to 13) can also be used for interrupts. Before we can use the INT or other Port B pins, we need to do two things. First we need to tell the PIC that we are going to use interrupts. Secondly, we need to specify which port B pin we will be using as an interrupt and not as an I/O pin.
Inside the PIC there is a register called INTCON, and is at address 0Bh. Within this register there are 8 bits that can be enabled or disabled. Bit 7 of INTCON is called GIE. This is the Global Interrngupt Enable. Setting this to 1 tells the PIC that we are going to use an interrupt. Bit 4 of INTCON is called INTE, which means INTerrupt  Enable. Setting this bit to 1 tells the PIC that RB0 will be an interrupt pin. Setting bit 3, called RBIE, tells the PIc that we will be using Port B bits 4 to 7.  Now the PIC knows when this pin goes high or low, it will need to stop what it’s doing and get on with an interrupt routine. Now, we need to tell the PIC whether the interrupt is going to be on the rising edge (0V to +5V) or the falling edge (+5V to 0V) transition of the signal. In other words, do we want the PIC to interrupt when the signal goes from low to high, or from high to low. By default, this is set up to be on the rising edge. The edge ‘triggering’ is set up in another register called the OPTION register, at address 81h. The bit we are interested in is bit 6, which is called INTEDG. Setting this to 1 will cause the PIC to interrupt on the rising edge (default state) and setting it to 0 will cause the PIC to interrupt on the falling edge. If you want the PIC to trigger on the rising edge, then you don’t need to do anything to this bit. Now, unfortunately, the Option register is in Bank 1, which means that we have to change from bank 0 to bank 1, set the bit in the Option register, then come back to bank 0. The trick here is to do all of the Bank 1 registers in one hit, such as setting up the port pins, then coming back to Bank 0 when you are finished.
Ok, so now we have told the PIC which pin is going to be the interrupt, and on which edge to trigger, what happens in the program and the PIC when the interrupt occurs? Two things happen. First, a ‘flag’ is set. This tells the internal processor of the PIC that an interrupt has occurred.  Secondly, the program counter (which we mentioned in the last tutorial) points to a particular address within the PIC. Let’s quickly look at each of these separately.

Interrupt Flag

In our INTCON register, bit 1 is the interrupt flag, called INTF. Now, when any interrupt occurs, this flag will be set to 1. While there isn’t an interrupt, the flag is set to 0. And that is all it does. Now you are probably thinking ‘what is the point?’  Well, while this flag is set to 1, the PIC cannot, and will not, respond to any other interrupt. So, let’s say that we cause an interrupt. The flag will be set to 1, and the PIC will go to our routine for processing the interrupt. If this flag wasn’t set to 1, and the PIC was allowed to keep responding to the interrupt, then continually pulsing the pin will keep the PIC going back to the start of our interrupt routine, and never finishing it. Going back to my  example of the telephone, it’s like picking up the telephone, and just as soon as you start to speak it starts ringing again because someone else want to talk to you. It is far better to finish one conversation, then pick up the phone again to talk to the second person.
There is a slight drawback to this flag. Although the PIC automatically sets this flag to 1, it doesn’t set it back to 0! That task has to be done by the programmer – i.e. you. This is easily done, as We are sure you can guess, and has to be done after the PIC has executed the interrupt routine.

Memory Location

When you first power up the PIC, or if there is a reset, the Program Counter points to address 0000h, which is right at the start of the program memory. However, when there is an interrupt, the Program Counter will point to address 0004h. So, when we are writing our program that is going to have interrupts, we first of all have to tell the PIC to jump over address 0004h, and keep the interrupt routine which starts at address 0004h separate from the rest of the program. This is very easy to do.
First, we start our program with a command called ORG. This command means Origin, or start.  We follow it with an address. Because the PIC will start at address 0000h, we type ORG 0000h. Next we need to skip over address 0004h. We do this by placing a GOTO instruction, followed by a label which points to our main program. We then follow this GOTO command with another ORG, this time with the address 0004h. It is after this command that we enter our interrupt routine. Now, we could either type in our interrupt routine directly following the second ORG command, or we can place a GOTO statement which points to the interrupt routine. It really is a matter of choice on your part. To tell the PIC that it has come to the end of the interrupt routine we need to place the command RTFIE at the end of the routine. This command means return from the interrupt routine. When the PIC see this, the Program Counter points to the last location the PIC was at before the interrupt happened. We have shown below a short segment of code to show the above:
            ORG    0000h  ;PIC starts here on power up and reset
            GOTO  start    ;Goto our main program
            ORG    0004h  ;The PIC will come here on an interrupt
            :                     ;This is our interrupt routine that we
            :                     ;want the PIC to do when it receives
            :                     ;an interrupt
            RETFIE           ;End of the interrupt routine
            start               ;This is the start of our main program.
There are two things you should be aware of when using interrupts. The first is that if you are using the same register in your main program and the interrupt routine, bear in mind that the contents of the register will probably change when the interrupt occurs. For example, let’s you are using the w register to send data to Port A in the main program, and you are also using the w register in the interrupt routine to move data from one location to another. If you are not careful, the w register will contain the last value it had when it was in the interrupt routine, and when you come back from the interrupt this data will be sent to Port A instead of the value you had before the interrupt happened. The way round this is to temporarily store the contents of the w register before you use it again in the interrupt routine. The second is that there is a delay between when one interrupt occurs and when the next one can occur.

0 comments:

Post a Comment