64 bit Timer Class.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Timer64.h Source File

Timer64.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2016 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  *
00016  * Modified by Tom Doyle    <ThomasEDoyle@gmail.com>
00017  *
00018  */
00019  
00020 #ifndef __TIMER64__
00021 #define __TIMER64__
00022 
00023 #include "platform.h"
00024 #include "ticker_api.h"
00025 #include <stdint.h>
00026 #include "rtos.h"
00027 
00028 #define TIMER64_OK                                  0
00029 
00030 #define TIMER64_ERROR_NOT_INITIALIZED               -1
00031 #define TIMER64_ERROR_NULL_POINTER                  -2
00032 
00033 #define TIMER64_WARNING_ALREADY_INITIALIZED         1
00034 #define TIMER64_WARNING_ALREADY_RUNNING             2
00035 #define TIMER64_WARNING_ALREADY_STOPPED             3
00036 #define TIMER64_WARNING_ALREADY_RELEASED            4
00037 
00038 #define TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS     30000
00039 #define TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS         1000
00040 #define TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS         65535
00041 
00042 /** Timer64 class
00043  *  Used to define a 64 bit timer64 that is thread safe.  The Timer64 behaves in a 
00044  *  similiar fashion to the mbed Timer class with the most notable exception that 
00045  *  the Timer64 will not rollover after 2^31 microseconds (approximately 35.8 minutes).
00046  *  The Timer64 extends the rollover time to 2^64 microseconds (approximately 585,000 years!)
00047  *
00048  *  The Timer64 class is also designed to be thread safe. The following functions can be 
00049  *  called from any thread after the class is instaniated and initialized:
00050  *  
00051  *  - start()
00052  *  - stop()
00053  *  - reset()
00054  *  - read_us()
00055  *  - read_ms()
00056  *  - read()
00057  *  - reset()
00058  *  - isRunning()
00059  *
00060  *  It is to be noted that the init() and release() methods need to be called from the same thread.
00061  *
00062  *  Give the Timer64 library a try and let me know if it works for you. Will gladly take suggestions
00063  *  on how to make it better.
00064  *
00065  *  Simple Example
00066  *  @code
00067  *  #include "mbed.h"
00068  *  #include "rtos.h"
00069  *  #include "Timer64.h"
00070  *
00071  * Timer64 timer64;
00072  *
00073  *   int main()
00074  *   {
00075  *      uint64_t timeInUsec;
00076  *      timer64.init();
00077  *      timer64.start();
00078  *      Thread::wait(100);
00079  *      timer64.stop();
00080  *      timer64.read_us(&timeInUsec);
00081  *      printf("Test - Elapsed time = %llu usec\n\n", timeInUsec);
00082  *      timer64.reset();
00083  *      timer64.release();
00084  *       
00085  *      while (1)
00086  *      {
00087  *          Thread::wait(1000);
00088  *      }
00089  *  }
00090  *  @endcode
00091 */
00092 
00093 class Timer64
00094 {
00095 
00096 public:
00097     Timer64();
00098     ~Timer64();
00099 
00100     /** Initialize the timer - this must be called before the timer can be used
00101      *  
00102      *  @param rolloverCheckTimeInMsecc specifies how ofter a rollover check is performed.
00103      *      This parameter is bounded by TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS and 
00104      *      TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS with a default value of
00105      *      TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS
00106      *
00107      *  @returns
00108      *      TIMER64_OK,
00109      *      TIMER64_WARNING_ALREADY_INITIALIZED
00110      */
00111     int init(uint32_t rolloverCheckTimeInMsecc = TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS);
00112 
00113     /** Release the timer - must be called from the same thread calling init()
00114      *  
00115      *  @returns
00116      *      TIMER64_OK,
00117      *      TIMER64_WARNING_ALREADY_RELEASED
00118      */
00119     int release(void);
00120 
00121     /** Start the timer - this method is thread safe
00122      *  
00123      *  @returns
00124      *      TIMER64_OK,
00125      *      TIMER64_ERROR_NOT_INITIALIZED,
00126      *      TIMER64_WARNING_ALREADY_RUNNING
00127      */
00128     int start(void);
00129 
00130     /** Stop the timer - this method is thread safe
00131      *  
00132      *  @returns
00133      *      TIMER64_OK,
00134      *      TIMER64_ERROR_NOT_INITIALIZED,
00135      *      TIMER64_WARNING_ALREADY_STOPPED
00136      */
00137     int stop(void);
00138 
00139     /** Reset the timer - this method is thread safe
00140      *  
00141      *  @returns
00142      *      TIMER64_OK,
00143      *      TIMER64_ERROR_NOT_INITIALIZED
00144      */
00145     int reset(void);
00146 
00147     /** Read the timer value in microseconds - this method is thread safe
00148      *  
00149      *  @param timeInUsec specifies a pointer to a uint64_t where to save the current time in microseconds
00150      *
00151      *  @returns
00152      *      TIMER64_OK,
00153      *      TIMER64_ERROR_NOT_INITIALIZED,
00154      *      TIMER64_ERROR_NULL_POINTER
00155      */
00156     int read_us(uint64_t* timeInUsec = NULL);
00157 
00158     /** Read the timer value in milliseconds - this method is thread safe
00159      *  
00160      *  @param timeInMsec specifies a pointer to a uint64_t where to save the current time in milliseconds
00161      *
00162      *  @returns
00163      *      TIMER64_OK,
00164      *      TIMER64_ERROR_NOT_INITIALIZED,
00165      *      TIMER64_ERROR_NULL_POINTER
00166      */
00167     int read_ms(uint64_t* timeInMsec = NULL);
00168 
00169     /** Read the timer value in seconds - this method is thread safe
00170      *  
00171      *  @param timeInMsec specifies a pointer to a double where to save the current time in seconds
00172      *
00173      *  @returns
00174      *      TIMER64_OK,
00175      *      TIMER64_ERROR_NOT_INITIALIZED,
00176      *      TIMER64_ERROR_NULL_POINTER,
00177      */
00178     int read(double* timeInSec = NULL);
00179     
00180     /** Check to see if timer is running - this method is thread safe
00181      *  
00182      *  @param running specifies a pointer to a bool where to save the running status
00183      *
00184      *  @returns
00185      *      TIMER64_OK,
00186      *      TIMER64_ERROR_NOT_INITIALIZED,
00187      *      TIMER64_ERROR_NULL_POINTER
00188      */
00189     int isRunning(bool* running);
00190 
00191 private:
00192     bool _timerInitialized;
00193     bool _timerRunning;                 // whether the timer is running
00194     timestamp_t _tickerStartTimeUsec;   // the start time of the latest slice
00195     uint64_t _totalTimeUsec;            // any accumulated time from previous slices
00196     const ticker_data_t *_ticker_data;
00197     RtosTimer* _rollOverCheckTimer;
00198     uint32_t _rollOverCheckTimerPeriodInMsec;
00199     Semaphore* _sem;
00200     
00201     static void _rollOverCheck(void const* args);
00202     static uint64_t _read_us(void const* args);
00203 };
00204 
00205 #endif  //__TIMER64__