What if you read twice, and compared the high byte of each read. If the
high byte matches you know you know the last time read is valid. If the
high byte does not match you need to do it again.
-Curtis.
On Mon, 2005-06-27 at 15:50, danjperron wrote:
> I create an extended 64 bit version of the free running timer.
>
>
> But if I want to use it into some threads, I need to ensure that 2
> threads reading tc4 will read the correct values;
>
> No process interrupts the reading of the low 32 bits tc4 and the
> high 32 bits tc4 sequence. I just don't want a thread reading tc4 at
> the same time than an other one reading the high 32 bits.
>
>
> check my routine , (inspire from Jesse Off ,messages #10), GetFRTime()
>
>
> ////// FreeRunningTimer.c
>
> #include<stdlib.h>
> #include<unistd.h>
> #include<sys/types.h>
> #include<sys/mman.h>
> #include<stdio.h>
> #include<fcntl.h>
>
> #include "FreeRunningTimer.h"
>
>
> int FRTimerHandle=-1;
>
> unsigned char *FRTimerBase=NULL;
> unsigned long *FRTimerLo=NULL;
> unsigned long *FRTimerHi=NULL;
>
> unsigned long FRTimerExtHi=0; // use to go behond 40 bit (extended)
>
>
>
> /* InitFRTimer
> * map physical address
> * return 0 if we can't mapped
> * return 1 if everything ok
> */
>
> int InitFRTimer(void)
> {
> FRTimerHandle= open("/dev/mem",O_RDWR);
> if(FRTimerHandle<0) return(0);
> FRTimerBase =
> mmap(0,getpagesize(),PROT_WRITE|PROT_READ,MAP_SHARED,FRTimerHandle,0x80810000UL);
> if(FRTimerBase == NULL)
> {
> CloseFRTimer();
> return(0);
> }
> FRTimerLo= (unsigned long *) (FRTimerBase + 0x60UL); // get
> Least
> significant long
>
> FRTimerHi= (unsigned long *) (FRTimerBase + 0x64UL); // get
> Most
> significant long
>
> *FRTimerHi=0x100; // start Timer
> return(1);
> }
>
>
> /* CloseFRTimer
> * release map of physical address
> */
>
> void CloseFRTimer(void)
> {
>
> if(FRTimerHandle>=0)
> {
> if(FRTimerBase)
> munmap(FRTimerBase,getpagesize());
> close(FRTimerHandle);
> }
> FRTimerHandle=-1;
> FRTimerBase=NULL;
> FRTimerLo=NULL;
> FRTimerHi=NULL;
> }
>
> /* ResetFRTimer
> * Reset and enable Free running timer
> */
> void ResetFRTimer(void)
> {
> *FRTimerHi= 0;
> *FRTimerHi= 0x100; // enable free running Timer
> FRTimerExtHi=0; // reset extended bit
> }
>
>
> /* GetFRTimer
> * return current free running timer value
> */
>
>
> unsigned long long GetFRTimer(void)
> {
> // need to be run at least once every 300 hours
> // for the extended bit system to work!
>
> unsigned long long tval;
>
> unsigned long HiVal;
>
> // need to disable irq here
> //
> // ??????
>
> tval = *FRTimerLo;
>
>
> HiVal= *FRTimerHi & 0xff;
>
> // need to enable irq here
> //
> // ?????
>
>
>
> if(HiVal < (FRTimerExtHi & 0xff))
> {
> // ok we got a wrapped Timer;
>
> FRTimerExtHi += 0x100; // increment bit 40
> }
> FRTimerExtHi &= ~0xff;
> FRTimerExtHi |= HiVal;
>
> tval |= ((unsigned long long ) FRTimerExtHi) << 32;
>
> return(tval);
> }
>
>
>
>
> ////// FreeRunningTimer.h
>
> #ifndef FREE_RUNNING_TIMER_H
> #define FREE_RUNNING_TIMER_H
>
>
> int InitFRTimer(void);
> void CloseFRTimer(void);
> void ResetFRTimer(void);
> unsigned long long GetFRTimer(void);
>
> #define FRTimerToMs(A) (((unsigned long long) A) / 984ULL)
> #define MsToFRTimer(A) (((unsigned long long) A) * 984ULL)
>
> //#define FRTimerToMs(A) ((unsigned long long) A >> 10)
> //#define MsToFRTimer(A) ((unsigned long long) A << 10)
>
> int IsFRTimerPassed(unsigned long long BaseTime,\
> unsigned long long CurrentTime);
> #endif
>
>
>
>
>
> ////A test program to check if the FRTimer works!
>
> #include<stdio.h>
> #include<stdlib.h>
> #include "freeRunningTimer.h"
>
>
>
> #define OUTPUT_ON 1
> #define OUTPUT_OFF 0
>
>
> void Output(int Value)
> {
> static int phy_out=0; // emulate real output
> unsigned long long tcount;
>
> tcount= GetFRTimer();
> if(phy_out==OUTPUT_ON)
> {
> if(!Value)
> {
> phy_out=OUTPUT_OFF; // emulate off
> printf("Output OFF at %llu
> (ms)\n",FRTimerToMs(tcount));fflush(stdout);
> }
> }
> else
> {
> if(Value)
> {
>
> phy_out=OUTPUT_ON; // emulate on
> printf("Output ON at %llu
> ms\n",FRTimerToMs(tcount));fflush(stdout);
> }
> }
> }
>
>
>
> int main(void)
> {
>
> int cycle;
>
> unsigned long long basecount;
> unsigned long long currentcount;
>
>
> if(!InitFRTimer())
> {
> printf("Unable to Map Free running Timer\n");
> return(1);
> }
>
> ResetFRTimer();
> basecount =0;
>
>
> for(cycle=0;cycle<5;cycle++)
> {
> printf("cycle %d\n",cycle);fflush(stdout);
> while(1)
> {
> currentcount = GetFRTimer()- basecount;
>
>
> if(FRTimerToMs(currentcount) < 1330ULL) // 1.33 seconds
> Output(OUTPUT_ON);
> else
> Output(OUTPUT_OFF);
>
> if(FRTimerToMs(currentcount) > 5000ULL) // 5 seconds
> {
> basecount += MsToFRTimer(5000ULL); // basecount
> to
> next cycle
> break;
> }
> }
> }
>
>
>
> printf("Done\n");
>
> CloseFRTimer();
>
> return(0);
> }
>
>
>
>
>
>
>
>
>
>
>
>
>
> ______________________________________________________________________
> YAHOO! GROUPS LINKS
> 1. Visit your group "ts-7000" on the web.
>
> 2. To unsubscribe from this group, send an email to:
>
>
> 3. Your use of Yahoo! Groups is subject to the Yahoo! Terms of
> Service.
>
>
> ______________________________________________________________________
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|