Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Timer64 by
Timer64.h@7:381bafbb2218, 2016-04-01 (annotated)
- Committer:
- tedoyle
- Date:
- Fri Apr 01 18:37:38 2016 +0000
- Revision:
- 7:381bafbb2218
- Parent:
- 5:e2a2d9790e36
Minor edits;
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| tedoyle | 4:9ca673a83acb | 1 | /* mbed Microcontroller Library |
| tedoyle | 4:9ca673a83acb | 2 | * Copyright (c) 2006-2016 ARM Limited |
| tedoyle | 4:9ca673a83acb | 3 | * |
| tedoyle | 4:9ca673a83acb | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| tedoyle | 4:9ca673a83acb | 5 | * you may not use this file except in compliance with the License. |
| tedoyle | 4:9ca673a83acb | 6 | * You may obtain a copy of the License at |
| tedoyle | 4:9ca673a83acb | 7 | * |
| tedoyle | 4:9ca673a83acb | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| tedoyle | 4:9ca673a83acb | 9 | * |
| tedoyle | 4:9ca673a83acb | 10 | * Unless required by applicable law or agreed to in writing, software |
| tedoyle | 4:9ca673a83acb | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| tedoyle | 4:9ca673a83acb | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| tedoyle | 4:9ca673a83acb | 13 | * See the License for the specific language governing permissions and |
| tedoyle | 4:9ca673a83acb | 14 | * limitations under the License. |
| tedoyle | 4:9ca673a83acb | 15 | * |
| tedoyle | 4:9ca673a83acb | 16 | * Modified by Tom Doyle <ThomasEDoyle@gmail.com> |
| tedoyle | 4:9ca673a83acb | 17 | * |
| tedoyle | 4:9ca673a83acb | 18 | */ |
| tedoyle | 4:9ca673a83acb | 19 | |
| tedoyle | 7:381bafbb2218 | 20 | #ifndef __TIMER64__ |
| tedoyle | 7:381bafbb2218 | 21 | #define __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 | 4:9ca673a83acb | 31 | #define TIMER64_ERROR_NULL_POINTER -2 |
| tedoyle | 0:1e0e79e82839 | 32 | |
| tedoyle | 1:497fba179833 | 33 | #define TIMER64_WARNING_ALREADY_INITIALIZED 1 |
| tedoyle | 1:497fba179833 | 34 | #define TIMER64_WARNING_ALREADY_RUNNING 2 |
| tedoyle | 1:497fba179833 | 35 | #define TIMER64_WARNING_ALREADY_STOPPED 3 |
| tedoyle | 2:e89b02820e93 | 36 | #define TIMER64_WARNING_ALREADY_RELEASED 4 |
| tedoyle | 0:1e0e79e82839 | 37 | |
| tedoyle | 3:8396d3e6eb62 | 38 | #define TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS 30000 |
| tedoyle | 3:8396d3e6eb62 | 39 | #define TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS 1000 |
| tedoyle | 3:8396d3e6eb62 | 40 | #define TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS 65535 |
| tedoyle | 0:1e0e79e82839 | 41 | |
| tedoyle | 4:9ca673a83acb | 42 | /** Timer64 class |
| tedoyle | 4:9ca673a83acb | 43 | * Used to define a 64 bit timer64 that is thread safe. The Timer64 behaves in a |
| tedoyle | 4:9ca673a83acb | 44 | * similiar fashion to the mbed Timer class with the most notable exception that |
| tedoyle | 4:9ca673a83acb | 45 | * the Timer64 will not rollover after 2^31 microseconds (approximately 35.8 minutes). |
| tedoyle | 5:e2a2d9790e36 | 46 | * The Timer64 extends the rollover time to 2^64 microseconds (approximately 585,000 years!) |
| tedoyle | 4:9ca673a83acb | 47 | * |
| tedoyle | 4:9ca673a83acb | 48 | * The Timer64 class is also designed to be thread safe. The following functions can be |
| tedoyle | 4:9ca673a83acb | 49 | * called from any thread after the class is instaniated and initialized: |
| tedoyle | 4:9ca673a83acb | 50 | * |
| tedoyle | 4:9ca673a83acb | 51 | * - start() |
| tedoyle | 4:9ca673a83acb | 52 | * - stop() |
| tedoyle | 4:9ca673a83acb | 53 | * - reset() |
| tedoyle | 4:9ca673a83acb | 54 | * - read_us() |
| tedoyle | 4:9ca673a83acb | 55 | * - read_ms() |
| tedoyle | 4:9ca673a83acb | 56 | * - read() |
| tedoyle | 4:9ca673a83acb | 57 | * - reset() |
| tedoyle | 4:9ca673a83acb | 58 | * - isRunning() |
| tedoyle | 4:9ca673a83acb | 59 | * |
| tedoyle | 4:9ca673a83acb | 60 | * It is to be noted that the init() and release() methods need to be called from the same thread. |
| tedoyle | 4:9ca673a83acb | 61 | * |
| tedoyle | 4:9ca673a83acb | 62 | * Give the Timer64 library a try and let me know if it works for you. Will gladly take suggestions |
| tedoyle | 4:9ca673a83acb | 63 | * on how to make it better. |
| tedoyle | 4:9ca673a83acb | 64 | * |
| tedoyle | 4:9ca673a83acb | 65 | * Simple Example |
| tedoyle | 4:9ca673a83acb | 66 | * @code |
| tedoyle | 4:9ca673a83acb | 67 | * #include "mbed.h" |
| tedoyle | 4:9ca673a83acb | 68 | * #include "rtos.h" |
| tedoyle | 4:9ca673a83acb | 69 | * #include "Timer64.h" |
| tedoyle | 4:9ca673a83acb | 70 | * |
| tedoyle | 4:9ca673a83acb | 71 | * Timer64 timer64; |
| tedoyle | 4:9ca673a83acb | 72 | * |
| tedoyle | 4:9ca673a83acb | 73 | * int main() |
| tedoyle | 4:9ca673a83acb | 74 | * { |
| tedoyle | 4:9ca673a83acb | 75 | * uint64_t timeInUsec; |
| tedoyle | 4:9ca673a83acb | 76 | * timer64.init(); |
| tedoyle | 4:9ca673a83acb | 77 | * timer64.start(); |
| tedoyle | 4:9ca673a83acb | 78 | * Thread::wait(100); |
| tedoyle | 4:9ca673a83acb | 79 | * timer64.stop(); |
| tedoyle | 4:9ca673a83acb | 80 | * timer64.read_us(&timeInUsec); |
| tedoyle | 4:9ca673a83acb | 81 | * printf("Test - Elapsed time = %llu usec\n\n", timeInUsec); |
| tedoyle | 4:9ca673a83acb | 82 | * timer64.reset(); |
| tedoyle | 4:9ca673a83acb | 83 | * timer64.release(); |
| tedoyle | 4:9ca673a83acb | 84 | * |
| tedoyle | 4:9ca673a83acb | 85 | * while (1) |
| tedoyle | 4:9ca673a83acb | 86 | * { |
| tedoyle | 4:9ca673a83acb | 87 | * Thread::wait(1000); |
| tedoyle | 4:9ca673a83acb | 88 | * } |
| tedoyle | 4:9ca673a83acb | 89 | * } |
| tedoyle | 4:9ca673a83acb | 90 | * @endcode |
| tedoyle | 4:9ca673a83acb | 91 | */ |
| tedoyle | 7:381bafbb2218 | 92 | |
| tedoyle | 7:381bafbb2218 | 93 | class Timer64 |
| tedoyle | 0:1e0e79e82839 | 94 | { |
| tedoyle | 0:1e0e79e82839 | 95 | |
| tedoyle | 0:1e0e79e82839 | 96 | public: |
| tedoyle | 0:1e0e79e82839 | 97 | Timer64(); |
| tedoyle | 1:497fba179833 | 98 | ~Timer64(); |
| tedoyle | 0:1e0e79e82839 | 99 | |
| tedoyle | 1:497fba179833 | 100 | /** Initialize the timer - this must be called before the timer can be used |
| tedoyle | 4:9ca673a83acb | 101 | * |
| tedoyle | 4:9ca673a83acb | 102 | * @param rolloverCheckTimeInMsecc specifies how ofter a rollover check is performed. |
| tedoyle | 4:9ca673a83acb | 103 | * This parameter is bounded by TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS and |
| tedoyle | 4:9ca673a83acb | 104 | * TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS with a default value of |
| tedoyle | 4:9ca673a83acb | 105 | * TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS |
| tedoyle | 4:9ca673a83acb | 106 | * |
| tedoyle | 4:9ca673a83acb | 107 | * @returns |
| tedoyle | 5:e2a2d9790e36 | 108 | * TIMER64_OK, |
| tedoyle | 4:9ca673a83acb | 109 | * TIMER64_WARNING_ALREADY_INITIALIZED |
| tedoyle | 0:1e0e79e82839 | 110 | */ |
| tedoyle | 4:9ca673a83acb | 111 | int init(uint32_t rolloverCheckTimeInMsecc = TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS); |
| tedoyle | 0:1e0e79e82839 | 112 | |
| tedoyle | 4:9ca673a83acb | 113 | /** Release the timer - must be called from the same thread calling init() |
| tedoyle | 4:9ca673a83acb | 114 | * |
| tedoyle | 4:9ca673a83acb | 115 | * @returns |
| tedoyle | 5:e2a2d9790e36 | 116 | * TIMER64_OK, |
| tedoyle | 4:9ca673a83acb | 117 | * TIMER64_WARNING_ALREADY_RELEASED |
| tedoyle | 0:1e0e79e82839 | 118 | */ |
| tedoyle | 0:1e0e79e82839 | 119 | int release(void); |
| tedoyle | 0:1e0e79e82839 | 120 | |
| tedoyle | 4:9ca673a83acb | 121 | /** Start the timer - this method is thread safe |
| tedoyle | 4:9ca673a83acb | 122 | * |
| tedoyle | 4:9ca673a83acb | 123 | * @returns |
| tedoyle | 5:e2a2d9790e36 | 124 | * TIMER64_OK, |
| tedoyle | 5:e2a2d9790e36 | 125 | * TIMER64_ERROR_NOT_INITIALIZED, |
| tedoyle | 4:9ca673a83acb | 126 | * TIMER64_WARNING_ALREADY_RUNNING |
| tedoyle | 0:1e0e79e82839 | 127 | */ |
| tedoyle | 0:1e0e79e82839 | 128 | int start(void); |
| tedoyle | 0:1e0e79e82839 | 129 | |
| tedoyle | 4:9ca673a83acb | 130 | /** Stop the timer - this method is thread safe |
| tedoyle | 4:9ca673a83acb | 131 | * |
| tedoyle | 4:9ca673a83acb | 132 | * @returns |
| tedoyle | 5:e2a2d9790e36 | 133 | * TIMER64_OK, |
| tedoyle | 5:e2a2d9790e36 | 134 | * TIMER64_ERROR_NOT_INITIALIZED, |
| tedoyle | 4:9ca673a83acb | 135 | * TIMER64_WARNING_ALREADY_STOPPED |
| tedoyle | 0:1e0e79e82839 | 136 | */ |
| tedoyle | 0:1e0e79e82839 | 137 | int stop(void); |
| tedoyle | 0:1e0e79e82839 | 138 | |
| tedoyle | 4:9ca673a83acb | 139 | /** Reset the timer - this method is thread safe |
| tedoyle | 4:9ca673a83acb | 140 | * |
| tedoyle | 4:9ca673a83acb | 141 | * @returns |
| tedoyle | 5:e2a2d9790e36 | 142 | * TIMER64_OK, |
| tedoyle | 4:9ca673a83acb | 143 | * TIMER64_ERROR_NOT_INITIALIZED |
| tedoyle | 0:1e0e79e82839 | 144 | */ |
| tedoyle | 0:1e0e79e82839 | 145 | int reset(void); |
| tedoyle | 0:1e0e79e82839 | 146 | |
| tedoyle | 4:9ca673a83acb | 147 | /** Read the timer value in microseconds - this method is thread safe |
| tedoyle | 4:9ca673a83acb | 148 | * |
| tedoyle | 4:9ca673a83acb | 149 | * @param timeInUsec specifies a pointer to a uint64_t where to save the current time in microseconds |
| tedoyle | 4:9ca673a83acb | 150 | * |
| tedoyle | 4:9ca673a83acb | 151 | * @returns |
| tedoyle | 5:e2a2d9790e36 | 152 | * TIMER64_OK, |
| tedoyle | 5:e2a2d9790e36 | 153 | * TIMER64_ERROR_NOT_INITIALIZED, |
| tedoyle | 4:9ca673a83acb | 154 | * TIMER64_ERROR_NULL_POINTER |
| tedoyle | 0:1e0e79e82839 | 155 | */ |
| tedoyle | 3:8396d3e6eb62 | 156 | int read_us(uint64_t* timeInUsec = NULL); |
| tedoyle | 0:1e0e79e82839 | 157 | |
| tedoyle | 4:9ca673a83acb | 158 | /** Read the timer value in milliseconds - this method is thread safe |
| tedoyle | 4:9ca673a83acb | 159 | * |
| tedoyle | 4:9ca673a83acb | 160 | * @param timeInMsec specifies a pointer to a uint64_t where to save the current time in milliseconds |
| tedoyle | 4:9ca673a83acb | 161 | * |
| tedoyle | 4:9ca673a83acb | 162 | * @returns |
| tedoyle | 5:e2a2d9790e36 | 163 | * TIMER64_OK, |
| tedoyle | 5:e2a2d9790e36 | 164 | * TIMER64_ERROR_NOT_INITIALIZED, |
| tedoyle | 4:9ca673a83acb | 165 | * TIMER64_ERROR_NULL_POINTER |
| tedoyle | 0:1e0e79e82839 | 166 | */ |
| tedoyle | 3:8396d3e6eb62 | 167 | int read_ms(uint64_t* timeInMsec = NULL); |
| tedoyle | 0:1e0e79e82839 | 168 | |
| tedoyle | 4:9ca673a83acb | 169 | /** Read the timer value in seconds - this method is thread safe |
| tedoyle | 4:9ca673a83acb | 170 | * |
| tedoyle | 4:9ca673a83acb | 171 | * @param timeInMsec specifies a pointer to a double where to save the current time in seconds |
| tedoyle | 4:9ca673a83acb | 172 | * |
| tedoyle | 4:9ca673a83acb | 173 | * @returns |
| tedoyle | 5:e2a2d9790e36 | 174 | * TIMER64_OK, |
| tedoyle | 5:e2a2d9790e36 | 175 | * TIMER64_ERROR_NOT_INITIALIZED, |
| tedoyle | 5:e2a2d9790e36 | 176 | * TIMER64_ERROR_NULL_POINTER, |
| tedoyle | 0:1e0e79e82839 | 177 | */ |
| tedoyle | 3:8396d3e6eb62 | 178 | int read(double* timeInSec = NULL); |
| tedoyle | 4:9ca673a83acb | 179 | |
| tedoyle | 4:9ca673a83acb | 180 | /** Check to see if timer is running - this method is thread safe |
| tedoyle | 4:9ca673a83acb | 181 | * |
| tedoyle | 4:9ca673a83acb | 182 | * @param running specifies a pointer to a bool where to save the running status |
| tedoyle | 4:9ca673a83acb | 183 | * |
| tedoyle | 4:9ca673a83acb | 184 | * @returns |
| tedoyle | 5:e2a2d9790e36 | 185 | * TIMER64_OK, |
| tedoyle | 5:e2a2d9790e36 | 186 | * TIMER64_ERROR_NOT_INITIALIZED, |
| tedoyle | 4:9ca673a83acb | 187 | * TIMER64_ERROR_NULL_POINTER |
| tedoyle | 4:9ca673a83acb | 188 | */ |
| tedoyle | 4:9ca673a83acb | 189 | int isRunning(bool* running); |
| tedoyle | 0:1e0e79e82839 | 190 | |
| tedoyle | 0:1e0e79e82839 | 191 | private: |
| tedoyle | 0:1e0e79e82839 | 192 | bool _timerInitialized; |
| tedoyle | 1:497fba179833 | 193 | bool _timerRunning; // whether the timer is running |
| tedoyle | 0:1e0e79e82839 | 194 | timestamp_t _tickerStartTimeUsec; // the start time of the latest slice |
| tedoyle | 0:1e0e79e82839 | 195 | uint64_t _totalTimeUsec; // any accumulated time from previous slices |
| tedoyle | 0:1e0e79e82839 | 196 | const ticker_data_t *_ticker_data; |
| tedoyle | 0:1e0e79e82839 | 197 | RtosTimer* _rollOverCheckTimer; |
| tedoyle | 0:1e0e79e82839 | 198 | uint32_t _rollOverCheckTimerPeriodInMsec; |
| tedoyle | 3:8396d3e6eb62 | 199 | Semaphore* _sem; |
| tedoyle | 3:8396d3e6eb62 | 200 | |
| tedoyle | 0:1e0e79e82839 | 201 | static void _rollOverCheck(void const* args); |
| tedoyle | 3:8396d3e6eb62 | 202 | static uint64_t _read_us(void const* args); |
| tedoyle | 0:1e0e79e82839 | 203 | }; |
| tedoyle | 0:1e0e79e82839 | 204 | |
| tedoyle | 7:381bafbb2218 | 205 | #endif //__TIMER64__ |
