17 #include <intrinsics.h>
18 #if (__IAR_SYSTEMS_ICC__ < 8)
19 #error "Only IAR EWARM 8.0 and higher is supported by STK."
29#include "stk_config.h"
42#ifndef STK_TICKLESS_IDLE
43 #define STK_TICKLESS_IDLE (0)
50#ifndef STK_STRICT_COMPLIANCY
51 #define STK_STRICT_COMPLIANCY (0)
62#ifndef STK_TICKLESS_USE_ARM_DWT
63 #define STK_TICKLESS_USE_ARM_DWT (1)
76#ifndef STK_TICKLESS_TICKS_MAX
77 #define STK_TICKLESS_TICKS_MAX (1000)
79#if STK_TICKLESS_TICKS_MAX > 100000
80 #error "STK_TICKLESS_TICKS_MAX is too large: cpu_ticks_requested may overflow uint32_t."
128#ifndef STK_TLS_PREFER_REGISTER
129 #ifdef _STK_ARCH_RISC_V
130 #define STK_TLS_PREFER_REGISTER (1)
132 #define STK_TLS_PREFER_REGISTER (0)
146#ifndef STK_MPU_STACK_GUARD
147 #define STK_MPU_STACK_GUARD (0)
162#ifndef STK_MPU_TASK_REGIONS
163 #define STK_MPU_TASK_REGIONS (2)
166#if STK_MPU_STACK_GUARD && (STK_MPU_TASK_REGIONS != 2) && (STK_MPU_TASK_REGIONS != 4)
167 #error "STK_MPU_TASK_REGIONS must be defined as 2 or 4"
179#if STK_SEGGER_SYSVIEW || STK_MPU_STACK_GUARD
180 #ifndef STK_STACK_NEEDS_TASK_ID
181 #define STK_STACK_NEEDS_TASK_ID (1)
192#if !defined(STK_SYNC_DEBUG_NAMES) && STK_SEGGER_SYSVIEW
193 #define STK_SYNC_DEBUG_NAMES (1)
194#elif !defined(STK_SYNC_DEBUG_NAMES)
195 #define STK_SYNC_DEBUG_NAMES (0)
201#if !STK_STRICT_COMPLIANCY
202 #define STK_VIRT_DTOR
204 #define STK_VIRT_DTOR virtual
213#if defined(__GNUC__) || defined(__ICCARM__)
214 #define __stk_forceinline __attribute__((always_inline)) inline
215#elif defined(_MSC_VER)
216 #define __stk_forceinline __forceinline
218 #define __stk_forceinline inline
227#if defined(__GNUC__) || defined(__ICCARM__)
228 #define __stk_aligned(x) __attribute__((aligned(x)))
230 #define __stk_aligned(x)
238#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) || defined(__CC_ARM) || defined(__ARMCC_VERSION)
239 #define __stk_weak __attribute__((weak))
251#if defined(__GNUC__) || defined(__ICCARM__)
252 #define __stk_attr_naked __attribute__((naked))
254 #define __stk_attr_naked
262#if defined(__GNUC__) || defined(__ICCARM__)
263 #define __stk_attr_noreturn __attribute__((__noreturn__))
265 #define __stk_attr_noreturn
273#if defined(__GNUC__) || defined(__ICCARM__)
274 #define __stk_attr_unused __attribute__((unused))
276 #define __stk_attr_unused
284#if defined(__GNUC__) || defined(__ICCARM__)
285 #define __stk_attr_used __attribute__((used))
287 #define __stk_attr_used
295#if defined(__GNUC__) || defined(__ICCARM__)
296 #define __stk_attr_noinline __attribute__((noinline))
298 #define __stk_attr_noinline
306#if defined(__GNUC__) || defined(__ICCARM__)
307 #define __stk_attr_deprecated __attribute__((deprecated))
308#elif defined(_MSC_VER)
309 #define __stk_attr_deprecated __declspec(deprecated)
311 #define __stk_attr_deprecated
319#if defined(__GNUC__) || defined(__clang__)
321#elif defined(__ICCARM__)
323#elif defined(_MSC_VER)
326 #error "__stk_full_memfence() is not implemented for this compiler. Add a definition to stk_defs.h."
337#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
338 static __stk_forceinline void __stk_compiler_barrier() { __asm
volatile(
"" :::
"memory"); }
339#elif defined(_MSC_VER)
342 #error "__stk_compiler_barrier() is not implemented for this compiler. Add a definition to stk_defs.h."
360#ifndef __stk_relax_cpu
361#if defined(__GNUC__) || defined(__clang__)
362 #if defined(__i386__) || defined(__x86_64__)
364 #elif defined(__riscv)
365 #ifdef __riscv_zihintpause
368 static __stk_forceinline void __stk_relax_cpu() { __asm
volatile(
"nop" :::
"memory"); }
370 #elif defined(__ARM_ARCH) || defined(_STK_ARCH_ARM_CORTEX_M)
371 static __stk_forceinline void __stk_relax_cpu() { __asm
volatile(
"yield" :::
"memory"); }
373 static __stk_forceinline void __stk_relax_cpu() { __asm
volatile(
"" :::
"memory"); }
375#elif defined(__ICCARM__)
377#elif defined(_MSC_VER)
379 #if defined(_M_IX86) || defined(_M_X64)
381 #elif defined(_M_ARM) || defined(_M_ARM64)
387 #error "__stk_relax_cpu() is not implemented for this compiler. Add a definition to stk_defs.h."
405#if defined(DEBUG) || defined(_DEBUG)
406 #if defined(_STK_ARCH_ARM_CORTEX_M)
408 #elif defined(_STK_ARCH_RISC_V)
410 #elif defined(_STK_ARCH_X86_WIN32)
425#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))
426 #define __stk_constexpr_cpp17 constexpr
428 #define __stk_constexpr_cpp17
447#ifdef _STK_ASSERT_REDIRECT
448 extern void STK_ASSERT_HANDLER(
const char *,
const char *, int32_t);
449 #define STK_ASSERT(e) ((e) ? (void)0 : STK_ASSERT_HANDLER(#e, __FILE__, __LINE__))
451 #if defined(DEBUG) || defined(_DEBUG)
453 #define STK_ASSERT(e) assert(e)
455 #define STK_ASSERT(e)
467#define STK_STATIC_ASSERT_DESC_N(NAME, X, DESC) static_assert((X), DESC)
475#define STK_STATIC_ASSERT_DESC(X, DESC) STK_STATIC_ASSERT_DESC_N(_, X, DESC)
484#define STK_STATIC_ASSERT_N(NAME, X) STK_STATIC_ASSERT_DESC_N(N, (X), #X)
492#define STK_STATIC_ASSERT(X) STK_STATIC_ASSERT_DESC_N(_, (X), #X)
501#ifndef STK_STACK_MEMORY_FILLER
502 #define STK_STACK_MEMORY_FILLER (static_cast<stk::Word>((sizeof(stk::Word) <= 4U) ? 0xDEADBEEFU : 0xDEADBEEFDEADBEEFULL))
508#ifndef STK_STACK_MEMORY_ALIGN
510 #define STK_STACK_MEMORY_ALIGN (16U)
511 #elif defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
512 #define STK_STACK_MEMORY_ALIGN (8U)
514 #define STK_STACK_MEMORY_ALIGN (4U)
528#ifndef STK_CS_NESTINGS_MAX
529 #define STK_CS_NESTINGS_MAX (16U)
538#ifndef STK_ARCH_CPU_COUNT
539 #define STK_ARCH_CPU_COUNT (1U)
557#ifndef STK_STACK_SIZE_MIN
559 #if defined(__riscv_32e) && (__riscv_32e == 1)
561 #if !defined(__riscv_flen) || (__riscv_flen == 0)
562 #define STK_STACK_SIZE_MIN (32U)
565 #define STK_STACK_SIZE_MIN (32U + (__riscv_flen * 2))
570 #if !defined(__riscv_flen) || (__riscv_flen == 0)
571 #define STK_STACK_SIZE_MIN (256U)
574 #define STK_STACK_SIZE_MIN (512U + (__riscv_flen * 2))
579 #define STK_STACK_SIZE_MIN (32U)
591#ifndef STK_SLEEP_TRAP_STACK_SIZE
592 #define STK_SLEEP_TRAP_STACK_SIZE (STK_STACK_SIZE_MIN)
606template <
size_t MODE,
size_t FLAG,
size_t ONTRUE,
size_t ONFALSE>
609#if defined(_MSC_VER) || defined(__ICCARM__)
611 static constexpr size_t Value = ((ONTRUE > ONFALSE) ? ONTRUE : ONFALSE);
614 static constexpr size_t Value = (((MODE & FLAG) != 0U) ? ONTRUE : ONFALSE);
628#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
629 #define STK_ENDIAN_IDX_HI (0U)
630 #define STK_ENDIAN_IDX_LO (1U)
632 #define STK_ENDIAN_IDX_HI (1U)
633 #define STK_ENDIAN_IDX_LO (0U)
647#define STK_NONCOPYABLE_CLASS(TYPE)\
648 TYPE(const TYPE &) = delete;\
649 TYPE &operator=(const TYPE &) = delete;
654#define STK_UNUSED(X) static_cast<void>((X))
665#if __cplusplus >= 202002L
666 #define STK_LIKELY(x) ([&]() { if (!!(x)) [[likely]] { return true; } else { return false; } }())
667 #define STK_UNLIKELY(x) ([&]() { if (!!(x)) { return true; } else [[unlikely]] { return false; } }())
668#elif defined(__GNUC__) || defined(__clang__)
669 #define STK_LIKELY(x) __builtin_expect(!!(x), 1)
670 #define STK_UNLIKELY(x) __builtin_expect(!!(x), 0)
672 #define STK_LIKELY(x) (x)
673 #define STK_UNLIKELY(x) (x)
681#define STK_STATIC_ARRAY_SIZE(ARRAY) static_cast<size_t>(sizeof(ARRAY) / sizeof(ARRAY[0]))
692static constexpr T
Min(T a, T b)
noexcept {
return ((a < b) ? a : b); }
698static constexpr T
Max(T a, T b)
noexcept {
return ((a > b) ? a : b); }
704static constexpr T
Align(T v, T align)
noexcept
706 return ((v + align -
static_cast<T
>(1U)) / align) * align;
715 return (v + align -
static_cast<T
>(1U)) & ~(align -
static_cast<T
>(1U));
725 uint32_t temp_val = value;
727#if defined(__GNUC__) || defined(__clang__)
728 ret_val =
static_cast<uint32_t
>(__builtin_clz(temp_val));
729#elif defined(__ICCARM__)
730 ret_val =
static_cast<uint32_t
>(__CLZ(temp_val));
735 if (temp_val <= 0x0000FFFFU) { count += 16U; temp_val = temp_val << 16U; }
else { }
736 if (temp_val <= 0x00FFFFFFU) { count += 8U; temp_val = temp_val << 8U; }
else { }
737 if (temp_val <= 0x0FFFFFFFU) { count += 4U; temp_val = temp_val << 4U; }
else { }
738 if (temp_val <= 0x3FFFFFFFU) { count += 2U; temp_val = temp_val << 2U; }
else { }
739 if (temp_val <= 0x7FFFFFFFU) { count += 1U; }
else { }
758#ifndef _STK_CUSTOM_MEMCPY
759static void STK_MEMCPY(
void *
const dest,
const void *
const src,
const size_t size);
765#ifndef _STK_CUSTOM_MEMSET
766static void STK_MEMSET(
void *
const dest,
const uint8_t value,
const size_t size);
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.
static void STK_MEMCPY(void *const dest, const void *const src, const size_t size)
A wrapper for a built-in memcpy, redefine to your own if required.
static void STK_MEMSET(void *const dest, const uint8_t value, const size_t size)
A wrapper for a built-in memset, redefine to your own if required.
static void __stk_debug_break()
Namespace of STK package.
static uint32_t CountLeadingZeros(const uint32_t value) noexcept
Count leading zeros.
static constexpr T AlignPow2(T v, T align) noexcept
Fast compile-time alignment for power-of-two boundaries.
static constexpr T Align(T v, T align) noexcept
Aligns a value towards the next larger size multiple.
static constexpr T Max(T a, T b) noexcept
Compile-time maximum of two values.
static constexpr T Min(T a, T b) noexcept
Compile-time minimum of two values.
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.
static constexpr size_t Value