Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

C program for timing interrupts Files provided timepack_sapc.c ( This is the file you will be modifying according to above instructions) #include #include #include #include

C program for timing interrupts image text in transcribed image text in transcribed Files provided

timepack_sapc.c ( This is the file you will be modifying according to above instructions)

#include #include #include #include #include

typedef enum { FALSE, TRUE } Boolean;

/* PC's 8254 timer: one tick consists of 64K counts at 1193182 counts/sec */ #define COUNTS_PER_SEC 1193182 #define COUNTS_PER_TICK (64*1024) /* This is a double constant--see K&R, p. 37. Doubles are great for conversion constants. Just convert back to int at end if apprpriate */ #define USECS_PER_TICK (1000000.0*COUNTS_PER_TICK/COUNTS_PER_SEC) /* precision = time between possible values, in us */ #define TIMER_PRECISION 1

extern const IntHandler irq0inthand;

static int tickcount; static int startcount; static int timer_running;

void set_timer_count(int count); void irq0inthandc(void); void smalldelay(void);

/* set timer ticking. This is called only once at start of program */ void inittimer() { tickcount = 0; #ifdef DEBUG printf("Disabling interrupts in CPU while setting them up "); #endif cli(); #ifdef DEBUG printf("Setting interrupt gate for timer, irq 0 "); #endif /* irq 0 maps to slot n = 0x20 in IDT for linux setup */ set_intr_gate(TIMER0_IRQ+IRQ_TO_INT_N_SHIFT, &irq0inthand); #ifdef DEBUG printf("Commanding PIC to interrupt CPU for irq 0 "); #endif pic_enable_irq(TIMER0_IRQ); timer_running = 0; /* starts running at call to starttimer */ #ifdef DEBUG printf("Commanding timer to generate a pulse train using max count "); #endif set_timer_count(0); #ifdef DEBUG printf("Enabling interrupts in CPU "); #endif sti(); }

/* This is NEEDED: future ints could find bogus int handler after this * code is overwritten by next download or whatever, requiring reboot. * This is called once at end of program. */ void shutdowntimer() { cli(); #ifdef DEBUG printf("Commanding PIC to shut off irq 0 to CPU "); #endif pic_disable_irq(TIMER0_IRQ); /* disallow irq 0 ints to get to CPU */ sti(); }

/* for the SAPC case: microsecond precision (though not microsecond * *accuracy* because of various overhead times involved) */ void querytimer(int *precision, int *running) { *precision = TIMER_PRECISION; *running = timer_running; return; }

/* start a timed experiment: improve this along with stoptimer */ int starttimer() { startcount = tickcount; timer_running = TRUE; return T_OK; }

/* temporary crude way: better to read the counter and add in the downcounts * (converted to us) since the last tick, and similarly change starttime * to record the starting downcount, and adjust for another partial tick. * Remember that printf takes a *lot* of time!! Don't do it during experiments. */ int stoptimer( int *interval ) { *interval = (tickcount - startcount)*USECS_PER_TICK; #ifdef DEBUG printf("stoptimer reached, returning inaccurate time until fixed "); #endif timer_running = FALSE; return T_OK; }

/* about 10 us on a SAPC (400Mhz Pentium) */ void smalldelay(void) { int i;

for (i=0;i

/* Set up timer to count down from given count, then send a tick interrupt, */ /* over and over. A count of 0 sets max count, 65536 = 2**16 */ void set_timer_count(int count) { outpt(TIMER_CNTRL_PORT, TIMER0|TIMER_SET_ALL|TIMER_MODE_RATEGEN); outpt(TIMER0_COUNT_PORT,count&0xff); /* set LSB here */ outpt(TIMER0_COUNT_PORT,count>>8); /* and MSB here */ smalldelay(); /* give the timer a moment to init. */ }

/* timer interrupt handler */ void irq0inthandc(void) { pic_end_int(); /* notify PIC that its part is done */ tickcount++; /* count the tick in global var */ }

file : timer.c ( this is the code you can get help from)

#include #include #include

#define NTIMES 5 #define MAX 80 void smalldelay1(void); void showcounts(void); void setcount(int count);

int main(void) { int count; char buf[MAX];

printf("Enter count for timer (decimal no.

for (i=0;i

/* Print out timer counts after little delays, to show downcounting. * Note we are assuming the calling overhead to outpt and inpt provide * sufficient delay between the accesses to the same port */ void showcounts() { int i, count[NTIMES];

for (i=0;i /* command timer 0 to latch count: */ outpt(TIMER_CNTRL_PORT, TIMER0|TIMER_LATCH); count[i] = inpt(TIMER0_COUNT_PORT); /* read in LSB of count */ count[i] |= inpt(TIMER0_COUNT_PORT)

/* set count to downcount from, in timer: it gets to 0, starts over */ void setcount(int count) { /* set timer 0 count, mode */ outpt(TIMER_CNTRL_PORT, TIMER0|TIMER_SET_ALL|TIMER_MODE_RATEGEN); outpt(TIMER0_COUNT_PORT,count&0xff); /* set LSB here */ outpt(TIMER0_COUNT_PORT,count>>8); /* and MSB here */ smalldelay1(); /* let timer have a moment */ } Remember, you just need to modify few lines of code for timepack_sapc.c .. No other files are needed !

You're working directly with the hardware device, the Programmable Interval Timer (PIT) with its interrupt handler. This code has been provided to you in a). The timepack_sapc.c as provided can measure time in timer "ticks" at an 18.2-Hz (55 ms/tick) standard PC tick rate.To use the PIT to measure higher precision, you make use of "downcounts" within the timer chip. What you need to do is determine how many counts have downcounted in the timer *since the last tick and compute a higher accuracy time. By doing this at both the start and the end of the time interval being measured, you can compute the elapsed time accurate to a few microseconds, a very respectable timer service. You'll need to modify the timepack_sapc.c to achieve this There are 64K place is 64 1024 downcounts within 1 tick and the time for one downcount to take usec. You will use this value later for your calculations. Example: Event A happens 35000 downcounts before tick 201 Event B happens 43000 downcounts before tick 203 35000 read as downcounts before tick 43000 read as downcounts before tick tick 200 A tick A 202 B tick tick Since timer downcounts count down from 64K at the tick, you need to subtract the register value from 65536 to get the number of downcounts since last tick: number of downcounts since tick - 65536- observed count (in register) Thus the accurate time between A and B is 202 clock ticks + (65536-43000) downcounts - (200 clock ticks (65536-35000) downcounts) -2 clock ticks-8000 downcounts where 1 tick- 64 1024 downcounts, so this whole thing can be expressed in downcounts, and then converted to usecs. Note that you need to *convert* downcounts (an int) to usecs (another int). To do this, cast the downcount value to double, multiply by the correct double conversion factor, and then cast back to int usecs. The idea here is that the conversion factor is itself non-integral, so the needed multiplication by it needs to be in floating point, resulting in a floating point number accurate to about 1 usec, so we might as well cast it back to an int value since ints are easier to work with. See the timer.c in the examples/timer_dir/ directory for a sample C program that reads the timer downcounts- you can take code from this as needed Don't leave any printf's in your final code that output during timing runs!! They take a really long time and ruin the data. Save the timing figures in memory and print them out after the stoptimer call Any private functions or variables you need should be declared static in "timepack_sapc.c", You're working directly with the hardware device, the Programmable Interval Timer (PIT) with its interrupt handler. This code has been provided to you in a). The timepack_sapc.c as provided can measure time in timer "ticks" at an 18.2-Hz (55 ms/tick) standard PC tick rate.To use the PIT to measure higher precision, you make use of "downcounts" within the timer chip. What you need to do is determine how many counts have downcounted in the timer *since the last tick and compute a higher accuracy time. By doing this at both the start and the end of the time interval being measured, you can compute the elapsed time accurate to a few microseconds, a very respectable timer service. You'll need to modify the timepack_sapc.c to achieve this There are 64K place is 64 1024 downcounts within 1 tick and the time for one downcount to take usec. You will use this value later for your calculations. Example: Event A happens 35000 downcounts before tick 201 Event B happens 43000 downcounts before tick 203 35000 read as downcounts before tick 43000 read as downcounts before tick tick 200 A tick A 202 B tick tick Since timer downcounts count down from 64K at the tick, you need to subtract the register value from 65536 to get the number of downcounts since last tick: number of downcounts since tick - 65536- observed count (in register) Thus the accurate time between A and B is 202 clock ticks + (65536-43000) downcounts - (200 clock ticks (65536-35000) downcounts) -2 clock ticks-8000 downcounts where 1 tick- 64 1024 downcounts, so this whole thing can be expressed in downcounts, and then converted to usecs. Note that you need to *convert* downcounts (an int) to usecs (another int). To do this, cast the downcount value to double, multiply by the correct double conversion factor, and then cast back to int usecs. The idea here is that the conversion factor is itself non-integral, so the needed multiplication by it needs to be in floating point, resulting in a floating point number accurate to about 1 usec, so we might as well cast it back to an int value since ints are easier to work with. See the timer.c in the examples/timer_dir/ directory for a sample C program that reads the timer downcounts- you can take code from this as needed Don't leave any printf's in your final code that output during timing runs!! They take a really long time and ruin the data. Save the timing figures in memory and print them out after the stoptimer call Any private functions or variables you need should be declared static in "timepack_sapc.c

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Structured Search For Big Data From Keywords To Key-objects

Authors: Mikhail Gilula

1st Edition

012804652X, 9780128046524

More Books

Students also viewed these Databases questions