[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Timer resolution et al : Implementation of Read_timer()



Hallo all,
I send patch to clock/ckinit.c file of i386/pc386 based bsps.
It contains procedure clock_read giving (I hope) microsecond accuracy.
I know it is ugly, sorry.

It fills timeval struct as follows:
tv_sec  - contains number of ticks(rtems ticks not timer0) from big-bang
tv_usec - microseconds elapsed from last tick.
I don't want to create new struct an I used what was available.
I think that maybe it will be beter if functions clock_read will return
microsecs from clock statrt as uint64, but I'm not sure.

Also I attached trivial test/example application
based on hallo example.

Gregory Matus


****** ckinit.c patch ******

38a39
> #include <sys/time.h>
61a63,96
> /* needed by Clock_read, filled by clockOn()  */
> static   rtems_unsigned32  microseconds_per_isr;
> 
> /*-------------------------------------------------------------------------+
> |         Function: Clock_read
> |      Description: read current 'time' elapsed since clock start with
> |                   microsecond precision
> | Global Variables: 
> |        Arguments:  
> |          Returns: parg->tv_sec  is Clock_driver_ticks since clock start
> |                   parg->tv_usec is microsecs elapsed since last
> |                                 Clock_driver_tick occurance
> +--------------------------------------------------------------------------*/
> void Clock_read(struct timeval *parg)
> {
>   unsigned long clock_ticks_elapsed;
>   unsigned long clock_isrs_elapsed;
>   unsigned long timer0_ticks;
>   unsigned32 level;
>   unsigned8 msb,lsb;
> 
>   _CPU_ISR_Disable(level);
>     outport_byte(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
>     inport_byte(TIMER_CNTR0, lsb);
>         inport_byte(TIMER_CNTR0, msb);
>         clock_ticks_elapsed = Clock_driver_ticks;
>         clock_isrs_elapsed = Clock_isrs_per_tick - Clock_isrs;
>       _CPU_ISR_Enable(level); 
> 
>       timer0_ticks = (msb << 8) | lsb;
>       parg->tv_sec = clock_ticks_elapsed;
>       parg->tv_usec = (clock_isrs_elapsed * microseconds_per_isr 
>       + TICK_TO_US(US_TO_TICK(microseconds_per_isr) - timer0_ticks));
> }
122,123c157,158
<   rtems_unsigned32  microseconds_per_isr;
< 
---
> /*  rtems_unsigned32  microseconds_per_isr;
> */


*********** test.c *************

/*
 *  Simple test program -- simplified version of sample test hello.
 */

#include <bsp.h>

#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

extern void Clock_read(struct timeval *);

rtems_task Init(
  rtems_task_argument ignored
)
{
        struct timeval start, end;
  struct timeval diff;

  printf( "\n\n*** HELLO WORLD TEST ***\n" );
  printf( "Hello World\n" );
        Clock_read(&start);
        printf("foo\n");
/*      rtems_task_wake_after(144);
*/
        Clock_read(&end);
        diff.tv_sec = end.tv_sec - start.tv_sec;
        diff.tv_usec = end.tv_usec - start.tv_usec;
        if ( diff.tv_usec < 0 )
                diff.tv_usec = -diff.tv_usec;
        printf("Diff is ticks %ld and useks %ld\n", diff.tv_sec, diff.tv_usec);
  printf( "*** END OF HELLO WORLD TEST ***\n" );
  exit( 0 );
}

/* configuration information */

#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER

#define CONFIGURE_TEST_NEEDS_CLOCK_DRIVER
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE

#define CONFIGURE_MAXIMUM_TASKS 1

#define CONFIGURE_INIT

#include <confdefs.h>

/* end of file */