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
Timer64.h@6:100cf27b43aa, 2016-04-01 (annotated)
- Committer:
- tedoyle
- Date:
- Fri Apr 01 16:26:49 2016 +0000
- Revision:
- 6:100cf27b43aa
- Parent:
- 3:8396d3e6eb62
?
Who changed what in which revision?
User | Revision | Line number | New 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 |