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 Tom Doyle

Committer:
tedoyle
Date:
Fri Apr 01 16:26:49 2016 +0000
Revision:
6:100cf27b43aa
Parent:
3:8396d3e6eb62
?

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tedoyle 6:100cf27b43aa 1 /* mbed Microcontroller Library
tedoyle 6:100cf27b43aa 2 * Copyright (c) 2006-2016 ARM Limited
tedoyle 6:100cf27b43aa 3 *
tedoyle 6:100cf27b43aa 4 * Licensed under the Apache License, Version 2.0 (the "License");
tedoyle 6:100cf27b43aa 5 * you may not use this file except in compliance with the License.
tedoyle 6:100cf27b43aa 6 * You may obtain a copy of the License at
tedoyle 6:100cf27b43aa 7 *
tedoyle 6:100cf27b43aa 8 * http://www.apache.org/licenses/LICENSE-2.0
tedoyle 6:100cf27b43aa 9 *
tedoyle 6:100cf27b43aa 10 * Unless required by applicable law or agreed to in writing, software
tedoyle 6:100cf27b43aa 11 * distributed under the License is distributed on an "AS IS" BASIS,
tedoyle 6:100cf27b43aa 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
tedoyle 6:100cf27b43aa 13 * See the License for the specific language governing permissions and
tedoyle 6:100cf27b43aa 14 * limitations under the License.
tedoyle 6:100cf27b43aa 15 *
tedoyle 6:100cf27b43aa 16 * Modified by Tom Doyle <ThomasEDoyle@gmail.com>
tedoyle 6:100cf27b43aa 17 *
tedoyle 6:100cf27b43aa 18 */
tedoyle 6:100cf27b43aa 19
tedoyle 0:1e0e79e82839 20 #ifndef __NEW_TIMER64__
tedoyle 0:1e0e79e82839 21 #define __NEW_TIMER64__
tedoyle 0:1e0e79e82839 22
tedoyle 0:1e0e79e82839 23 #include "platform.h"
tedoyle 0:1e0e79e82839 24 #include "ticker_api.h"
tedoyle 0:1e0e79e82839 25 #include <stdint.h>
tedoyle 0:1e0e79e82839 26 #include "rtos.h"
tedoyle 0:1e0e79e82839 27
tedoyle 1:497fba179833 28 #define TIMER64_OK 0
tedoyle 0:1e0e79e82839 29
tedoyle 1:497fba179833 30 #define TIMER64_ERROR_NOT_INITIALIZED -1
tedoyle 0:1e0e79e82839 31
tedoyle 1:497fba179833 32 #define TIMER64_WARNING_ALREADY_INITIALIZED 1
tedoyle 1:497fba179833 33 #define TIMER64_WARNING_ALREADY_RUNNING 2
tedoyle 1:497fba179833 34 #define TIMER64_WARNING_ALREADY_STOPPED 3
tedoyle 2:e89b02820e93 35 #define TIMER64_WARNING_ALREADY_RELEASED 4
tedoyle 0:1e0e79e82839 36
tedoyle 3:8396d3e6eb62 37 #define TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS 30000
tedoyle 3:8396d3e6eb62 38 #define TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS 1000
tedoyle 3:8396d3e6eb62 39 #define TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS 65535
tedoyle 0:1e0e79e82839 40
tedoyle 6:100cf27b43aa 41 /** Timer64 class
tedoyle 6:100cf27b43aa 42 * Used to define a 64 bit timer64 that is thread safe. The Timer64 behaves in a
tedoyle 6:100cf27b43aa 43 * similiar fashion to the mbed Timer class with the most notable exception that
tedoyle 6:100cf27b43aa 44 * the Timer64 will not rollover after 2^31 microseconds (approximately 35.8 minutes).
tedoyle 6:100cf27b43aa 45 * The Timer64 extends the rollover time to 2^64 microsecnods (approximately 585,000 years!)
tedoyle 6:100cf27b43aa 46 *
tedoyle 6:100cf27b43aa 47 * The Timer64 class is also designed to be thread safe. The following functions can be
tedoyle 6:100cf27b43aa 48 * called from any thread after the class is instaniated and initialized:
tedoyle 6:100cf27b43aa 49 *
tedoyle 6:100cf27b43aa 50 * - start()
tedoyle 6:100cf27b43aa 51 * - stop()
tedoyle 6:100cf27b43aa 52 * - reset()
tedoyle 6:100cf27b43aa 53 * - read_us()
tedoyle 6:100cf27b43aa 54 * - read_ms()
tedoyle 6:100cf27b43aa 55 * - read()
tedoyle 6:100cf27b43aa 56 * - reset()
tedoyle 6:100cf27b43aa 57 * - isRunning()
tedoyle 6:100cf27b43aa 58 *
tedoyle 6:100cf27b43aa 59 * It is to be noted that the init() and release() methods need to be called from the same thread.
tedoyle 6:100cf27b43aa 60 *
tedoyle 6:100cf27b43aa 61 * Give the Timer64 library a try and let me know if it works for you. Will gladly take suggestions
tedoyle 6:100cf27b43aa 62 * on how to make it better.
tedoyle 6:100cf27b43aa 63 *
tedoyle 6:100cf27b43aa 64 * Simple Example
tedoyle 6:100cf27b43aa 65 * @code
tedoyle 6:100cf27b43aa 66 * #include "mbed.h"
tedoyle 6:100cf27b43aa 67 * #include "rtos.h"
tedoyle 6:100cf27b43aa 68 * #include "Timer64.h"
tedoyle 6:100cf27b43aa 69 *
tedoyle 6:100cf27b43aa 70 * Timer64 timer64;
tedoyle 6:100cf27b43aa 71 *
tedoyle 6:100cf27b43aa 72 * int main()
tedoyle 6:100cf27b43aa 73 * {
tedoyle 6:100cf27b43aa 74 * uint64_t timeInUsec;
tedoyle 6:100cf27b43aa 75 * timer64.init();
tedoyle 6:100cf27b43aa 76 * timer64.start();
tedoyle 6:100cf27b43aa 77 * Thread::wait(100);
tedoyle 6:100cf27b43aa 78 * timer64.stop();
tedoyle 6:100cf27b43aa 79 * timer64.read_us(&timeInUsec);
tedoyle 6:100cf27b43aa 80 * printf("Test - Elapsed time = %llu usec\n\n", timeInUsec);
tedoyle 6:100cf27b43aa 81 * timer64.reset();
tedoyle 6:100cf27b43aa 82 * timer64.release();
tedoyle 6:100cf27b43aa 83 *
tedoyle 6:100cf27b43aa 84 * while (1)
tedoyle 6:100cf27b43aa 85 * {
tedoyle 6:100cf27b43aa 86 * Thread::wait(1000);
tedoyle 6:100cf27b43aa 87 * }
tedoyle 6:100cf27b43aa 88 * }
tedoyle 6:100cf27b43aa 89 * @endcode
tedoyle 6:100cf27b43aa 90 */
tedoyle 6:100cf27b43aa 91
tedoyle 0:1e0e79e82839 92 class Timer64
tedoyle 0:1e0e79e82839 93 {
tedoyle 0:1e0e79e82839 94
tedoyle 0:1e0e79e82839 95 public:
tedoyle 0:1e0e79e82839 96 Timer64();
tedoyle 1:497fba179833 97 ~Timer64();
tedoyle 0:1e0e79e82839 98
tedoyle 1:497fba179833 99 /** Initialize the timer - this must be called before the timer can be used
tedoyle 0:1e0e79e82839 100 */
tedoyle 6:100cf27b43aa 101 int init(uint32_t rolloverCheckTimeInMsecc = TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS);
tedoyle 0:1e0e79e82839 102
tedoyle 0:1e0e79e82839 103 /** Release the timer
tedoyle 0:1e0e79e82839 104 */
tedoyle 0:1e0e79e82839 105 int release(void);
tedoyle 0:1e0e79e82839 106
tedoyle 0:1e0e79e82839 107 /** Start the timer
tedoyle 0:1e0e79e82839 108 */
tedoyle 0:1e0e79e82839 109 int start(void);
tedoyle 0:1e0e79e82839 110
tedoyle 0:1e0e79e82839 111 /** Stop the timer
tedoyle 0:1e0e79e82839 112 */
tedoyle 0:1e0e79e82839 113 int stop(void);
tedoyle 0:1e0e79e82839 114
tedoyle 0:1e0e79e82839 115 /** Reset the timer to 0.
tedoyle 0:1e0e79e82839 116 *
tedoyle 0:1e0e79e82839 117 * If it was already counting, it will continue
tedoyle 0:1e0e79e82839 118 */
tedoyle 0:1e0e79e82839 119 int reset(void);
tedoyle 0:1e0e79e82839 120
tedoyle 3:8396d3e6eb62 121 /** Get the time passed in micro-seconds
tedoyle 0:1e0e79e82839 122 */
tedoyle 3:8396d3e6eb62 123 int read_us(uint64_t* timeInUsec = NULL);
tedoyle 0:1e0e79e82839 124
tedoyle 1:497fba179833 125 /** Get the time passed in milli-seconds
tedoyle 0:1e0e79e82839 126 */
tedoyle 3:8396d3e6eb62 127 int read_ms(uint64_t* timeInMsec = NULL);
tedoyle 0:1e0e79e82839 128
tedoyle 3:8396d3e6eb62 129 /** Get the time passed in seconds
tedoyle 0:1e0e79e82839 130 */
tedoyle 3:8396d3e6eb62 131 int read(double* timeInSec = NULL);
tedoyle 6:100cf27b43aa 132
tedoyle 6:100cf27b43aa 133 /** Check to see if timer is running
tedoyle 6:100cf27b43aa 134 */
tedoyle 6:100cf27b43aa 135 int isRunning(bool* running);
tedoyle 0:1e0e79e82839 136
tedoyle 0:1e0e79e82839 137 private:
tedoyle 0:1e0e79e82839 138 bool _timerInitialized;
tedoyle 1:497fba179833 139 bool _timerRunning; // whether the timer is running
tedoyle 0:1e0e79e82839 140 timestamp_t _tickerStartTimeUsec; // the start time of the latest slice
tedoyle 0:1e0e79e82839 141 uint64_t _totalTimeUsec; // any accumulated time from previous slices
tedoyle 0:1e0e79e82839 142 const ticker_data_t *_ticker_data;
tedoyle 0:1e0e79e82839 143 RtosTimer* _rollOverCheckTimer;
tedoyle 0:1e0e79e82839 144 uint32_t _rollOverCheckTimerPeriodInMsec;
tedoyle 3:8396d3e6eb62 145 Semaphore* _sem;
tedoyle 3:8396d3e6eb62 146
tedoyle 0:1e0e79e82839 147 static void _rollOverCheck(void const* args);
tedoyle 3:8396d3e6eb62 148 static uint64_t _read_us(void const* args);
tedoyle 0:1e0e79e82839 149 };
tedoyle 0:1e0e79e82839 150
tedoyle 0:1e0e79e82839 151 #endif