Helmut Tschemernjak / Mbed 2 deprecated Turtle_RadioShuttle

Dependencies:   mbed BufferedSerial SX1276GenericLib OLED_SSD1306 HELIOS_Si7021 NVProperty RadioShuttle-STM32L4 USBDeviceHT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arch.h Source File

arch.h

00001 /*
00002  * $Id: config.h,v 1.5 2017/02/23 14:31:38 grimrath Exp $
00003  * This is an unpublished work copyright (c) 2019 HELIOS Software GmbH
00004  * 30827 Garbsen, Germany
00005  */
00006 #ifndef __ARCH_H__
00007 #define __ARCH_H__
00008 
00009 #ifdef __cplusplus
00010 #define _extern_c extern "C"
00011 #else
00012 #define _extern_c
00013 #endif
00014 
00015 // --------------------------------------------------------------------------------------------------------------------
00016 // Definitions to adapt between POSIX and MBED
00017 //
00018 #ifdef __MBED__
00019 
00020 #include <mbed_assert.h>
00021 #include <mbed_debug.h>
00022 
00023 #ifdef TARGET_DEBUG
00024 #define DEBUG 1
00025 #define STATIC_ASSERT   MBED_STATIC_ASSERT
00026 #define ASSERT      MBED_ASSERT
00027 #else
00028 #define ASSERT(x)   ((void)0)
00029 #endif
00030 
00031 #define STATIC_ASSERT   MBED_STATIC_ASSERT
00032 
00033 #ifndef TOOLCHAIN_GCC
00034 #ifdef __cplusplus
00035 using std::size_t;
00036 using std::va_list;
00037 using std::abort;
00038 #endif
00039 
00040 _extern_c size_t strnlen(const char *s, size_t maxlen);
00041 _extern_c char *strdup(const char *s);
00042 _extern_c char *stpcpy(char *dest, const char *src);
00043 
00044 #endif
00045 
00046 struct iovec {
00047     void *  iov_base;
00048     size_t  iov_len;
00049 };
00050 
00051 
00052 static inline unsigned read_systicker_us(void) {
00053     extern uint32_t us_ticker_read(void);   // I do not want to include us_ticker_api.h here
00054 
00055     return us_ticker_read();
00056 }
00057 
00058 #define FlashFileSysMount   "Flash"
00059 // #define ESPFileSysMount     "ESP"
00060 #define PseudoFileSysMount  "pseudo"
00061 
00062 #else // __MBED__
00063 
00064 #include <assert.h>
00065 #include <time.h>
00066 
00067 #ifdef __cplusplus
00068 #define STATIC_ASSERT(condition, msg) ((void)sizeof(char[1 - 2*!(condition)]))
00069 #else
00070 #define STATIC_ASSERT(expr, msg)    _Static_assert(expr, msg)  // C11 feature
00071 #endif
00072 #define ASSERT              assert
00073 
00074 //static inline unsigned read_systicker_us(void) {
00075 //  struct timespec ts;
00076 //  clock_gettime(CLOCK_MONOTONIC, &ts);
00077 //  return (ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
00078 //}
00079 
00080 #endif // __MBED__
00081 
00082 
00083 // --------------------------------------------------------------------------------------------------------------------
00084 // synchronize memory contents with external peripherals and interrupt handlers
00085 //
00086 // __ATOMIC_RELAXED should be ok since we are only dealing with irq handlers on exactly one CPU/MCU
00087 //
00088 // __atomic_load_n is not available in the online IDE (yet)
00089 //
00090 #if defined(__ATOMIC_RELAXED)
00091 
00092 #define help_atomic_load_relaxed(ptr) __atomic_load_n((ptr), __ATOMIC_RELAXED)
00093 
00094 #define help_atomic_store_relaxed(ptr, val) __atomic_store_n((ptr), (val), __ATOMIC_RELAXED)
00095 
00096 #define help_atomic_readclr_relaxed(ptr) __atomic_exchange_n((ptr), 0, __ATOMIC_RELAXED)
00097 
00098 #define help_atomic_or_relaxed(ptr, val) __atomic_fetch_or((ptr), (val), __ATOMIC_RELAXED)
00099 
00100 #ifdef __cplusplus
00101 template<typename T> inline bool help_atomic_compare_and_swap(T *ptr, T checkval, T newval) {
00102     return __atomic_compare_exchange_n(ptr, &checkval, newval, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
00103 }
00104 #else
00105 #define help_atomic_compare_and_swap(ptr, checkval, newval) __sync_bool_compare_and_swap((ptr), (checkval), (newval))
00106 #endif
00107 
00108 #define sync_memory(mem) do { \
00109     asm volatile("" : "=m" (mem)); \
00110     __atomic_thread_fence(__ATOMIC_SEQ_CST); \
00111 } while (0)
00112 
00113 #define irq_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
00114 
00115 #define sync_memory_all() do { \
00116     asm volatile("" : : : "memory"); \
00117     __atomic_thread_fence(__ATOMIC_SEQ_CST); \
00118 } while (0)
00119 
00120 #else // defined(__ATOMIC_RELAXED)
00121 
00122 #define help_atomic_load_relaxed(ptr) (*(ptr))
00123 
00124 #define help_atomic_store_relaxed(ptr, val) ((void)(*(ptr) = (val)))
00125 
00126 #define help_atomic_readclr_relaxed(ptr) __sync_fetch_and_and((ptr), 0)
00127 
00128 #define help_atomic_or_relaxed(ptr, val) __sync_fetch_and_or((ptr), (val))
00129 
00130 #define help_atomic_compare_and_swap(ptr, checkval, newval) __sync_bool_compare_and_swap((ptr), (checkval), (newval))
00131 
00132 #define sync_memory(mem) __sync_synchronize()
00133 
00134 #define sync_memory_all() __sync_synchronize()
00135 
00136 #define irq_barrier() __sync_synchronize()
00137 
00138 #endif
00139 
00140 
00141 #define help_atomic_init(ptr, initval) do { *(ptr) = (initval); } while (0)
00142 
00143 // --------------------------------------------------------------------------------------------------------------------
00144 // other
00145 
00146 #define ispowerof2(x) (((x) & ((x) - 1)) == 0)
00147 
00148 static inline uint32_t alignup32(uint32_t size, uint32_t next) {
00149     uint32_t next1 = next - 1;
00150     ASSERT((next & next1) == 0);    // 2^n check
00151     return (size + next1) & ~next1;
00152 }
00153 
00154 
00155 // --------------------------------------------------------------------------------------------------------------------
00156 // typesafe macros to get the number of compile-time known array elements.
00157 //
00158 #ifdef __cplusplus
00159 
00160 template< typename T, std::size_t N > char(&COUNTOF_REQUIRES_ARRAY_ARGUMENT(T(&)[N]))[N];
00161 #define ARRAYLEN(x) sizeof(COUNTOF_REQUIRES_ARRAY_ARGUMENT(x))
00162 
00163 #else
00164 
00165 // MBED OS online compiler does not support unnamed and zero sized bitfields as GCC does
00166 // #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))    // used by Linux kernel
00167 #define __must_be_zero(e) (sizeof(struct { char dummy:(1 - 2*!!(e)); }) - 1)
00168 
00169 // __builtin_types_compatible_p: gcc extension, but understood by Intel, clang and ARM compilers too
00170 // __builtin_types_compatible_p is not available in C++
00171 #define __must_be_array(arr) __must_be_zero(__builtin_types_compatible_p(typeof(arr), typeof(&(arr)[0])))
00172 
00173 #define ARRAYLEN(arr) (sizeof(arr) / sizeof(0[arr])) + __must_be_array(arr)
00174 
00175 #endif
00176 
00177 
00178 // --------------------------------------------------------------------------------------------------------------------
00179 // quick int32 -> int conversion mainly for printf. Shorter than static_cast<int> and works with C too.
00180 //
00181 static inline int itoi(int val) { return val; }
00182 static inline long long lltoll(long long val) { return val; }
00183 
00184 
00185 // --------------------------------------------------------------------------------------------------------------------
00186 // Byte order
00187 //
00188 #ifdef __MBED__
00189 
00190 #if BYTE_ORDER == LITTLE_ENDIAN
00191 
00192 static inline uint16_t htole16(uint16_t x) { return x; }
00193 static inline uint16_t le16toh(uint16_t x) { return x; }
00194 static inline uint32_t htole32(uint32_t x) { return x; }
00195 static inline uint32_t le32toh(uint32_t x) { return x; }
00196 
00197 #else
00198 
00199 // unused big endian variants
00200 // static inline uint16_t htobe16(uint16_t x) { return __REV16(x); }
00201 // static inline uint16_t be16toh(uint16_t x) { return __REV16(x); }
00202 // static inline uint32_t htobe32(uint32_t x) { return __REV(x); }
00203 // static inline uint32_t be32toh(uint32_t x) { return __REV(x); }
00204 
00205 #endif
00206 
00207 #elif defined(__linux__)
00208 
00209 #include <endian.h>
00210 
00211 #elif defined(__APPLE__)
00212 
00213 #include <libkern/OSByteOrder.h>
00214 #define htole16 OSSwapHostToLittleInt16
00215 #define le16toh OSSwapHostToLittleInt16
00216 #define htole32 OSSwapHostToLittleInt32
00217 #define le32toh OSSwapHostToLittleInt32
00218 
00219 #endif
00220 
00221 
00222 // --------------------------------------------------------------------------------------------------------------------
00223 // memory debugging
00224 //
00225 #ifdef DEBUG
00226 
00227 #ifdef USE_VALGRIND
00228 
00229 #include <valgrind/valgrind.h>
00230 #include <valgrind/memcheck.h>
00231 #include <string.h>
00232 
00233 #define CHECKDEFINED(obj) VALGRIND_CHECK_MEM_IS_DEFINED(&(obj), sizeof(obj))
00234 
00235 #endif // ! valgrind
00236 
00237 static inline void POISONMEM(void *ptr, size_t sz) {
00238     memset(ptr, 0x55, sz);
00239 #ifdef USE_VALGRIND
00240     VALGRIND_MAKE_MEM_UNDEFINED(ptr, sz);
00241 #endif
00242 }
00243 
00244 #define POISON(obj) POISONMEM(&(obj), sizeof(obj))
00245 
00246 #else // ! DEBUG
00247 
00248 #ifdef USE_VALGRIND
00249 #error valgrind features only useable in debug builds
00250 #endif
00251 
00252 static inline void POISONMEM(void *ptr, size_t sz) { (void)ptr; (void)sz; }
00253 
00254 #define POISON(obj) ((void)0)
00255 
00256 #endif // DEBUG
00257 
00258 // --------------------------------------------------------------------------------------------------------------------
00259 // Macros to live bookmark code
00260 //
00261 #ifdef DEBUG
00262 
00263 _extern_c void dbg_fail_handler(const char *file, int line, const char *func, const char *msg) __attribute__((noreturn));
00264 
00265 #define TODO(...)   dbg_fail_handler(__FILE__, __LINE__, __func__, "TODO" __VA_ARGS__)
00266 #define UNTESTED()  dbg_fail_handler(__FILE__, __LINE__, __func__, "UNTESTED")
00267 #define UNREACHABLE()   dbg_fail_handler(__FILE__, __LINE__, __func__, "UNREACHABLE")
00268 #if defined(__x86_64__) || defined(__i386__)
00269 #define BREAKPOINT()    asm("int $3")
00270 #elif defined(__arm__)
00271 #define BREAKPOINT()    __BKPT(0)
00272 #else
00273 #error no compile time breakpoints supplied for this architecture - add them if needed
00274 #endif
00275 
00276 #else // ! debug
00277 
00278 #define TODO(...)   abort()
00279 #define UNTESTED()  ((void)0)
00280 #ifdef __MBED__
00281 #   define UNREACHABLE()    MBED_UNREACHABLE
00282 #else
00283 #   define UNREACHABLE() __builtin_unreachable()
00284 #endif
00285 // no BREAKPOINT() - these must be removed in release builds
00286 
00287 #endif // debug
00288 
00289 
00290 
00291 // --------------------------------------------------------------------------------------------------------------------
00292 // Tracing
00293 //
00294 #ifdef DEBUG
00295 
00296 // Do not call these directly, use DTRC
00297 _extern_c void trc_dbg(const char *file, int line, const char *func, const char *fmt, ...) __attribute__((format(printf,4,5)));
00298 _extern_c void trc_vdbg(const char *file, int line, const char *func, const char *fmt, va_list ap);
00299 
00300 #define DTRC(_fmt, ...) trc_dbg(__FILE__, __LINE__, __func__, (_fmt), ## __VA_ARGS__)
00301 
00302 
00303 #else // DEBUG
00304 
00305 #define DTRC(_fmt, ...) ((void)0)
00306 
00307 #endif
00308 
00309 // Do not call these directly, use TRC_* macros
00310 _extern_c void trc_printf(const char *fmt, ...) __attribute__((format(printf,1,2)));
00311 _extern_c void trc_vprintf(const char *fmt, va_list ap);
00312 
00313 // These exists even in release builds
00314 #define TRC_INF(_fmt, ...) trc_printf((_fmt), ## __VA_ARGS__)
00315 #define TRC_WRN TRC_INF
00316 #define TRC_ERR TRC_INF
00317 #define TRC_VERR(fmt, ap) trc_vprintf((fmt), (ap))
00318 
00319 #endif // __ARCH_H__