SuperTinyKernel™ RTOS 1.06.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk_defs.h
Go to the documentation of this file.
1/*
2 * SuperTinyKernel(TM) RTOS: Lightweight High-Performance Deterministic C++ RTOS for Embedded Systems.
3 *
4 * Source: https://github.com/SuperTinyKernel-RTOS
5 *
6 * Copyright (c) 2022-2026 Neutron Code Limited <stk@neutroncode.com>. All Rights Reserved.
7 * License: MIT License, see LICENSE for a full text.
8 */
9
10#ifndef STK_DEFS_H_
11#define STK_DEFS_H_
12
13#include <cstddef>
14#include <cstdint>
15#include <algorithm>
16#ifdef __ICCARM__
17 #include <intrinsics.h>
18 #if (__IAR_SYSTEMS_ICC__ < 8)
19 #error "Only IAR EWARM 8.0 and higher is supported by STK."
20 #endif
21#endif
22
29#include "stk_config.h"
30
42#ifndef STK_TICKLESS_IDLE
43 #define STK_TICKLESS_IDLE (0)
44#endif
45
50#ifndef STK_STRICT_COMPLIANCY
51 #define STK_STRICT_COMPLIANCY (0)
52#endif
53
62#ifndef STK_TICKLESS_USE_ARM_DWT
63 #define STK_TICKLESS_USE_ARM_DWT (1)
64#endif
65
76#ifndef STK_TICKLESS_TICKS_MAX
77 #define STK_TICKLESS_TICKS_MAX (1000)
78#endif
79#if STK_TICKLESS_TICKS_MAX > 100000
80 #error "STK_TICKLESS_TICKS_MAX is too large: cpu_ticks_requested may overflow uint32_t."
81#endif
82
98#ifndef STK_TLS
99 #define STK_TLS (0)
100#endif
101
126#ifndef STK_TLS_PREFER_REGISTER
127 #define STK_TLS_PREFER_REGISTER (0)
128#endif
129
138#if STK_SEGGER_SYSVIEW
139 #define STK_STACK_NEEDS_TASK_ID (1)
140#endif
141
149#if !defined(STK_SYNC_DEBUG_NAMES) && STK_SEGGER_SYSVIEW
150 #define STK_SYNC_DEBUG_NAMES (1)
151#elif !defined(STK_SYNC_DEBUG_NAMES)
152 #define STK_SYNC_DEBUG_NAMES (0)
153#endif
154
158#if !STK_STRICT_COMPLIANCY
159 #define STK_VIRT_DTOR
160#else
161 #define STK_VIRT_DTOR virtual
162#endif
163
170#if defined(__GNUC__) || defined(__ICCARM__)
171 #define __stk_forceinline __attribute__((always_inline)) inline
172#elif defined(_MSC_VER)
173 #define __stk_forceinline __forceinline
174#else
175 #define __stk_forceinline inline
176#endif
177
184#if defined(__GNUC__) || defined(__ICCARM__)
185 #define __stk_aligned(x) __attribute__((aligned(x)))
186#else
187 #define __stk_aligned(x)
188#endif
189
195#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) || defined(__CC_ARM) || defined(__ARMCC_VERSION)
196 #define __stk_weak __attribute__((weak))
197#else
198 #define __stk_weak
199#endif
200
208#if defined(__GNUC__) || defined(__ICCARM__)
209 #define __stk_attr_naked __attribute__((naked))
210#else
211 #define __stk_attr_naked
212#endif
213
219#if defined(__GNUC__) || defined(__ICCARM__)
220 #define __stk_attr_noreturn __attribute__((__noreturn__))
221#else
222 #define __stk_attr_noreturn
223#endif
224
230#if defined(__GNUC__) || defined(__ICCARM__)
231 #define __stk_attr_unused __attribute__((unused))
232#else
233 #define __stk_attr_unused
234#endif
235
241#if defined(__GNUC__) || defined(__ICCARM__)
242 #define __stk_attr_used __attribute__((used))
243#else
244 #define __stk_attr_used
245#endif
246
252#if defined(__GNUC__) || defined(__ICCARM__)
253 #define __stk_attr_noinline __attribute__((noinline))
254#else
255 #define __stk_attr_noinline
256#endif
257
263#if defined(__GNUC__) || defined(__ICCARM__)
264 #define __stk_attr_deprecated __attribute__((deprecated))
265#elif defined(_MSC_VER)
266 #define __stk_attr_deprecated __declspec(deprecated)
267#else
268 #define __stk_attr_deprecated
269#endif
270
276#if defined(__GNUC__) || defined(__clang__)
277 static __stk_forceinline void __stk_full_memfence() { __sync_synchronize(); }
278#elif defined(__ICCARM__)
279 static __stk_forceinline void __stk_full_memfence() { __DMB(); }
280#elif defined(_MSC_VER)
281 static __stk_forceinline void __stk_full_memfence() { __stk_dmb(); }
282#else
283 #error "__stk_full_memfence() is not implemented for this compiler. Add a definition to stk_defs.h."
284#endif
285
294#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
295 static __stk_forceinline void __stk_compiler_barrier() { __asm volatile("" ::: "memory"); }
296#elif defined(_MSC_VER)
297 static __stk_forceinline void __stk_compiler_barrier() { _ReadWriteBarrier(); }
298#else
299 #error "__stk_compiler_barrier() is not implemented for this compiler. Add a definition to stk_defs.h."
300#endif
301
314#ifndef __stk_relax_cpu
315#if defined(__GNUC__) || defined(__clang__)
316 #if defined(__i386__) || defined(__x86_64__)
317 static __stk_forceinline void __stk_relax_cpu() { __builtin_ia32_pause(); }
318 #elif defined(__riscv)
319 #ifdef __riscv_zihintpause
320 static __stk_forceinline void __stk_relax_cpu() { __builtin_riscv_pause(); }
321 #else
322 static __stk_forceinline void __stk_relax_cpu() { __stk_full_memfence(); }
323 #endif
324 #elif defined(__ARM_ARCH) || defined(_STK_ARCH_ARM_CORTEX_M)
325 static __stk_forceinline void __stk_relax_cpu() { __asm volatile("yield"); }
326 #else
327 static __stk_forceinline void __stk_relax_cpu() { __stk_full_memfence(); }
328 #endif
329#elif defined(__ICCARM__)
330 static __stk_forceinline void __stk_relax_cpu() { __asm volatile("YIELD"); }
331#elif defined(_MSC_VER)
332 #include <intrin.h>
333 #if defined(_M_IX86) || defined(_M_X64)
334 static __stk_forceinline void __stk_relax_cpu() { _mm_pause(); }
335 #elif defined(_M_ARM) || defined(_M_ARM64)
336 static __stk_forceinline void __stk_relax_cpu() { __yield(); }
337 #else
338 static __stk_forceinline void __stk_relax_cpu() { __stk_full_memfence(); }
339 #endif
340#else
341 #error "__stk_relax_cpu() is not implemented for this compiler. Add a definition to stk_defs.h."
342#endif
343#endif
344
359#if defined(DEBUG) || defined(_DEBUG)
360 #if defined(_STK_ARCH_ARM_CORTEX_M)
361 static __stk_forceinline void __stk_debug_break() { __asm volatile("bkpt 0"); }
362 #elif defined(_STK_ARCH_RISC_V)
363 static __stk_forceinline void __stk_debug_break() { __asm volatile("ebreak"); }
364 #elif defined(_STK_ARCH_X86_WIN32)
365 #ifdef _MSC_VER
366 static __stk_forceinline void __stk_debug_break() { __debugbreak(); }
367 #else
368 static __stk_forceinline void __stk_debug_break() { __asm volatile("int $3"); }
369 #endif
370 #endif
371#else
373#endif
374
379#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))
380 #define __stk_constexpr_cpp17 constexpr
381#else
382 #define __stk_constexpr_cpp17
383#endif
384
401#ifdef _STK_ASSERT_REDIRECT
402 extern void STK_ASSERT_HANDLER(const char *, const char *, int32_t);
403 #define STK_ASSERT(e) ((e) ? (void)0 : STK_ASSERT_HANDLER(#e, __FILE__, __LINE__))
404#else
405 #if defined(DEBUG) || defined(_DEBUG)
406 #include <cassert>
407 #define STK_ASSERT(e) assert(e)
408 #else
409 #define STK_ASSERT(e)
410 #endif
411#endif
412
421#define STK_STATIC_ASSERT_DESC_N(NAME, X, DESC) static_assert((X), DESC)
422
429#define STK_STATIC_ASSERT_DESC(X, DESC) STK_STATIC_ASSERT_DESC_N(_, X, DESC)
430
438#define STK_STATIC_ASSERT_N(NAME, X) STK_STATIC_ASSERT_DESC_N(N, (X), #X)
439
446#define STK_STATIC_ASSERT(X) STK_STATIC_ASSERT_DESC_N(_, (X), #X)
447
455#ifndef STK_STACK_MEMORY_FILLER
456 #define STK_STACK_MEMORY_FILLER (static_cast<stk::Word>((sizeof(stk::Word) <= 4U) ? 0xDEADBEEFU : 0xDEADBEEFDEADBEEFULL))
457#endif
458
462#ifndef STK_STACK_MEMORY_ALIGN
463 #if defined(__riscv)
464 #define STK_STACK_MEMORY_ALIGN (16U)
465 #elif defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
466 #define STK_STACK_MEMORY_ALIGN (8U)
467 #else // ARM, others
468 #define STK_STACK_MEMORY_ALIGN (4U)
469 #endif
470#endif
471
482#ifndef STK_CRITICAL_SECTION_NESTINGS_MAX
483 #define STK_CRITICAL_SECTION_NESTINGS_MAX (16U)
484#endif
485
492#ifndef STK_ARCH_CPU_COUNT
493 #define STK_ARCH_CPU_COUNT (1U)
494#endif
495
511#ifndef STK_STACK_SIZE_MIN
512 #ifdef __riscv
513 #if defined(__riscv_32e) && (__riscv_32e == 1)
514 // RISC-V RV32E (Embedded): Small 16-register file
515 #if !defined(__riscv_flen) || (__riscv_flen == 0)
516 #define STK_STACK_SIZE_MIN (32U)
517 #else
518 // FPU present: Requires additional space for 32 FP registers
519 #define STK_STACK_SIZE_MIN (32U + (__riscv_flen * 2))
520 #endif
521 #else
522 // Standard RISC-V (RV32I/RV64I): Large 32-register file
523 // Higher minimum to prevent memory corruption on platforms like RP2350
524 #if !defined(__riscv_flen) || (__riscv_flen == 0)
525 #define STK_STACK_SIZE_MIN (256U)
526 #else
527 // Standard RISC-V with FPU: Maximum frame allocation
528 #define STK_STACK_SIZE_MIN (512U + (__riscv_flen * 2))
529 #endif
530 #endif
531 #else
532 // ARM Cortex-M and other architectures
533 #define STK_STACK_SIZE_MIN (32U)
534 #endif
535#endif
536
545#ifndef STK_SLEEP_TRAP_STACK_SIZE
546 #define STK_SLEEP_TRAP_STACK_SIZE (STK_STACK_SIZE_MIN)
547#endif
548
560template <size_t MODE, size_t FLAG, size_t ONTRUE, size_t ONFALSE>
562{
563#if defined(_MSC_VER) || defined(__ICCARM__)
564 /* MSVC and IAR builds may over-allocate when the flag is not set to avoid compile errors. */
565 static constexpr size_t Value = ((ONTRUE > ONFALSE) ? ONTRUE : ONFALSE);
566#else
567 /* GCC and Clang support zero-sized array extensions natively. */
568 static constexpr size_t Value = (((MODE & FLAG) != 0U) ? ONTRUE : ONFALSE);
569#endif
570};
571
582#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
583 #define STK_ENDIAN_IDX_HI (0U) // big-endian: high word at index 0
584 #define STK_ENDIAN_IDX_LO (1U) // big-endian: low word at index 1
585#else
586 #define STK_ENDIAN_IDX_HI (1U) // little-endian (default): high word at index 1
587 #define STK_ENDIAN_IDX_LO (0U) // little-endian (default): low word at index 0
588#endif
589
601#define STK_NONCOPYABLE_CLASS(TYPE)\
602 TYPE(const TYPE &) = delete;\
603 TYPE &operator=(const TYPE &) = delete;
604
608#define STK_UNUSED(X) static_cast<void>((X))
609
613namespace stk {
614
618template <typename T>
619static constexpr T Min(T a, T b) { return ((a < b) ? a : b); }
620
624template <typename T>
625static constexpr T Max(T a, T b) { return ((a > b) ? a : b); }
626
631namespace util {}
632
633} // namespace stk
634
635#endif /* STK_DEFS_H_ */
static void __stk_dmb()
Hardware memory barrier: ensures visibility across cores and bus masters.
#define __stk_forceinline
Forces compiler to always inline the decorated function, regardless of optimisation level.
Definition stk_defs.h:175
static void __stk_debug_break()
Definition stk_defs.h:372
Namespace of STK package.
static constexpr T Max(T a, T b)
Compile-time maximum of two values.
Definition stk_defs.h:625
static constexpr T Min(T a, T b)
Compile-time minimum of two values.
Definition stk_defs.h:619
Internal utility namespace containing data structure helpers (linked lists, etc.) used by the kernel ...
Selects a static array element count at compile time based on a mode flag.
Definition stk_defs.h:562
static constexpr size_t Value
Definition stk_defs.h:568