Simple 64-bit timer for mbed. It is a drastically simplified version of Timer64 class by Tom Doyle. It is meant to be used in single-thread applications, where timer is used frequently, while standard 32-bit Timer is not enough.
Fork of Timer64 by
Diff: Timer64.cpp
- Revision:
- 3:8396d3e6eb62
- Parent:
- 2:e89b02820e93
- Child:
- 4:9ca673a83acb
- Child:
- 6:100cf27b43aa
--- a/Timer64.cpp Sun Mar 27 20:44:54 2016 +0000 +++ b/Timer64.cpp Mon Mar 28 16:31:42 2016 +0000 @@ -23,9 +23,10 @@ _totalTimeUsec(0L), _ticker_data(get_us_ticker_data()), _rollOverCheckTimer(NULL), - _rollOverCheckTimerPeriodInMsec(TIMER64_15MINUTE_ROLLOVER_CHECK_IN_MSECS) + _rollOverCheckTimerPeriodInMsec(TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS), + _sem(NULL) { - reset(); + ; } Timer64::~Timer64() @@ -54,6 +55,7 @@ _totalTimeUsec = 0L; _rollOverCheckTimerPeriodInMsec = rolloverCheckTimeInMsec; _rollOverCheckTimer = new RtosTimer(_rollOverCheck, osTimerPeriodic, this); + _sem = new Semaphore(1); _timerInitialized = true; return(TIMER64_OK); @@ -77,112 +79,198 @@ _rollOverCheckTimer->stop(); delete _rollOverCheckTimer; _rollOverCheckTimer = NULL; + delete _sem; + _sem = NULL; return(TIMER64_OK); } + int Timer64::start(void) { - if (!_timerInitialized) - { - return(TIMER64_ERROR_NOT_INITIALIZED); - } - - if (_timerRunning) + int status = TIMER64_OK; + + _sem->wait(); { - return(TIMER64_WARNING_ALREADY_RUNNING); + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else if (_timerRunning) + { + status = TIMER64_WARNING_ALREADY_RUNNING; + } + else + { + _tickerStartTimeUsec = ticker_read(_ticker_data); + _timerRunning = true; + _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); + } } - - _tickerStartTimeUsec = ticker_read(_ticker_data); - _timerRunning = true; - _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); - return(TIMER64_OK); + _sem->release(); + + return(status); } int Timer64::stop(void) { - if (!_timerInitialized) - { - return(TIMER64_ERROR_NOT_INITIALIZED); - } - - if (!_timerRunning) + int status = TIMER64_OK; + + _sem->wait(); { - return(TIMER64_WARNING_ALREADY_STOPPED); + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else if (!_timerRunning) + { + status = TIMER64_WARNING_ALREADY_STOPPED; + } + else + { + _read_us(this); + _timerRunning = false; + _rollOverCheckTimer->stop(); + } } - - read_us(); - _timerRunning = false; - _rollOverCheckTimer->stop(); + _sem->release(); - return(TIMER64_OK); + return(status); } int Timer64::reset(void) { - if (!_timerInitialized) - { - return(TIMER64_ERROR_NOT_INITIALIZED); - } - - if (_timerRunning) + int status = TIMER64_OK; + + _sem->wait(); { - _tickerStartTimeUsec = ticker_read(_ticker_data); - _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else + { + if (_timerRunning) + { + _tickerStartTimeUsec = ticker_read(_ticker_data); + _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); + } + + _totalTimeUsec = 0L; + } } + _sem->release(); - _totalTimeUsec = 0L; - return(TIMER64_OK); + return(status); } -uint64_t Timer64::read_us(int* status) +int Timer64::read_us(uint64_t* timeInUsec) { - if (!_timerInitialized) + int status = TIMER64_OK; + + _sem->wait(); { - if (status) + if (!_timerInitialized) { - *status = TIMER64_ERROR_NOT_INITIALIZED; - } - - return(0L); - } - - if (_timerRunning) - { - timestamp_t ticker_current_timeUsec = ticker_read(_ticker_data); - - // check for ticker time rollover - - if (ticker_current_timeUsec >= _tickerStartTimeUsec) - { - _totalTimeUsec += (uint64_t)(ticker_current_timeUsec - _tickerStartTimeUsec); + status = TIMER64_ERROR_NOT_INITIALIZED; } else { - // rollover! - _totalTimeUsec += (4294967296L - ((uint64_t)_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec; - + if (_timerRunning) + { + *timeInUsec = _read_us(this); + } + else + { + *timeInUsec = _totalTimeUsec; + } } - - _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); - _tickerStartTimeUsec = ticker_current_timeUsec; - } - - return(_totalTimeUsec); + } + _sem->release(); + + return(status); } -uint64_t Timer64::read_ms(int* status) +int Timer64::read_ms(uint64_t* timeInMsec) { - return(read_us(status) / 1000L); + int status = TIMER64_OK; + + _sem->wait(); + { + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else + { + if (_timerRunning) + { + *timeInMsec = _read_us(this)/1000L; + } + else + { + *timeInMsec = _totalTimeUsec/1000L; + } + } + } + _sem->release(); + + return(status); } -double Timer64::read(int* status) +int Timer64::read(double* timeInSec) { - return((double)read_us(status) / 1000000.0L); + int status = TIMER64_OK; + + _sem->wait(); + { + if (!_timerInitialized) + { + status = TIMER64_ERROR_NOT_INITIALIZED; + } + else + { + if (_timerRunning) + { + *timeInSec = (double)_read_us(this)/1000000.0L; + } + else + { + *timeInSec = (double)_totalTimeUsec/1000000.0L; + } + } + } + _sem->release(); + + return(status); } void Timer64::_rollOverCheck(void const* args) { Timer64* timer = (Timer64*)args; - timer->read_us(); + timer->_read_us(timer); return; } + +uint64_t Timer64::_read_us(void const* args) +{ + Timer64* timer = (Timer64*)args; + timestamp_t ticker_current_timeUsec = ticker_read(timer->_ticker_data); + + // check for ticker time rollover + + if (ticker_current_timeUsec >= timer->_tickerStartTimeUsec) + { + timer->_totalTimeUsec += (uint64_t)(ticker_current_timeUsec - timer->_tickerStartTimeUsec); + } + else + { + // rollover! + timer->_totalTimeUsec += (4294967296L - ((uint64_t)timer->_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec; + + } + + timer->_rollOverCheckTimer->start(timer->_rollOverCheckTimerPeriodInMsec); + timer->_tickerStartTimeUsec = ticker_current_timeUsec; + return(timer->_totalTimeUsec); +} +