rtmlib
src
time_compat.h
Go to the documentation of this file.
1
/*
2
* rtmlib is a Real-Time Monitoring Library.
3
*
4
* Copyright (C) 2018-2020 André Pedro
5
*
6
* This file is part of rtmlib.
7
*
8
* This program is free software: you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation, either version 3 of the License, or
11
* (at your option) any later version.
12
*
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
17
*
18
* You should have received a copy of the GNU General Public License
19
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20
*/
21
22
#ifndef _TIME_COMPAT_H_
23
#define _TIME_COMPAT_H_
24
25
#include "
atomic_compat.h
"
26
27
#ifdef __HW__
28
29
typedef
long
long
timeabs;
30
typedef
long
timespan;
31
32
#define clockgettime() 0
33
34
#elif (__NUTTX__)
35
#include <nuttx/clock.h>
36
37
/*
38
* We may interpret timestamps as uint8_t, uint16_t, uint24_t, uint32_t, and
39
* uint64_t.
40
*
41
* - uint8_t only contains 255 ticks and is small; It means that we have to
42
* execute the monitors as fast as 255 ticks, inducing a huge overhead.
43
*
44
* - uint16_t can be enough for faster monitors (the Cortex-M is excluded)
45
*
46
* - uint24_t is enough if the monitor has a period no bigger than 100hz
47
*
48
* - uint32_t is enough if the monitor has a period no bigger than 1hz
49
*
50
* - for all the other cases uint64_t is required
51
*
52
* In this note, the timestamps are measured in nanoseconds.
53
*/
54
typedef
uint64_t timeabs;
55
typedef
uint32_t timespan;
56
57
#define NOP __NOP()
58
59
// we need to adjust the systick when is triggering the IRQ
60
#define clockgettime() \
61
({ \
62
ISB timespan ns = SysTick->VAL; \
63
uint64_t ms = g_system_timer; \
64
ISB(ms * 1000000) + ((1000000. / SysTick->LOAD) * (SysTick->LOAD - ns)); \
65
})
66
67
// get cpu_clock
68
// assuming 168mhz 1000000000/(168000000/167999)
69
// (1000000000/(clock/SysTick->LOAD))/SysTick->LOAD currently ~= 5.5(5)ns
70
71
#elif defined(__x86__) || defined(__x86_64__)
72
73
#include <pthread.h>
74
#include <time.h>
75
76
typedef
long
long
timeabs;
77
typedef
long
timespan;
78
79
#define clockgettime() \
80
({ \
81
struct timespec __n; \
82
clock_gettime(CLOCK_REALTIME, &__n); \
83
uint64_t result = __n.tv_sec; \
84
(result * 1000000000) + (__n.tv_nsec); \
85
})
86
87
#else
88
89
#error \
90
"This monitoring library only supports NuttX ARM Cortex-M4 and x86 architecture!"
91
92
#endif
93
94
typedef
timeabs
timespanw
;
95
96
/* Operations on timespecs. */
97
#define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0
98
99
#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec)
100
101
#define timespeccmp(tsp, usp, cmp) \
102
(((tsp)->tv_sec == (usp)->tv_sec) ? ((tsp)->tv_nsec cmp(usp)->tv_nsec) \
103
: ((tsp)->tv_sec cmp(usp)->tv_sec))
104
105
#define timespecadd(tsp, usp, vsp) \
106
do { \
107
(vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
108
(vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
109
if ((vsp)->tv_nsec >= 1000000000L) { \
110
(vsp)->tv_sec++; \
111
(vsp)->tv_nsec -= 1000000000L; \
112
} \
113
} while (0)
114
115
#define timespecsub(tsp, usp, vsp) \
116
do { \
117
(vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
118
(vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
119
if ((vsp)->tv_nsec < 0) { \
120
(vsp)->tv_sec--; \
121
(vsp)->tv_nsec += 1000000000L; \
122
} \
123
} while (0)
124
125
#define useconds_t2timespec(tsp, vsp) \
126
do { \
127
(vsp)->tv_sec = *tsp / 1000000L; \
128
(vsp)->tv_nsec = (*tsp % 1000000L) * 1000; \
129
} while (0)
130
131
#endif //_TIME_COMPAT_H_
timespanw
timeabs timespanw
Definition:
time_compat.h:94
atomic_compat.h
Generated by
1.8.15