I'm going to preface this posting with the assurance that I believe
something is setup incorrectly on my system. Any help in finding out what
that something is would be greatly appreciated.

Every now and again I get a glitch of 1.0 -> 1.5 ms in my real time
processes. I've compiled a ridiculously simple example below, to
illustrate my problem. The following code uses clock_gethrtime to grab two
consecutive times from the CLOCK_REALTIME clock, periodically. If the time
between the two clock grabs is a new maximum, it is recorded.

A typical dmesg looks as follows:

Delay of     192ns near       0ms
Delay of     288ns near      95ms
Delay of     352ns near    1609ms
Delay of     384ns near    1648ms
Delay of     448ns near   23322ms
Delay of 1141792ns near  937517ms
Delay of 1224000ns near 1530446ms

You see the two vastly different scales. The first 5 maximum delays are
under .5 useconds, and don't hurt me. The final 2 maximum delays however,
are larger than a single cycle period (1000000 ns). Any advice?
-Chuck


// Stipped down DAQ code - Chuck

// ***** System headers ***** //
#include <rtl.h>
#include <rtl_sync.h>
#include <time.h>
#include <pthread.h>

// ***** System Definitions ***** //
#define FREQUENCY 1000                      // Thread frequency [=] Hz

// ***** Function Declarations ***** //
void *daq_code(void*);                      // DAQ Periodic function

// ***** Global Variables ***** //
pthread_t daq_thread;                       // main rtlinux thread


// Simple thread measures clock 
void *daq_code(void *param)
{
  rtl_irqstate_t irqstate;

  hrtime_t zero_time,  tick_time, tock_time;
  long     delay_time, delay,     max_delay=0;

  zero_time = clock_gethrtime(CLOCK_REALTIME);

  while (1)      // periodic task, must loop
    {

      // Begin DANGER
      rtl_no_interrupts(irqstate);

      tick_time = clock_gethrtime(CLOCK_REALTIME);
      tock_time = clock_gethrtime(CLOCK_REALTIME);
      delay     = (long)(tock_time - tick_time);

      rtl_restore_interrupts(irqstate);
      // End DANGER


      if (delay > max_delay)
        {
          // reset delay max
          max_delay  = delay;

          // reset time of max, >>20 is ~equal to /1e6
          delay_time = (long)((tock_time - zero_time)>>20);

          printk( "Delay of %7ldns near %7ldms\n", max_delay, delay_time);
        }

      pthread_wait_np( );
    }    
}


// ***** Module Standard Functions ***** ///

int init_module(void)
{
  pthread_attr_t attr;
  struct sched_param sched_param;
  hrtime_t period, soon;

  // initialize pthread attributes
  if( pthread_attr_init(&attr) ) 
    printk( "Cannot initialize pthread attributes\n" );

  // modify pthread priority
  sched_param.sched_priority = 1;
  if ( pthread_attr_setschedparam (&attr, &sched_param) )
    printk( "Cannot set pthread priority: 0\n" );
  
  // initialize the main thread
  if( pthread_create (&daq_thread, &attr, daq_code,(void *)1) )
    printk( "Cannot create pthread\n" );

  // make the thread run off the CPU clock
  period = HRTICKS_PER_SEC / FREQUENCY;
  soon   = clock_gethrtime(CLOCK_REALTIME) + (100 * period);
  if( pthread_make_periodic_np (daq_thread, soon, period) )
    printk( "Cannot make pthread periodic\n" );

  return 0;
}

void cleanup_module(void)
{
  // destroy periodic thread
  if( pthread_delete_np(daq_thread) )
    printk( "Cannot destroy phread\n" );
}


-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/

Reply via email to