next up previous
Next: lpt_irq Up: Playing with the Parallel Previous: rt_irq_gen.o

rt_irq_gen.c


#include <rtl.h>
#include <rtl_time.h>
#include <rtl_fifo.h>
#include <asm/rt_irq.h>
#include <asm/rt_time.h>
#include <rtl_sched.h>
#include <asm/io.h>
#include <linux/cons.h>
#include <pthread.h>
#include <time.h>
#include <rtl_sched.h>
#include <rtl_sync.h>
#include <unistd.h>
#include <rtl_debug.h>
#include <errno.h>
#define LPT 0x378
#define LPT_IRQ 7
#define RTC_IRQ 8

struct sample {
   hrtime_t min;
   hrtime_t max;
};

/* all time values in nano-seconds */
#define TIMEOUT 10000000
#define SAMPLES 10

pthread_t thread;
hrtime_t min_response;
hrtime_t max_response;
struct sample samp;
int samples;

void * irq_gen(void *arg) {

/* putting these in registers prevents 
 * additional delays due to load and 
 * store to memory during the timing loop
 */
register int i;
register int orig;

int old_interrupts;
hrtime_t before, after, response;
struct sched_param p;
p . sched_priority = 1;
pthread_setschedparam (pthread_self(), 
   SCHED_FIFO, &p);

pthread_make_periodic_np (pthread_self(), 
   gethrtime(), 100000000);

while (1) {
   min_response = 2000000000;
   max_response = 0;
   for (samples = 0;samples < SAMPLES;samples++){

     /* turn off interrupts so we really get the */
     /* round-trip time by the busy-wait loop */
     rtl_no_interrupts(old_interrupts);
     outb_p(0xf, LPT);  /* ACK is 1 for logic 0 */
     orig = inb_p(LPT + 1);

     outb(0x0, LPT);  /* trigger an interrupt */
     before = gethrtime();
     i = 0;

    /* the busy wait loop,poling the interrupt */
    /* pin of the parallel port .*/
     while ((inb(LPT + 1) == orig) && i++ < TIMEOUT);
        after = gethrtime();

       /* if this loop were not present the system */
       /* would wait for ever until an interrupt is */
       /* polled on ACK of the parport. */
        if (i >= TIMEOUT) {
           rtl_printf("timeout!!!\n");
           return 0;
           }

      response = after - before;
      if (response < min_response) {
         min_response = response;
         }
      if (response > max_response) {
         max_response = response;
         }

     /* restore interrupts before sending */
     /* the thread to sleep */
      rtl_restore_interrupts(old_interrupts);
      pthread_wait_np();
      }
   samp.min = min_response;
   samp.max = max_response;
   rtf_put(0, &samp, sizeof(samp));
   }
   return 0;
}

int init_module(void)
{
rtf_destroy(0);
rtf_create(0, 4000);
return pthread_create (&thread,NULL,irq_gen,0);
}

void cleanup_module(void)
{
rtl\_printf ("Removing rt_gen_irq on CPU %d 
   and clearing ACK on %d\n",rtl_getcpuid(),LPT);
outb_p(0xf, LPT);      /* clear ACK on parport */
pthread_delete_np (thread);
rtf_destroy(0);
}



Der Herr Hofrat
2002-03-08