diff options
Diffstat (limited to 'main/common/timestuff.c')
-rw-r--r-- | main/common/timestuff.c | 449 |
1 files changed, 228 insertions, 221 deletions
diff --git a/main/common/timestuff.c b/main/common/timestuff.c index 5cab2d3..d5ba4cf 100644 --- a/main/common/timestuff.c +++ b/main/common/timestuff.c @@ -1,7 +1,7 @@ /************************************************************************** * * Copyright (c) 2013 Alcatel-Lucent - * + * * Alcatel Lucent licenses this file to You under the Apache License, * Version 2.0 (the "License"); you may not use this file except in * compliance with the License. A copy of the License is contained the @@ -33,31 +33,31 @@ * with this calibration the accuracy of this mechanism is limited; * however, since there is no code in the monitor that really requires * extremely accurate timing this may be ok. - * + * * On the other hand, it is preferrable to have accuracy, so on targets * that have a pollable clock, the hooks can be put in place to allow - * that clock to be used as the hardware assist for the monitor's - * elapsed time measurements. The INCLUDE_HWTMR is set to 1, and + * that clock to be used as the hardware assist for the monitor's + * elapsed time measurements. The INCLUDE_HWTMR is set to 1, and * TIMER_TICKS_PER_MSEC defines the number of ticks of the timer that - * correspond to 1 millisecond of elapsed time. The function target_timer() + * correspond to 1 millisecond of elapsed time. The function target_timer() * is assumed to be established and must return an unsigned long value * that is the content of the polled hardware timer. * * Regardless of the hardware-assist or not, the following interface is * used by the code in the monitor... * - * #include "timer.h" + * #include "timer.h" * - * struct elapsed_tmr tmr; + * struct elapsed_tmr tmr; * - * startElapsedTimer(&tmr,TIMEOUT): - * do { - * SOMETHING(); - * } while(!msecElapsed(&tmr)); + * startElapsedTimer(&tmr,TIMEOUT): + * do { + * SOMETHING(); + * } while(!msecElapsed(&tmr)); * * Refer to the functions startElapsedTimer() and msecElapsed() below for * more details. - * + * * Original author: Ed Sutter (ed.sutter@alcatel-lucent.com) * */ @@ -75,11 +75,11 @@ * with the number of ticks that must elapse for the timer to expire. * * In the case of the non-hardware-assisted timer, the expiration count - * is based on the value of LoopsPerMillisecond (derived from the + * is based on the value of LoopsPerMillisecond (derived from the * LOOPS_PER_SECOND definition in config.h). Each time msecElapsed() * is called the elapsed count is incremented until it exceeds the timeout * timeout_low timeout_high values recorded by startElapsedTimer(). - * + * * The case of the hardware-assisted timer is similar except that now * the number of ticks initialized in timeout_low and timeout_high are * based on the tick rate of the hardware timer (TIMER_TICKS_PER_MSEC). @@ -89,53 +89,54 @@ * * Notice that 64-bit values are used (high & low) because a 32-bit value * isn't large enough to deal with the tick rates (per second) of various - * CPUs. + * CPUs. */ void startElapsedTimer(struct elapsed_tmr *tmr, long milliseconds) { - unsigned long new_tm_low; - unsigned long stepmsecs, stepticks, remainder; + unsigned long new_tm_low; + unsigned long stepmsecs, stepticks, remainder; #if INCLUDE_HWTMR - tmr->tmrflags = HWTMR_ENABLED; - tmr->tpm = (unsigned long)TIMER_TICKS_PER_MSEC; + tmr->tmrflags = HWTMR_ENABLED; + tmr->tpm = (unsigned long)TIMER_TICKS_PER_MSEC; #else - tmr->tmrflags = 0; - tmr->tpm = (unsigned long)LoopsPerMillisecond; + tmr->tmrflags = 0; + tmr->tpm = (unsigned long)LoopsPerMillisecond; #endif - - tmr->elapsed_low = 0; - tmr->elapsed_high = 0; - tmr->timeout_high = 0; - tmr->timeout_low = 0; - - /* Convert incoming timeout from a millisecond count to a - * tick count... - * Maximum number of milliseconds and ticks before 32-bit - * (tick counter) unsigned long overlaps - */ - stepmsecs = 0xffffffff / tmr->tpm; - stepticks = stepmsecs * tmr->tpm; - remainder = (milliseconds % stepmsecs); - - /* Take care of the step remainder - */ - tmr->timeout_low = remainder * tmr->tpm; - milliseconds -= remainder; - - for (;milliseconds; milliseconds -= stepmsecs) { - new_tm_low = tmr->timeout_low + stepticks; - - if (new_tm_low < tmr->timeout_low) - tmr->timeout_high++; - tmr->timeout_low = new_tm_low; - } - + + tmr->elapsed_low = 0; + tmr->elapsed_high = 0; + tmr->timeout_high = 0; + tmr->timeout_low = 0; + + /* Convert incoming timeout from a millisecond count to a + * tick count... + * Maximum number of milliseconds and ticks before 32-bit + * (tick counter) unsigned long overlaps + */ + stepmsecs = 0xffffffff / tmr->tpm; + stepticks = stepmsecs * tmr->tpm; + remainder = (milliseconds % stepmsecs); + + /* Take care of the step remainder + */ + tmr->timeout_low = remainder * tmr->tpm; + milliseconds -= remainder; + + for(; milliseconds; milliseconds -= stepmsecs) { + new_tm_low = tmr->timeout_low + stepticks; + + if(new_tm_low < tmr->timeout_low) { + tmr->timeout_high++; + } + tmr->timeout_low = new_tm_low; + } + #if INCLUDE_HWTMR - tmr->tmrval = target_timer(); + tmr->tmrval = target_timer(); #else - tmr->tmrval = 0; + tmr->tmrval = 0; #endif } @@ -143,43 +144,45 @@ startElapsedTimer(struct elapsed_tmr *tmr, long milliseconds) int msecElapsed(struct elapsed_tmr *tmr) { - ulong new_elapsed_low, new_tmrval, elapsed; + ulong new_elapsed_low, new_tmrval, elapsed; - /* If timeout has already occurred, then we can assume that this - * function being called without a matching startElapsedTimer() call. - */ - if (ELAPSED_TIMEOUT(tmr)) - return(1); + /* If timeout has already occurred, then we can assume that this + * function being called without a matching startElapsedTimer() call. + */ + if(ELAPSED_TIMEOUT(tmr)) { + return(1); + } #if INCLUDE_HWTMR - new_tmrval = target_timer(); + new_tmrval = target_timer(); #else - new_tmrval = tmr->tmrval + 1; + new_tmrval = tmr->tmrval + 1; #endif - /* Record how many ticks elapsed since the last call to msecElapsed - * and add that value to the total number of ticks that have elapsed. - */ - elapsed = new_tmrval - tmr->tmrval; - new_elapsed_low = tmr->elapsed_low + elapsed; - - if (new_elapsed_low < tmr->elapsed_low) - tmr->elapsed_high++; - - /* If the total elapsed number of ticks exceeds the timeout number - * of ticks, then we can return 1 to indicate that the requested - * amount of time has elapsed. Otherwise, we record the values and - * return 0. - */ - if ((tmr->elapsed_high >= tmr->timeout_high) && - (new_elapsed_low >= tmr->timeout_low)) { - tmr->tmrflags |= TIMEOUT_OCCURRED; - return(1); - } - - tmr->tmrval = new_tmrval; - tmr->elapsed_low = new_elapsed_low; - return(0); + /* Record how many ticks elapsed since the last call to msecElapsed + * and add that value to the total number of ticks that have elapsed. + */ + elapsed = new_tmrval - tmr->tmrval; + new_elapsed_low = tmr->elapsed_low + elapsed; + + if(new_elapsed_low < tmr->elapsed_low) { + tmr->elapsed_high++; + } + + /* If the total elapsed number of ticks exceeds the timeout number + * of ticks, then we can return 1 to indicate that the requested + * amount of time has elapsed. Otherwise, we record the values and + * return 0. + */ + if((tmr->elapsed_high >= tmr->timeout_high) && + (new_elapsed_low >= tmr->timeout_low)) { + tmr->tmrflags |= TIMEOUT_OCCURRED; + return(1); + } + + tmr->tmrval = new_tmrval; + tmr->elapsed_low = new_elapsed_low; + return(0); } /* msecRemainging(): @@ -188,41 +191,42 @@ msecElapsed(struct elapsed_tmr *tmr) ulong msecRemaining(struct elapsed_tmr *tmr) { - ulong high, low, msectot, leftover, divisor; + ulong high, low, msectot, leftover, divisor; + + if(ELAPSED_TIMEOUT(tmr)) { + return(0); + } - if (ELAPSED_TIMEOUT(tmr)) - return(0); - - high = tmr->timeout_high - tmr->elapsed_high; - low = tmr->timeout_low - tmr->elapsed_low; + high = tmr->timeout_high - tmr->elapsed_high; + low = tmr->timeout_low - tmr->elapsed_low; - msectot = leftover = 0; + msectot = leftover = 0; #if INCLUDE_HWTMR - divisor = (ulong)TIMER_TICKS_PER_MSEC; + divisor = (ulong)TIMER_TICKS_PER_MSEC; #else - divisor = (ulong)LoopsPerMillisecond; + divisor = (ulong)LoopsPerMillisecond; #endif - while(1) { - while (low > divisor) { - msectot++; - low -= divisor; - } - leftover += low; - if (high == 0) - break; - else { - high--; - low = 0xffffffff; - } - } - - while(leftover > divisor) { - msectot++; - low -= divisor; - } - return(msectot); + while(1) { + while(low > divisor) { + msectot++; + low -= divisor; + } + leftover += low; + if(high == 0) { + break; + } else { + high--; + low = 0xffffffff; + } + } + + while(leftover > divisor) { + msectot++; + low -= divisor; + } + return(msectot); } /* monDelay(): @@ -233,13 +237,13 @@ msecRemaining(struct elapsed_tmr *tmr) void monDelay(int milliseconds) { - struct elapsed_tmr tmr; + struct elapsed_tmr tmr; - startElapsedTimer(&tmr,milliseconds); - while(!msecElapsed(&tmr)) { - WATCHDOG_MACRO; - pollethernet(); - } + startElapsedTimer(&tmr,milliseconds); + while(!msecElapsed(&tmr)) { + WATCHDOG_MACRO; + pollethernet(); + } } /* monTimer(): @@ -249,138 +253,141 @@ monDelay(int milliseconds) int monTimer(int cmd, void *arg) { - int rc = 0; - struct elapsed_tmr *tmr = (struct elapsed_tmr *)arg; - - switch(cmd) { - case TIMER_START: - startElapsedTimer(tmr,tmr->start); - break; - case TIMER_ELAPSED: - msecElapsed(tmr); - if (ELAPSED_TIMEOUT(tmr)) - rc = 1; - break; - case TIMER_QUERY: + int rc = 0; + struct elapsed_tmr *tmr = (struct elapsed_tmr *)arg; + + switch(cmd) { + case TIMER_START: + startElapsedTimer(tmr,tmr->start); + break; + case TIMER_ELAPSED: + msecElapsed(tmr); + if(ELAPSED_TIMEOUT(tmr)) { + rc = 1; + } + break; + case TIMER_QUERY: #if INCLUDE_HWTMR - tmr->tmrflags = HWTMR_ENABLED; - tmr->tpm = (unsigned long)TIMER_TICKS_PER_MSEC; - tmr->currenttmrval = target_timer(); + tmr->tmrflags = HWTMR_ENABLED; + tmr->tpm = (unsigned long)TIMER_TICKS_PER_MSEC; + tmr->currenttmrval = target_timer(); #else - tmr->tmrflags = 0; - tmr->tpm = (unsigned long)LoopsPerMillisecond; - tmr->currenttmrval = 0; + tmr->tmrflags = 0; + tmr->tpm = (unsigned long)LoopsPerMillisecond; + tmr->currenttmrval = 0; #endif - break; - default: - rc = -1; - break; - } - return(rc); + break; + default: + rc = -1; + break; + } + return(rc); } #if INCLUDE_TFSSCRIPT /* Sleep(): - * Simple delay loop accessible by the command line. - * This loop count is dependent on the underlying hardware. - * The LoopsPerMillisecond count is loaded with a default at startup, or + * Simple delay loop accessible by the command line. + * This loop count is dependent on the underlying hardware. + * The LoopsPerMillisecond count is loaded with a default at startup, or * it can be calibrated by the user via the -c option. - * Note that this LoopsPerMillisecond value is used in a few other places - * in the monitor also for time-dependent stuff. - * NOTES: - * - This is obviously not real accurate (not intended to be), but allows the - * monitor to be independent of the underlying hardware. - * - The delay time is very dependent on ethernet activity, since the call - * to pollethernet() part of the loop. + * Note that this LoopsPerMillisecond value is used in a few other places + * in the monitor also for time-dependent stuff. + * NOTES: + * - This is obviously not real accurate (not intended to be), but allows the + * monitor to be independent of the underlying hardware. + * - The delay time is very dependent on ethernet activity, since the call + * to pollethernet() part of the loop. */ char *SleepHelp[] = { - "Second or msec delay (not precise)", - "-[clmv:] {count}", + "Second or msec delay (not precise)", + "-[clmv:] {count}", #if INCLUDE_VERBOSEHELP - " -c calibrate new LPS count", - " -l store LPS count", - " -m millisecond", - " -v {LPSvarname}", + " -c calibrate new LPS count", + " -l store LPS count", + " -m millisecond", + " -v {LPSvarname}", #endif - 0, + 0, }; int Sleep(int argc,char *argv[]) { - int opt, calibrate, count, multiplier; - - multiplier = 1000; - calibrate = 0; - while ((opt=getopt(argc,argv,"clmv:")) != -1) { - switch(opt) { - case 'c': - calibrate = 2; - break; - case 'l': - calibrate = 1; - break; - case 'm': - multiplier = 1; - break; - case 'v': - shell_sprintf(optarg,"%d",LoopsPerMillisecond*1000); - return(CMD_SUCCESS); - default: - return(CMD_PARAM_ERROR); - } - } - - /* If no args, just print the current LPS value and return... */ - if (argc == 1) { + int opt, calibrate, count, multiplier; + + multiplier = 1000; + calibrate = 0; + while((opt=getopt(argc,argv,"clmv:")) != -1) { + switch(opt) { + case 'c': + calibrate = 2; + break; + case 'l': + calibrate = 1; + break; + case 'm': + multiplier = 1; + break; + case 'v': + shell_sprintf(optarg,"%d",LoopsPerMillisecond*1000); + return(CMD_SUCCESS); + default: + return(CMD_PARAM_ERROR); + } + } + + /* If no args, just print the current LPS value and return... */ + if(argc == 1) { #if INCLUDE_HWTMR - printf("Hardware-based timer, LPS not applicable\n"); + printf("Hardware-based timer, LPS not applicable\n"); #else - printf("Current LPS = %ld\n",LoopsPerMillisecond * 1000); + printf("Current LPS = %ld\n",LoopsPerMillisecond * 1000); #endif - return(CMD_SUCCESS); - } - - /* For calibration, take in the count on the command line, then use - * it to put out 5 dots dot at the rate of the loop to allow the user - * to adjust it to be about 1 second. - */ - if (calibrate) { + return(CMD_SUCCESS); + } + + /* For calibration, take in the count on the command line, then use + * it to put out 5 dots dot at the rate of the loop to allow the user + * to adjust it to be about 1 second. + */ + if(calibrate) { #if INCLUDE_HWTMR - printf("Hardware-based timer, doesn't calibrate\n"); + printf("Hardware-based timer, doesn't calibrate\n"); #else - long lps; - - if (argc != optind+1) - return(CMD_PARAM_ERROR); - - printf("Current LPS: %ld\n",LoopsPerMillisecond * 1000); - lps = strtol(argv[optind],0,0); - LoopsPerMillisecond = lps/1000; - printf("New LPS: %ld%s\n",LoopsPerMillisecond * 1000, - lps % 1000 ? " (truncated by 1000)" : ""); - - if (calibrate == 2) { - count = 10; - while(count-- > 0) { - monDelay(1000); - putstr(".\007"); - } - putchar('\n'); - } + long lps; + + if(argc != optind+1) { + return(CMD_PARAM_ERROR); + } + + printf("Current LPS: %ld\n",LoopsPerMillisecond * 1000); + lps = strtol(argv[optind],0,0); + LoopsPerMillisecond = lps/1000; + printf("New LPS: %ld%s\n",LoopsPerMillisecond * 1000, + lps % 1000 ? " (truncated by 1000)" : ""); + + if(calibrate == 2) { + count = 10; + while(count-- > 0) { + monDelay(1000); + putstr(".\007"); + } + putchar('\n'); + } #endif - return(CMD_SUCCESS); - } + return(CMD_SUCCESS); + } - if (argc == optind) - count = 1; - else - count = strtol(argv[optind],(char **)0,0); + if(argc == optind) { + count = 1; + } else { + count = strtol(argv[optind],(char **)0,0); + } - monDelay(count * multiplier); - return(CMD_SUCCESS); + monDelay(count * multiplier); + return(CMD_SUCCESS); } #endif |