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 (0U)
50#ifndef STK_STRICT_COMPLIANCY
51 #define STK_STRICT_COMPLIANCY (0U)
62#ifndef STK_TICKLESS_USE_ARM_DWT
63 #define STK_TICKLESS_USE_ARM_DWT (1U)
76#ifndef STK_TICKLESS_TICKS_MAX
77 #define STK_TICKLESS_TICKS_MAX (1000U)
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 (1U)
132 #define STK_TLS_PREFER_REGISTER (0U)
146#ifndef STK_MPU_STACK_GUARD
147 #define STK_MPU_STACK_GUARD (0U)
162#ifndef STK_MPU_TASK_REGIONS
163 #define STK_MPU_TASK_REGIONS (2U)
165#ifndef STK_MPU_TASK_REGIONS_NS
166 #define STK_MPU_TASK_REGIONS_NS (STK_MPU_TASK_REGIONS)
168#if STK_MPU_STACK_GUARD && \
169 (STK_MPU_TASK_REGIONS != 2U) && (STK_MPU_TASK_REGIONS != 4U) && \
170 (STK_MPU_TASK_REGIONS != 6U) && (STK_MPU_TASK_REGIONS != 8U) && \
171 (STK_MPU_TASK_REGIONS != 12U) && (STK_MPU_TASK_REGIONS != 16U)
172 #error "STK_MPU_TASK_REGIONS_S must be defined as 2, 4, 6, 8, 12, or 16"
174#if STK_MPU_STACK_GUARD && \
175 (STK_MPU_TASK_REGIONS_NS != 2U) && (STK_MPU_TASK_REGIONS_NS != 4U) && \
176 (STK_MPU_TASK_REGIONS_NS != 6U) && (STK_MPU_TASK_REGIONS_NS != 8U) && \
177 (STK_MPU_TASK_REGIONS_NS != 12U) && (STK_MPU_TASK_REGIONS_NS != 16U)
178 #error "STK_MPU_TASK_REGIONS_NS must be defined as 2, 4, 6, 8, 12, or 16"
185 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
186 #define STK_TZ_SECURE (1)
188 #define STK_TZ_SECURE (0)
195#ifndef STK_TZ_NON_SECURE
196 #if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 1)
197 #define STK_TZ_NON_SECURE (1)
199 #define STK_TZ_NON_SECURE (0)
204#ifdef _STK_CORTEX_M_TRUSTZONE_NON_SECURE
205#if !STK_TZ_NON_SECURE
206 #error "Do not use -cmse compiler flag for Non-Secure binary compilation!"
211#if STK_MPU_STACK_GUARD && !STK_MPU
212 #error "Enable MPU support (STK_MPU=1) to use per-task MPU feature (STK_MPU_STACK_GUARD=1)!"
218#ifndef STK_CORE_FREQ_UNIFIED
219 #define STK_CORE_FREQ_UNIFIED (1U)
231#if STK_SEGGER_SYSVIEW || STK_MPU_STACK_GUARD
232 #ifndef STK_STACK_NEEDS_TASK_ID
233 #define STK_STACK_NEEDS_TASK_ID (1U)
244#if !defined(STK_SYNC_DEBUG_NAMES) && STK_SEGGER_SYSVIEW
245 #define STK_SYNC_DEBUG_NAMES (1U)
246#elif !defined(STK_SYNC_DEBUG_NAMES)
247 #define STK_SYNC_DEBUG_NAMES (0U)
253#ifndef STK_STACK_GUARD
254 #define STK_STACK_GUARD (1U)
260#if !STK_STRICT_COMPLIANCY
261 #define STK_VIRT_DTOR
263 #define STK_VIRT_DTOR virtual
272#if defined(__GNUC__) || defined(__ICCARM__)
273 #define __stk_forceinline __attribute__((always_inline)) inline
274#elif defined(_MSC_VER)
275 #define __stk_forceinline __forceinline
277 #define __stk_forceinline inline
286#if defined(__GNUC__) || defined(__ICCARM__)
287 #define __stk_aligned(x) __attribute__((aligned(x)))
289 #define __stk_aligned(x)
297#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) || defined(__CC_ARM) || defined(__ARMCC_VERSION)
298 #define __stk_weak __attribute__((weak))
310#if defined(__GNUC__) || defined(__ICCARM__)
311 #define __stk_attr_naked __attribute__((naked))
313 #define __stk_attr_naked
321#if defined(__GNUC__) || defined(__ICCARM__)
322 #define __stk_attr_noreturn __attribute__((__noreturn__))
324 #define __stk_attr_noreturn
332#if defined(__GNUC__) || defined(__ICCARM__)
333 #define __stk_attr_unused __attribute__((unused))
335 #define __stk_attr_unused
343#if defined(__GNUC__) || defined(__ICCARM__)
344 #define __stk_attr_used __attribute__((used))
346 #define __stk_attr_used
354#if defined(__GNUC__) || defined(__ICCARM__)
355 #define __stk_attr_noinline __attribute__((noinline))
357 #define __stk_attr_noinline
365#if defined(__GNUC__) || defined(__ICCARM__)
366 #define __stk_attr_deprecated __attribute__((deprecated))
367#elif defined(_MSC_VER)
368 #define __stk_attr_deprecated __declspec(deprecated)
370 #define __stk_attr_deprecated
378#if defined(__GNUC__) || defined(__clang__)
380#elif defined(__ICCARM__)
382#elif defined(_MSC_VER)
385 #error "__stk_full_memfence() is not implemented for this compiler. Add a definition to stk_defs.h."
396#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
397 static __stk_forceinline void __stk_compiler_barrier() { __asm
volatile(
"" :::
"memory"); }
398#elif defined(_MSC_VER)
401 #error "__stk_compiler_barrier() is not implemented for this compiler. Add a definition to stk_defs.h."
419#ifndef __stk_relax_cpu
420#if defined(__GNUC__) || defined(__clang__)
421 #if defined(__i386__) || defined(__x86_64__)
423 #elif defined(__riscv)
424 #ifdef __riscv_zihintpause
427 static __stk_forceinline void __stk_relax_cpu() { __asm
volatile(
"nop" :::
"memory"); }
429 #elif defined(__ARM_ARCH) || defined(_STK_ARCH_ARM_CORTEX_M)
430 static __stk_forceinline void __stk_relax_cpu() { __asm
volatile(
"yield" :::
"memory"); }
432 static __stk_forceinline void __stk_relax_cpu() { __asm
volatile(
"" :::
"memory"); }
434#elif defined(__ICCARM__)
436#elif defined(_MSC_VER)
438 #if defined(_M_IX86) || defined(_M_X64)
440 #elif defined(_M_ARM) || defined(_M_ARM64)
446 #error "__stk_relax_cpu() is not implemented for this compiler. Add a definition to stk_defs.h."
464#if defined(DEBUG) || defined(_DEBUG)
465 #if defined(_STK_ARCH_ARM_CORTEX_M)
467 #elif defined(_STK_ARCH_RISC_V)
469 #elif defined(_STK_ARCH_X86_WIN32)
486#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))
487 #define __stk_constexpr_cpp17 constexpr
489 #define __stk_constexpr_cpp17
508#ifdef _STK_ASSERT_REDIRECT
509 extern void STK_ASSERT_HANDLER(
const char *,
const char *, int32_t);
510 #define STK_ASSERT(e) ((e) ? (void)0 : STK_ASSERT_HANDLER(#e, __FILE__, __LINE__))
512 #if defined(DEBUG) || defined(_DEBUG)
514 #define STK_ASSERT(e) assert(e)
516 #define STK_ASSERT(e)
528#define STK_STATIC_ASSERT_DESC_N(NAME, X, DESC) static_assert((X), DESC)
536#define STK_STATIC_ASSERT_DESC(X, DESC) STK_STATIC_ASSERT_DESC_N(_, X, DESC)
545#define STK_STATIC_ASSERT_N(NAME, X) STK_STATIC_ASSERT_DESC_N(N, (X), #X)
553#define STK_STATIC_ASSERT(X) STK_STATIC_ASSERT_DESC_N(_, (X), #X)
562#ifndef STK_STACK_MEMORY_FILLER
563 #define STK_STACK_MEMORY_FILLER (static_cast<stk::Word>((sizeof(stk::Word) <= 4U) ? 0xDEADBEEFU : 0xDEADBEEFDEADBEEFULL))
569#ifndef STK_STACK_MEMORY_ALIGN
571 #define STK_STACK_MEMORY_ALIGN (16U)
572 #elif defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
573 #define STK_STACK_MEMORY_ALIGN (8U)
575 #define STK_STACK_MEMORY_ALIGN (4U)
589#ifndef STK_CS_NESTINGS_MAX
590 #define STK_CS_NESTINGS_MAX (16U)
599#ifndef STK_ARCH_CPU_COUNT
600 #define STK_ARCH_CPU_COUNT (1U)
618#ifndef STK_STACK_SIZE_MIN
620 #if defined(__riscv_32e) && (__riscv_32e == 1)
622 #if !defined(__riscv_flen) || (__riscv_flen == 0)
623 #define STK_STACK_SIZE_MIN (32U)
626 #define STK_STACK_SIZE_MIN (32U + (__riscv_flen * 2))
631 #if !defined(__riscv_flen) || (__riscv_flen == 0)
632 #define STK_STACK_SIZE_MIN (256U)
635 #define STK_STACK_SIZE_MIN (512U + (__riscv_flen * 2))
640 #define STK_STACK_SIZE_MIN (32U)
652#ifndef STK_SLEEP_TRAP_STACK_SIZE
653 #define STK_SLEEP_TRAP_STACK_SIZE (STK_STACK_SIZE_MIN)
667template <
size_t MODE,
size_t FLAG,
size_t ONTRUE,
size_t ONFALSE>
670#if defined(_MSC_VER) || defined(__ICCARM__)
672 static constexpr size_t Value = ((ONTRUE > ONFALSE) ? ONTRUE : ONFALSE);
675 static constexpr size_t Value = (((MODE & FLAG) != 0U) ? ONTRUE : ONFALSE);
689#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
690 #define STK_ENDIAN_IDX_HI (0U)
691 #define STK_ENDIAN_IDX_LO (1U)
693 #define STK_ENDIAN_IDX_HI (1U)
694 #define STK_ENDIAN_IDX_LO (0U)
708#define STK_NONCOPYABLE_CLASS(TYPE)\
709 TYPE(const TYPE &) = delete;\
710 TYPE &operator=(const TYPE &) = delete;
715#define STK_UNUSED(X) static_cast<void>((X))
726#if __cplusplus >= 202002L
727 #define STK_LIKELY(x) ([&]() { if (!!(x)) [[likely]] { return true; } else { return false; } }())
728 #define STK_UNLIKELY(x) ([&]() { if (!!(x)) { return true; } else [[unlikely]] { return false; } }())
729#elif defined(__GNUC__) || defined(__clang__)
730 #define STK_LIKELY(x) __builtin_expect(!!(x), 1)
731 #define STK_UNLIKELY(x) __builtin_expect(!!(x), 0)
733 #define STK_LIKELY(x) (x)
734 #define STK_UNLIKELY(x) (x)
742#define STK_STATIC_ARRAY_SIZE(ARRAY) static_cast<size_t>(sizeof(ARRAY) / sizeof(ARRAY[0]))
753static constexpr T
Min(T a, T b)
noexcept {
return ((a < b) ? a : b); }
759static constexpr T
Max(T a, T b)
noexcept {
return ((a > b) ? a : b); }
765static constexpr T
Align(T v, T align)
noexcept
767 return ((v + align -
static_cast<T
>(1U)) / align) * align;
776 return (v + align -
static_cast<T
>(1U)) & ~(align -
static_cast<T
>(1U));
786 uint32_t temp_val = value;
788#if defined(__GNUC__) || defined(__clang__)
789 ret_val =
static_cast<uint32_t
>(__builtin_clz(temp_val));
790#elif defined(__ICCARM__)
791 ret_val =
static_cast<uint32_t
>(__CLZ(temp_val));
796 if (temp_val <= 0x0000FFFFU) { count += 16U; temp_val = temp_val << 16U; }
else { }
797 if (temp_val <= 0x00FFFFFFU) { count += 8U; temp_val = temp_val << 8U; }
else { }
798 if (temp_val <= 0x0FFFFFFFU) { count += 4U; temp_val = temp_val << 4U; }
else { }
799 if (temp_val <= 0x3FFFFFFFU) { count += 2U; temp_val = temp_val << 2U; }
else { }
800 if (temp_val <= 0x7FFFFFFFU) { count += 1U; }
else { }
819#ifndef _STK_CUSTOM_MEMCPY
820static void STK_MEMCPY(
void *
const dest,
const void *
const src,
const size_t size);
826#ifndef _STK_CUSTOM_MEMSET
827static 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