[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Timer resolution et al : Implementation of Read_timer()
- Date: Sun, 14 Mar 2004 14:25:21 +0100
- From: gregmatu at poczta.onet.pl (Gregory Matus)
- Subject: 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 */