SuperTinyKernel™ RTOS 1.08.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk_helper.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_HELPER_H_
11#define STK_HELPER_H_
12
13#include "stk_common.h"
14#include "stk_arch.h"
15#ifdef _STK_CORTEX_M_TRUSTZONE_NON_SECURE
16 #include "arch/arm/cortex-m/stk_arch_arm-tz.h"
17#endif
18
22
23namespace stk {
24
35template <size_t TStackSize> struct StackMemoryDef
36{
37 enum EConsts : size_t
38 {
39 SIZE = TStackSize
40 };
41
45#if STK_MPU_STACK_GUARD
46 #if STK_ARCH_ARMV8_M
47 // ARMv8-M alignment is 32 bytes.
48 typedef __stk_aligned(32U) Word Type[SIZE];
49 #else
50 // ARMv7-M alignment is a size of the memory region.
51 typedef __stk_aligned(TStackSize * sizeof(Word)) Word Type[SIZE];
52 #endif
53#else
55#endif
56};
57
91template <size_t _StackSize, EAccessMode _AccessMode>
92class Task
93#ifdef _STK_CORTEX_M_TRUSTZONE_NON_SECURE
94 : public tz::nsec::NsTask
95#else
96 : public ITask
97#endif
98{
99public:
100 enum { STACK_SIZE = _StackSize };
101
102 const Word *GetStack() const override { return const_cast<Word *>(m_stack); }
103 size_t GetStackSize() const override { return _StackSize; }
104 EAccessMode GetAccessMode() const override { return _AccessMode; }
105
106 TId GetTid() const { return GetTidFromUserTask(this); }
107
108protected:
110
119 {}
120
124 STK_VIRT_DTOR ~Task() = default;
125
126private:
128};
129
145template <Weight _Weight, size_t _StackSize, EAccessMode _AccessMode>
146class TaskW
147#ifdef _STK_CORTEX_M_TRUSTZONE_NON_SECURE
148 : public tz::nsec::NsTask
149#else
150 : public ITask
151#endif
152{
153public:
154 enum { STACK_SIZE = _StackSize };
155
156 const Word *GetStack() const override { return const_cast<Word *>(m_stack); }
157 size_t GetStackSize() const override { return _StackSize; }
158 EAccessMode GetAccessMode() const override { return _AccessMode; }
159 Weight GetWeight() const override { return _Weight; }
160
161 TId GetTid() const { return GetTidFromUserTask(this); }
162
163protected:
165
173 TaskW() : m_stack() {}
174
179
180private:
182};
183
191template <size_t _StackSize>
193{
194public:
199
205 explicit StackMemoryWrapper(MemoryType *stack) : m_stack(stack)
206 {
207 STK_STATIC_ASSERT(_StackSize >= STACK_SIZE_MIN);
208 }
209
213
216 const Word *GetStack() const override { return (*m_stack); }
217
220 size_t GetStackSize() const override { return _StackSize; }
221
222private:
224};
225
247#ifdef _STK_CORTEX_M_TRUSTZONE_NON_SECURE
248 : public tz::nsec::NsSyncObject
249#else
250 : public ISyncObject
251#endif
252{
253 friend class IKernelService;
254
255public:
256 void AddWaitObject(IWaitObject *wobj) override
257 {
259 }
260
261 void RemoveWaitObject(IWaitObject *wobj) override
262 {
264 }
265
267 {
268 return m_wait_list;
269 }
270
271protected:
276 {}
277
287 {
289
290 ISyncObject::ListHeadType *const head = GetHead();
291 if (head != nullptr)
292 {
293 head->Unlink(this);
294 }
295 }
296
297 void WakeOne() override
298 {
299 IKernelService::GetInstance()->Wake(this, false);
300 }
301
302 void WakeAll() override
303 {
304 IKernelService::GetInstance()->Wake(this, true);
305 }
306
308 {
309 return m_wait_list;
310 }
311
313};
314
316inline bool ISyncObject::Tick(Timeout elapsed_ticks)
317{
319
320 // note: ScopedCriticalSection usage
321 //
322 // Single-core: no critical section needed - Tick() runs inside the
323 // SysTick ISR which already executes with interrupts disabled, making
324 // re-entrancy impossible on the local core.
325 //
326 // Multi-core: critical section is required because the tick handler on
327 // each core may call Tick() concurrently for the same Semaphore instance,
328 // and ISyncObject::Tick() is not re-entrant.
329#if (STK_ARCH_CPU_COUNT > 1)
331#endif
332
334
335 while (itr != nullptr)
336 {
338
339 if (!itr->Tick(elapsed_ticks))
340 {
341 itr->Wake(true);
342 }
343
344 itr = next;
345 }
346
347 return !wlist.IsEmpty();
348}
349
352{
353 Weight max_weight = NO_WEIGHT;
355
356 while (itr != nullptr)
357 {
358 const Weight w = GetUserTaskFromTid(itr->GetTid())->GetWeight();
359 if (w > max_weight)
360 {
361 max_weight = w;
362 }
363
365 }
366
367 return ((max_weight > comp) ? max_weight : NO_WEIGHT);
368}
369
380
390
397static __stk_forceinline Time GetMsFromTicks(Ticks tick_count, uint32_t resolution)
398{
399 return static_cast<Time>((tick_count * static_cast<Time>(resolution)) / 1000LL);
400}
401
408static __stk_forceinline Ticks GetTicksFromMs(Time ms, uint32_t resolution)
409{
410 Ticks tick_count = 0LL;
411
412 if (resolution != 0U)
413 {
414 tick_count = static_cast<Ticks>((ms * 1000LL) / static_cast<Time>(resolution));
415 }
416
417 return tick_count;
418}
419
431
438{
439 const Time time_ms = static_cast<Time>(ms);
440 const Ticks tick_count = GetTicksFromMs(time_ms);
441
442 const Ticks final_ticks = (tick_count < static_cast<Ticks>(WAIT_INFINITE)) ?
443 tick_count : static_cast<Ticks>(WAIT_INFINITE);
444
445 return static_cast<Timeout>(final_ticks);
446}
447
456
464{
465 const IKernelService *const service = IKernelService::GetInstance();
466 const uint32_t resolution = service->GetTickResolution();
467 const Ticks tick_count = service->GetTicks();
468
469 return ((resolution == 1000U) ? tick_count :
470 ((tick_count * static_cast<Ticks>(resolution)) / 1000LL));
471}
472
481
490
497static __stk_forceinline void Sleep(Timeout tick_count)
498{
499 IKernelService::GetInstance()->Sleep(tick_count);
500}
501
514
522static __stk_forceinline bool SleepUntil(Ticks timestamp)
523{
524 return IKernelService::GetInstance()->SleepUntil(timestamp);
525}
526
539{
541}
542
564
575{
576 return IKernelService::GetInstance()->SetWeight(tid, weight);
577}
578
589{
590 return SetWeight(GetTid(), weight);
591}
592
602{
603 return IKernelService::GetInstance()->SetTimeSlice(tid, ticks);
604}
605
612{
613 return SetTimeSlice(GetTid(), ticks);
614}
615
622static __stk_forceinline void Delay(Timeout tick_count)
623{
624 IKernelService::GetInstance()->Delay(tick_count);
625}
626
637
638} // namespace stk
639
640#endif /* STK_HELPER_H_ */
Hardware Abstraction Layer (HAL) declarations for the stk::hw namespace.
Contains interface definitions of the library.
#define __stk_forceinline
Forces compiler to always inline the decorated function, regardless of optimisation level.
Definition stk_defs.h:277
#define __stk_aligned(x)
Specifies minimum alignment in bytes for the decorated variable or struct member (data instance prefi...
Definition stk_defs.h:289
#define STK_NONCOPYABLE_CLASS(TYPE)
Disables copy construction and assignment for a class.
Definition stk_defs.h:708
#define STK_STACK_MEMORY_ALIGN
Stack memory alignment.
Definition stk_defs.h:575
#define STK_STATIC_ASSERT(X)
Compile-time assertion. Produces a compilation error if X is false.
Definition stk_defs.h:553
#define STK_VIRT_DTOR
Makes destructors virtual and compliant to strict rules if STK_STRICT_COMPLIANCY=0.
Definition stk_defs.h:261
Namespace of STK package.
uintptr_t Word
Native processor word type.
Definition stk_common.h:160
static Time GetMsFromTicks(Ticks tick_count, uint32_t resolution)
Convert ticks to milliseconds.
Definition stk_helper.h:397
static void Yield()
Notify scheduler to switch to the next runnable task.
Definition stk_helper.h:560
static Timeout SetTimeSlice(TId tid, Timeout ticks)
Change the time-slice quantum of a task at run-time and reload its slice.
Definition stk_helper.h:601
static void Sleep(Timeout tick_count)
Put calling process into a sleep state.
Definition stk_helper.h:497
static void SleepCancel(TId task_id)
Cancel sleep of the task.
Definition stk_helper.h:538
static void SleepMs(Timeout ms)
Put calling process into a sleep state.
Definition stk_helper.h:510
EAccessMode
Hardware access modes by the task.
Definition stk_common.h:36
static constexpr ITask * GetUserTaskFromTid(TId task_id) noexcept
Get task instance from its identifier.
Definition stk_arch.h:725
static Time GetTimeNowMs()
Get current time in milliseconds since kernel start.
Definition stk_helper.h:463
@ STACK_SIZE_MIN
Minimum stack size in elements of Word. Used as a lower bound for all stack allocations (user task,...
Definition stk_common.h:108
int64_t Ticks
Ticks value.
Definition stk_common.h:175
static void DelayMs(Timeout ms)
Delay calling process by busy-waiting until the deadline expires.
Definition stk_helper.h:633
int32_t Timeout
Timeout time (ticks).
Definition stk_common.h:170
static bool SleepUntil(Ticks timestamp)
Put calling process into a sleep state until the specified timestamp.
Definition stk_helper.h:522
int64_t Time
Time value.
Definition stk_common.h:180
static Ticks GetTicksFromMs(Time ms, uint32_t resolution)
Convert milliseconds to ticks.
Definition stk_helper.h:408
static uint32_t GetTickResolution()
Get number of microseconds in one tick.
Definition stk_helper.h:386
static uint32_t GetSysTimerFrequency()
Get system timer frequency.
Definition stk_helper.h:486
static void Delay(Timeout tick_count)
Delay calling process by busy-waiting until the deadline expires.
Definition stk_helper.h:622
static constexpr Weight NO_WEIGHT
Weight value: weight is not set.
Definition stk_common.h:239
static Ticks GetTicks()
Get number of ticks elapsed since kernel start.
Definition stk_helper.h:452
static Weight SetWeight(TId tid, Weight weight)
Change the base scheduling weight of a task at run-time.
Definition stk_helper.h:574
static constexpr Timeout WAIT_INFINITE
Timeout value: block indefinitely until the synchronization object is signaled.
Definition stk_common.h:228
static TId GetTid()
Get task/thread Id of the calling task.
Definition stk_helper.h:376
static Timeout GetTicksFromMsClampedToTimeout(Timeout ms)
Convert milliseconds to ticks and clamp the result to a Timeout type.
Definition stk_helper.h:437
static constexpr TId GetTidFromUserTask(const ITask *task) noexcept
Get task identifier from ITask instance.
Definition stk_arch.h:716
static Cycles GetSysTimerCount()
Get system timer count value.
Definition stk_helper.h:477
uint64_t Cycles
Cycles value.
Definition stk_common.h:185
Word TId
Task (thread) id.
Definition stk_common.h:165
int32_t Weight
Weight value (aka priority).
Definition stk_common.h:190
RAII instance that enters the critical section on construction and exits it on destruction.
Definition stk_arch.h:494
Interface for a stack memory region.
Definition stk_common.h:448
Wait object.
Definition stk_common.h:497
DLHeadType ListHeadType
List head type for IWaitObject elements.
Definition stk_common.h:502
virtual TId GetTid() const =0
Get thread Id of the task owning .
virtual void Wake(bool timeout)=0
Wake task.
virtual bool Tick(Timeout elapsed_ticks)=0
Update wait object's waiting time.
Synchronization object interface.
Definition stk_common.h:612
virtual bool Tick(Timeout elapsed_ticks)
Called by kernel on every system tick to handle timeout logic of waiting tasks.
Definition stk_helper.h:316
DLHeadType ListHeadType
List head type for ISyncObject elements.
Definition stk_common.h:620
static void AddWaitObject(IWaitObject::ListHeadType &wlist, IWaitObject *wobj)
Called by kernel when a new task starts waiting on this event.
Definition stk_common.h:631
virtual IWaitObject::ListHeadType & GetMutableWaitList()=0
Get list of tasks blocked on this object.
static void RemoveWaitObject(IWaitObject::ListHeadType &wlist, IWaitObject *wobj)
Called by kernel when a waiting task is being removed (timeout expired, wait aborted,...
Definition stk_common.h:647
virtual const IWaitObject::ListHeadType & GetWaitList() const =0
Get list of tasks blocked on this object.
Weight FindWeightHigherThan(Weight comp) const
Find higher weight within linked wait objects.
Definition stk_helper.h:351
Interface for a user task.
Definition stk_common.h:824
virtual Weight GetWeight() const
Get static base weight of the task.
Definition stk_common.h:928
Interface for the kernel services exposed to the user processes during run-time when Kernel started s...
virtual TId GetTid() const =0
Get thread Id of the currently running task.
virtual Timeout SetTimeSlice(TId tid, Timeout ticks)=0
Change the time-slice quantum of the task at run-time and reload its slice.
virtual void Wake(ISyncObject *sobj, bool all)=0
Wake one or all tasks currently waiting on a synchronization object.
virtual void SleepCancel(TId task_id)=0
Cancel sleep of the task.
static IKernelService * GetInstance()
Get CPU-local instance of the kernel service.
virtual uint32_t GetTickResolution() const =0
Get number of microseconds in one tick.
virtual bool SleepUntil(Ticks timestamp)=0
Put calling process into a sleep state until the specified timestamp.
virtual Ticks GetTicks() const =0
Get number of ticks elapsed since kernel start.
virtual void SwitchToNext()=0
Notify scheduler to switch to the next task (yield).
virtual void Sleep(Timeout ticks)=0
Put calling process into a sleep state.
virtual Weight SetWeight(TId tid, Weight weight)=0
Change the base weight of the task at run-time (replaces ITask::GetWeight() value).
virtual Cycles GetSysTimerCount() const =0
Get system timer count value.
virtual uint32_t GetSysTimerFrequency() const =0
Get system timer frequency.
virtual void Delay(Timeout ticks)=0
Delay calling process.
Stack memory type definition.
Definition stk_helper.h:36
Word Type[SIZE]
Stack memory type.
Definition stk_helper.h:51
Task()
Initializes task instance and zero-initializes its internal stack memory.
Definition stk_helper.h:118
Task(const Task &)=delete
TId GetTid() const
Definition stk_helper.h:106
~Task()=default
Destructor.
size_t GetStackSize() const override
Get number of elements of the stack memory array.
Definition stk_helper.h:103
const Word * GetStack() const override
Get pointer to the stack memory.
Definition stk_helper.h:102
StackMemoryDef< _StackSize >::Type m_stack
Stack memory region, STK_STACK_MEMORY_ALIGN-byte aligned.
Definition stk_helper.h:127
EAccessMode GetAccessMode() const override
Get pointer to the stack memory.
Definition stk_helper.h:104
Weight GetWeight() const override
Get static base weight of the task.
Definition stk_helper.h:159
TaskW(const TaskW &)=delete
const Word * GetStack() const override
Get pointer to the stack memory.
Definition stk_helper.h:156
~TaskW()=default
Destructor.
EAccessMode GetAccessMode() const override
Get pointer to the stack memory.
Definition stk_helper.h:158
size_t GetStackSize() const override
Get number of elements of the stack memory array.
Definition stk_helper.h:157
TaskW()
Initializes task instance and zero-initializes its internal stack memory.
Definition stk_helper.h:173
TId GetTid() const
Definition stk_helper.h:161
StackMemoryDef< _StackSize >::Type m_stack
Stack memory region, 16-byte aligned.
Definition stk_helper.h:181
size_t GetStackSize() const override
Get number of elements in the wrapped stack array.
Definition stk_helper.h:220
~StackMemoryWrapper()=default
Destructor.
const Word * GetStack() const override
Get pointer to the first element of the wrapped stack array.
Definition stk_helper.h:216
StackMemoryDef< _StackSize >::Type MemoryType
Definition stk_helper.h:198
StackMemoryWrapper(MemoryType *stack)
Construct a wrapper around an existing stack memory array.
Definition stk_helper.h:205
~SyncObjectBase()
Destructor.
Definition stk_helper.h:286
void WakeAll() override
Wake all tasks currently in the wait list.
Definition stk_helper.h:302
SyncObjectBase()
Constructor.
Definition stk_helper.h:275
void RemoveWaitObject(IWaitObject *wobj) override
Called by kernel when a waiting task is being removed (timeout expired, wait aborted,...
Definition stk_helper.h:261
IWaitObject::ListHeadType & GetMutableWaitList() override
Get list of tasks blocked on this object.
Definition stk_helper.h:307
IWaitObject::ListHeadType m_wait_list
Tasks blocked on this object.
Definition stk_helper.h:312
void WakeOne() override
Wake the first task in the wait list (FIFO order).
Definition stk_helper.h:297
const IWaitObject::ListHeadType & GetWaitList() const override
Get list of tasks blocked on this object.
Definition stk_helper.h:266
friend class IKernelService
Definition stk_helper.h:253
void AddWaitObject(IWaitObject *wobj) override
Called by kernel when a new task starts waiting on this event.
Definition stk_helper.h:256
void Unlink(DLEntryType *entry)
Remove entry from this list.
DLEntryType * GetFirst()
Get the first (front) entry without removing it.
bool IsEmpty() const
Check whether the list contains no entries.
DLEntryType * GetNext()
Get the next entry in the list.
static __stk_forceinline TTargetType * ListEntryToParent(TSourceType *const lentry)
Safely casts an intrusive list entry to its concrete parent container object type.