-
Notifications
You must be signed in to change notification settings - Fork 0
/
cdefs.h
137 lines (112 loc) · 3.41 KB
/
cdefs.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (c) 2021 Mathema GmbH
// SPDX-License-Identifier: BSD-3-Clause
// Author: Günter Woigk (Kio!)
// Copyright (c) 2021 [email protected]
// BSD 2-clause license
#pragma once
#ifndef __cplusplus
#error "C++ ahead"
#endif
#if __cplusplus < 201103L
#error "need c++11 or later"
#endif
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "standard_types.h"
#include "settings.h"
// optimization:
#define LIKELY(x) __builtin_expect((x),true)
#define UNLIKELY(x) __builtin_expect((x),false)
#ifndef __printflike
#define __printflike(A,B) __attribute__((format(printf, A, B)))
#endif
// Assertions:
// STATIC_ASSERT(COND) --> checked by compiler
// ASSERT(COND) --> checked at runtime, target Debug only!
// RUNTIME_ASSERT(COND) --> checked at runtime, target Final too! (will reset the CPU or do s.th. similar evil)
#if defined(DEBUG)
#ifndef assert
#define assert(COND) (LIKELY(COND) ? (void)0 : handle_assert(__FILE__,__LINE__))
#endif
#else
#undef assert
#define assert(COND) ((void)0)
#endif
#define TOSTRING(X) #X
#define RUNTIME_ASSERT(COND) do { if(UNLIKELY(!(COND))) throw FatalError("ASSERT FAILED: " __FILE__ " line " TOSTRING(__LINE__) ": " #COND); } while(0)
#define KITTY(X,Y) X ## Y
#define CAT(X,Y) KITTY(X,Y)
#define STATIC_ASSERT(COND) typedef char CAT(line_,__LINE__)[(COND)?1:-1] __attribute__((unused))
#define NELEM(feld) (sizeof(feld)/sizeof((feld)[0])) // UNSIGNED !!
#ifndef debug_break
#ifdef DEBUG
#if defined(__arm__)
#define debug_break() __asm__ volatile("bkpt")
#else
#include "3rdparty/debugbreak.h"
#endif
#else
#define debug_break __debugbreak
static inline void debug_break(){}
#endif
// must be provided by application:
__attribute__((noreturn)) extern void handle_assert(cstr file, uint line) noexcept;
#define IERR() handle_assert(__FILE__,__LINE__)
#define TODO() handle_assert(__FILE__,__LINE__)
#define OMEM() handle_assert(__FILE__,__LINE__)
#endif // debug_break
/**
* Template: Determine the minimum of two values.
* @param a the one value
* @param b the other value
* @return the smaller one
*/
template<typename T>
static inline T min(T a,T b)
{
return a<=b?a:b;
}
/**
* Template: Determine the maximum of two values.
* @param a the one value
* @param b the other value
* @return the greater one
*/
template<typename T>
static inline T max(T a,T b)
{
return a>=b?a:b;
}
/**
* Template: Limit a value to a lower and upper limit.
* @param a the lower limit
* @param x the value
* @param b the upper limit
* @return the limited value
*/
template<typename S, typename T, typename U>
static inline T minmax(S a, T x, U b)
{
return x >= a ? x <= b ? x : b : a;
}
/**
* Wait for Interrupt.
*
* Whenever waiting this function should be used to consume time.
* On an ARM it uses the assembler instruction @ref wfi which waits for the next interrupt.
* It is not required that interrupts are enabled, but they should.
* This function is expected to reduce the power consumption of this core (slightly).
*/
static inline void wfi() noexcept
{
#ifdef __arm__
__asm__ __volatile__("wfi");
#else
for (uint i=0; i<999; i++) { __asm__ __volatile__(""); }
#endif
}
static constexpr bool on = true;
static constexpr bool off = false;