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
281 ~SyncObjectBase() = default;
282
283 void WakeOne() override
284 {
285 IKernelService::GetInstance()->Wake(this, false);
286 }
287
288 void WakeAll() override
289 {
290 IKernelService::GetInstance()->Wake(this, true);
291 }
292
294 {
295 return m_wait_list;
296 }
297
299};
300
302inline bool ISyncObject::Tick(Timeout elapsed_ticks)
303{
305
306 // note: ScopedCriticalSection usage
307 //
308 // Single-core: no critical section needed - Tick() runs inside the
309 // SysTick ISR which already executes with interrupts disabled, making
310 // re-entrancy impossible on the local core.
311 //
312 // Multi-core: critical section is required because the tick handler on
313 // each core may call Tick() concurrently for the same Semaphore instance,
314 // and ISyncObject::Tick() is not re-entrant.
315#if (STK_ARCH_CPU_COUNT > 1)
317#endif
318
320
321 while (itr != nullptr)
322 {
324
325 if (!itr->Tick(elapsed_ticks))
326 {
327 itr->Wake(true);
328 }
329
330 itr = next;
331 }
332
333 return !wlist.IsEmpty();
334}
335
338{
339 Weight max_weight = NO_WEIGHT;
341
342 while (itr != nullptr)
343 {
344 const Weight w = GetUserTaskFromTid(itr->GetTid())->GetWeight();
345 if (w > max_weight)
346 {
347 max_weight = w;
348 }
349
351 }
352
353 return ((max_weight > comp) ? max_weight : NO_WEIGHT);
354}
355
366
376
383static __stk_forceinline Time GetMsFromTicks(Ticks tick_count, uint32_t resolution)
384{
385 return static_cast<Time>((tick_count * static_cast<Time>(resolution)) / 1000LL);
386}
387
394static __stk_forceinline Ticks GetTicksFromMs(Time ms, uint32_t resolution)
395{
396 Ticks tick_count = 0LL;
397
398 if (resolution != 0U)
399 {
400 tick_count = static_cast<Ticks>((ms * 1000LL) / static_cast<Time>(resolution));
401 }
402
403 return tick_count;
404}
405
417
424{
425 const Time time_ms = static_cast<Time>(ms);
426 const Ticks tick_count = GetTicksFromMs(time_ms);
427
428 const Ticks final_ticks = (tick_count < static_cast<Ticks>(WAIT_INFINITE)) ?
429 tick_count : static_cast<Ticks>(WAIT_INFINITE);
430
431 return static_cast<Timeout>(final_ticks);
432}
433
442
450{
451 const IKernelService *const service = IKernelService::GetInstance();
452 const uint32_t resolution = service->GetTickResolution();
453 const Ticks tick_count = service->GetTicks();
454
455 return ((resolution == 1000U) ? tick_count :
456 ((tick_count * static_cast<Ticks>(resolution)) / 1000LL));
457}
458
467
476
483static __stk_forceinline void Sleep(Timeout tick_count)
484{
485 IKernelService::GetInstance()->Sleep(tick_count);
486}
487
500
508static __stk_forceinline bool SleepUntil(Ticks timestamp)
509{
510 return IKernelService::GetInstance()->SleepUntil(timestamp);
511}
512
525{
527}
528
550
561{
562 return IKernelService::GetInstance()->SetWeight(tid, weight);
563}
564
575{
576 return SetWeight(GetTid(), weight);
577}
578
588{
589 return IKernelService::GetInstance()->SetTimeSlice(tid, ticks);
590}
591
598{
599 return SetTimeSlice(GetTid(), ticks);
600}
601
608static __stk_forceinline void Delay(Timeout tick_count)
609{
610 IKernelService::GetInstance()->Delay(tick_count);
611}
612
623
624} // namespace stk
625
626#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:146
static Time GetMsFromTicks(Ticks tick_count, uint32_t resolution)
Convert ticks to milliseconds.
Definition stk_helper.h:383
static void Yield()
Notify scheduler to switch to the next runnable task.
Definition stk_helper.h:546
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:587
static void Sleep(Timeout tick_count)
Put calling process into a sleep state.
Definition stk_helper.h:483
static void SleepCancel(TId task_id)
Cancel sleep of the task.
Definition stk_helper.h:524
static void SleepMs(Timeout ms)
Put calling process into a sleep state.
Definition stk_helper.h:496
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:449
@ 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:94
int64_t Ticks
Ticks value.
Definition stk_common.h:161
static void DelayMs(Timeout ms)
Delay calling process by busy-waiting until the deadline expires.
Definition stk_helper.h:619
int32_t Timeout
Timeout time (ticks).
Definition stk_common.h:156
static bool SleepUntil(Ticks timestamp)
Put calling process into a sleep state until the specified timestamp.
Definition stk_helper.h:508
int64_t Time
Time value.
Definition stk_common.h:166
static Ticks GetTicksFromMs(Time ms, uint32_t resolution)
Convert milliseconds to ticks.
Definition stk_helper.h:394
static uint32_t GetTickResolution()
Get number of microseconds in one tick.
Definition stk_helper.h:372
static uint32_t GetSysTimerFrequency()
Get system timer frequency.
Definition stk_helper.h:472
static void Delay(Timeout tick_count)
Delay calling process by busy-waiting until the deadline expires.
Definition stk_helper.h:608
static constexpr Weight NO_WEIGHT
Weight value: weight is not set.
Definition stk_common.h:225
static Ticks GetTicks()
Get number of ticks elapsed since kernel start.
Definition stk_helper.h:438
static Weight SetWeight(TId tid, Weight weight)
Change the base scheduling weight of a task at run-time.
Definition stk_helper.h:560
static constexpr Timeout WAIT_INFINITE
Timeout value: block indefinitely until the synchronization object is signaled.
Definition stk_common.h:214
static TId GetTid()
Get task/thread Id of the calling task.
Definition stk_helper.h:362
static Timeout GetTicksFromMsClampedToTimeout(Timeout ms)
Convert milliseconds to ticks and clamp the result to a Timeout type.
Definition stk_helper.h:423
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:463
uint64_t Cycles
Cycles value.
Definition stk_common.h:171
Word TId
Task (thread) id.
Definition stk_common.h:151
int32_t Weight
Weight value (aka priority).
Definition stk_common.h:176
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:422
Wait object.
Definition stk_common.h:471
DLHeadType ListHeadType
List head type for IWaitObject elements.
Definition stk_common.h:476
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:586
virtual bool Tick(Timeout elapsed_ticks)
Called by kernel on every system tick to handle timeout logic of waiting tasks.
Definition stk_helper.h:302
static void AddWaitObject(IWaitObject::ListHeadType &wlist, IWaitObject *wobj)
Called by kernel when a new task starts waiting on this event.
Definition stk_common.h:605
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:621
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:337
Interface for a user task.
Definition stk_common.h:780
virtual Weight GetWeight() const
Get static base weight of the task.
Definition stk_common.h:884
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()=default
Destructor.
void WakeAll() override
Wake all tasks currently in the wait list.
Definition stk_helper.h:288
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 m_wait_list
Tasks blocked on this object.
Definition stk_helper.h:298
void WakeOne() override
Wake the first task in the wait list (FIFO order).
Definition stk_helper.h:283
const IWaitObject::ListHeadType & GetWaitList() const override
Get list of tasks blocked on this object.
Definition stk_helper.h:266
IWaitObject::ListHeadType & GetWaitList() override
Get list of tasks blocked on this object.
Definition stk_helper.h:293
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
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.