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::Kernel< TMode, TSize, TStrategy, TPlatform > Class Template Referencefinal

Concrete implementation of IKernel. More...

#include <stk.h>

Inheritance diagram for stk::Kernel< TMode, TSize, TStrategy, TPlatform >:
Collaboration diagram for stk::Kernel< TMode, TSize, TStrategy, TPlatform >:

Classes

class  KernelTask
 Internal per-slot kernel descriptor that wraps a user ITask instance. More...
class  KernelService
 Concrete implementation of IKernelService exposed to running tasks. More...
class  SleepTrapStack
 Storage bundle for the sleep trap: a Stack descriptor paired with its backing memory. More...
class  ExitTrapStack
 Storage bundle for the exit trap: a Stack descriptor paired with its backing memory. More...

Public Types

enum  EKernelState : uint8_t {
  KSTATE_INACTIVE = 0 ,
  KSTATE_READY ,
  KSTATE_RUNNING ,
  KSTATE_SUSPENDED
}
 Kernel state. More...

Public Member Functions

 Kernel ()
 Construct the kernel with all storage zero-initialized, m_request cleared to REQ_NONE, and m_kstate set to KSTATE_INACTIVE (indicating uninitialized state; advanced to KSTATE_READY by Initialize()).
 ~Kernel ()=default
 Destructor.
void Initialize (uint32_t resolution_us=PERIODICITY_DEFAULT) override
 Initialize kernel.
void AddTask (ITask *user_task) override
 Register task for a soft real-time (SRT) scheduling.
void AddTask (ITask *user_task, Timeout periodicity_tc, Timeout deadline_tc, Timeout start_delay_tc) override
 Register a task for hard real-time (HRT) scheduling.
void RemoveTask (ITask *user_task) override
 Remove a previously added task from the kernel when it is not started.
void ScheduleTaskRemoval (ITask *user_task) override
 Schedule task removal from scheduling (exit).
void SuspendTask (ITask *user_task, bool &suspended) override
 Suspend task.
void ResumeTask (ITask *user_task) override
 Resume task.
void CancelTaskWait (ITask *user_task) override
 Cancel task's in-progress wait on a synchronization object.
bool GetTaskState (ITask *user_task, TaskStateInfo &info) const override
 Get a snapshot of the kernel-side state of a task.
size_t EnumerateKernelTasks (ArrayView< IKernelTask * > tasks) override
 Enumerate kernel tasks.
size_t EnumerateTasks (ArrayView< ITask * > user_tasks) override
 Enumerate user tasks.
void Start () override
 Start the scheduler. This call does not return until all tasks have exited (KERNEL_DYNAMIC mode) or indefinitely (KERNEL_STATIC mode).
bool IsStarted () const
 Check whether scheduler is currently running.
IPlatform * GetPlatform () override
 Get platform driver instance owned by this kernel.
ITaskSwitchStrategy * GetSwitchStrategy () override
 Get task-switching strategy instance owned by this kernel.
EKernelState GetState () const override
 Get kernel state.
template<size_t TMaxCount, typename TCallback>
size_t EnumerateTasksT (TCallback &&callback)
 Enumerate tasks, invoking a callback for each active task.

Static Public Attributes

static constexpr size_t TASKS_MAX = TSize
 Maximum number of concurrently registered tasks. Fixed at compile time. Exceeding this limit in AddTask() triggers a compile-time assert (TASKS_MAX > 0) and a runtime STK_ASSERT.

Protected Types

enum  ERequest : uint8_t {
  REQ_NONE = 0 ,
  REQ_ADD_TASK = (1 << 0)
}
 Bitmask flags for pending inter-task requests that must be processed by the kernel on the next tick (in UpdateTaskRequest()). More...
enum  EFsmState : int8_t {
  FSM_STATE_NONE = -1 ,
  FSM_STATE_SWITCHING ,
  FSM_STATE_SLEEPING ,
  FSM_STATE_WAKING ,
  FSM_STATE_EXITING ,
  FSM_STATE_MAX
}
 Finite-state machine (FSM) state. Encodes what the kernel is currently doing between two consecutive tick events. More...
enum  EFsmEvent : int8_t {
  FSM_EVENT_SWITCH = 0 ,
  FSM_EVENT_SLEEP ,
  FSM_EVENT_WAKE ,
  FSM_EVENT_EXIT ,
  FSM_EVENT_MAX
}
 Finite-state machine (FSM) event. Computed by FetchNextEvent() each tick based on strategy output and current kernel state. More...
typedef StackMemoryWrapper<((32U))> SleepTrapStackMemory
 Stack memory wrapper type for the sleep trap.
typedef StackMemoryWrapper< STACK_SIZE_MIN > ExitTrapStackMemory
 Stack memory wrapper type for the exit trap.
typedef KernelTask TaskStorageType[TASKS_MAX]
 KernelTask array type used as a storage for the KernelTask instances.
typedef ISyncObject::ListHeadType SyncObjectList
 Intrusive list of active ISyncObject instances registered with this kernel. Each sync object in this list receives a Tick() call every kernel tick for timeout tracking. Allocated only when KERNEL_SYNC is set (zero-size otherwise).

Protected Member Functions

void InitTraps ()
 Initialize stack of the traps.
KernelTask * AllocateNewTask (ITask *user_task)
 Allocate new instance of KernelTask.
void AddKernelTask (KernelTask *task)
 Add kernel task to the scheduling strategy.
void AllocateAndAddNewTask (ITask *user_task)
 Allocate new instance of KernelTask and add it into the scheduling process.
void HrtAllocateAndAddNewTask (ITask *user_task, Timeout periodicity_tc, Timeout deadline_tc, Timeout start_delay_tc)
 Allocate new instance of KernelTask and add it into the HRT scheduling process.
void RequestAddTask (ITask *const user_task)
 Request to add new task.
KernelTask * FindTaskByUserTask (const ITask *user_task)
 Find kernel task by the bound ITask instance (Non-const version).
const KernelTask * FindTaskByUserTask (const ITask *user_task) const
 Find kernel task by the bound ITask instance (Const version).
KernelTask * FindTaskByStack (const Stack *stack)
 Find kernel task by the bound Stack instance.
KernelTask * FindTaskBySP (Word SP)
 Find kernel task for a Stack Pointer (SP).
void RemoveTask (KernelTask *task)
 Remove kernel task.
void OnStart (Stack *&active) override
 Called by platform driver immediately after a scheduler start (first tick).
void OnStop () override
 Called by the platform driver after a scheduler stop (all tasks have exited).
bool OnTick (Stack *&idle, Stack *&active, Timeout &ticks) override
 Process one scheduler tick. Called from the platform timer/tick ISR.
bool OnForceContextSwitch (TId id, Stack *&idle, Stack *&active)
 Called when task state change forces a context switch (Sleep, SleepUntil, Wait).
void OnTaskSwitch (Word caller_SP) override
 Called by Thread process (via IKernelService::SwitchToNext) to switch to a next task.
void OnTaskSleep (Word caller_SP, Timeout ticks) override
 Called by Thread process (via IKernelService::Sleep) for exclusion of the calling process from scheduling (sleeping).
bool OnTaskSleepUntil (Word caller_SP, Ticks timestamp) override
 Called by Thread process (via IKernelService::SleepUntil) for exclusion of the calling process from scheduling (sleeping).
void OnTaskExit (Stack *stack) override
 Called from the Thread process when task finished (its Run function exited by return).
EWaitResult OnTaskWait (Word caller_SP, ISyncObject *sync_obj, IMutex *mutex, Timeout timeout) override
 Called from the Thread process when task needs to wait.
TId OnGetTid (Word caller_SP) override
 Called from the Thread process when for getting task/thread id of the process.
void OnSuspend (bool suspended) override
 Called from the Thread process to suspend scheduling.
void OnInheritWeight (TId tid, Weight weight)
Weight OnSetWeight (TId tid, Weight weight)
Timeout OnSetTimeSlice (TId tid, Timeout ticks)
void UpdateTimeslice (const Timeout elapsed_ticks)
 Charge the running task and rotate it behind its same-priority peers when its slice expires.
void OnRestoreWeight (TId tid, ISyncObject *sobj)
Timeout UpdateTasks (const Timeout elapsed_ticks)
 Update tasks (sleep, requests).
void ProcessTaskPendingSleep (KernelTask *const task)
void ProcessTaskPendingYield (KernelTask *const task)
Timeout UpdateTaskState (const Timeout elapsed_ticks)
 Update task state: process removals, deliver sleep/wake notifications, advance sleep timers, and track HRT durations.
void UpdateSyncObjects (const Timeout elapsed_ticks)
 Update synchronization objects.
void UpdateTaskRequest ()
 Update pending task requests.
EFsmEvent FetchNextEvent (KernelTask *&next)
 Fetch next event for the FSM.
EFsmState GetNewFsmState (KernelTask *&next)
 Get new FSM state.
bool UpdateFsmState (Stack *&idle, Stack *&active)
 Update FSM state.
bool StateSwitch (KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
 Switches contexts.
bool StateWake (KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
 Wakes up after sleeping.
bool StateSleep (KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
 Enters into a sleeping mode.
bool StateExit (KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
 Exits from scheduling.
bool IsInitialized () const
 Check whether Initialize() has been called and completed successfully.
void ScheduleAddTask ()
 Signal the kernel to process a pending AddTask request on the next tick.

Static Protected Member Functions

static bool IsValidFsmState (EFsmState state)
 Check if FSM state is valid.
template<typename TaskPtr, typename Storage>
static TaskPtr FindTaskByUserTaskImpl (const ITask *user_task, Storage &task_storage)
static constexpr bool IsStaticMode ()
static constexpr bool IsDynamicMode ()
static constexpr bool IsHrtMode ()
static constexpr bool IsSyncMode ()
static constexpr bool IsTicklessMode ()
static constexpr bool IsTimesliceMode ()
static constexpr bool IsTelemetryMode ()

Protected Attributes

KernelService m_service
 Kernel service singleton exposed to running tasks via IKernelService::GetInstance().
TPlatform m_platform
 Platform driver (SysTick, PendSV, context switch implementation).
TStrategy m_strategy
 Task-switching strategy (determines which task runs next).
KernelTask * m_task_now
 Currently executing task, or nullptr before Start() or after all tasks exit.
TaskStorageType m_task_storage
 Static pool of TSize KernelTask slots (free slots have m_user == nullptr).
SleepTrapStack m_sleep_trap [1]
 Sleep trap (always present): executed when all tasks are sleeping.
ExitTrapStack m_exit_trap [STK_ALLOCATE_COUNT< TMode, KERNEL_DYNAMIC, 1U, 0U >::Value]
 Exit trap: zero-size in KERNEL_STATIC mode; one entry in KERNEL_DYNAMIC mode.
EFsmState m_fsm_state
 Current FSM state. Drives context-switch decision on every tick.
volatile uint8_t m_request
 Bitmask of pending ERequest flags from running tasks. Written by tasks, read/cleared by UpdateTaskRequest() in tick context.
volatile EKernelState m_kstate
 Current kernel state.
SyncObjectList m_sync_list [STK_ALLOCATE_COUNT< TMode, KERNEL_SYNC, 1U, 0U >::Value]
 List of active sync objects. Zero-size (no memory) if KERNEL_SYNC is not set.
const EFsmState m_fsm [FSM_STATE_MAX][FSM_EVENT_MAX]

Static Protected Attributes

static constexpr Timeout YIELD_TICKS = 1
 Ticks to yield.

Detailed Description

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
class stk::Kernel< TMode, TSize, TStrategy, TPlatform >

Concrete implementation of IKernel.

All configuration is expressed as template parameters. No virtual dispatch, no heap allocation - the entire kernel, tasks, and traps live in statically reserved storage.

Template Parameters
TModeBitmask of EKernelMode flags that configures kernel features:
  • KERNEL_STATIC - fixed task list, no add/remove after Start().
  • KERNEL_DYNAMIC - tasks may be added or removed at runtime.
  • KERNEL_HRT - Hard Real-Time mode (must combine with STATIC or DYNAMIC).
  • KERNEL_SYNC - enables synchronization primitives (Mutex, Event, etc.).
  • KERNEL_TICKLESS - enables tickless low-power operation. Requires STK_TICKLESS_IDLE=1 in stk_config.h. Incompatible with KERNEL_HRT (tickless suppresses the timer, which destroys the precise periodicity HRT depends on - enforced by the compile-time assertion TICKLESS_HRT_CONFLICT).
  • KERNEL_TIMESLICE - enables time-slicing: a running task is rotated behind its same-priority peers when its quantum (ITask::GetTimeSlice, IKernelService::SetTimeSlice) expires. Requires a strategy with TIMESLICE_API == 1 (e.g. SwitchStrategyPT32_TS), incompatible with KERNEL_HRT (TIMESLICE_HRT_CONFLICT).
  • KERNEL_TELEMETRY - enables introspection functions for diagnostics / telemetry (IKernel::GetTaskState). Without it these functions are compiled out and report failure. Combines with any other mode. KERNEL_STATIC and KERNEL_DYNAMIC are mutually exclusive.
    Template Parameters
    TSizeMaximum number of concurrent tasks. Must be > 0.
    TStrategyTask-switching strategy type (e.g. SwitchStrategyRoundRobin). Must inherit ITaskSwitchStrategy.
    TPlatformPlatform driver type (e.g. PlatformArmCortexM, or PlatformDefault). Must inherit IPlatform.
    Note
    At least 1 task is required: TSize must be > 0 (enforced by compile-time assertion).
    KERNEL_HRT is incompatible with weighted scheduling strategies (WEIGHT_API == true), also enforced by a compile-time assertion.
    KERNEL_TICKLESS is incompatible with KERNEL_HRT, also enforced by a compile-time assertion (TICKLESS_HRT_CONFLICT).
    Usage example:
    static MyTask1<256, ACCESS_PRIVILEGED> task1;
    static MyTask2<512, ACCESS_USER> task2;
    static MyTask3<512, ACCESS_USER> task3;
    kernel.Initialize();
    kernel.AddTask(&task1);
    kernel.AddTask(&task2);
    kernel.AddTask(&task3);
    kernel.Start();
    Concrete implementation of IKernel.
    Definition stk.h:100
    void AddTask(ITask *user_task) override
    Register task for a soft real-time (SRT) scheduling.
    Definition stk.h:1375
    void Start() override
    Start the scheduler. This call does not return until all tasks have exited (KERNEL_DYNAMIC mode) or i...
    Definition stk.h:1755
    void Initialize(uint32_t resolution_us=PERIODICITY_DEFAULT) override
    Initialize kernel.
    Definition stk.h:1338

Definition at line 95 of file stk.h.

Member Typedef Documentation

◆ ExitTrapStackMemory

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
typedef StackMemoryWrapper<STACK_SIZE_MIN> stk::Kernel< TMode, TSize, TStrategy, TPlatform >::ExitTrapStackMemory
protected

Stack memory wrapper type for the exit trap.

See also
ExitTrapStack, STACK_SIZE_MIN

Definition at line 112 of file stk.h.

◆ SleepTrapStackMemory

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
typedef StackMemoryWrapper< ( (32U) )> stk::Kernel< TMode, TSize, TStrategy, TPlatform >::SleepTrapStackMemory
protected

Stack memory wrapper type for the sleep trap.

See also
SleepTrapStack, STK_SLEEP_TRAP_STACK_SIZE

Definition at line 106 of file stk.h.

◆ SyncObjectList

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
typedef ISyncObject::ListHeadType stk::Kernel< TMode, TSize, TStrategy, TPlatform >::SyncObjectList
protected

Intrusive list of active ISyncObject instances registered with this kernel. Each sync object in this list receives a Tick() call every kernel tick for timeout tracking. Allocated only when KERNEL_SYNC is set (zero-size otherwise).

Definition at line 3238 of file stk.h.

◆ TaskStorageType

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
typedef KernelTask stk::Kernel< TMode, TSize, TStrategy, TPlatform >::TaskStorageType[TASKS_MAX]
protected

KernelTask array type used as a storage for the KernelTask instances.

Definition at line 3200 of file stk.h.

Member Enumeration Documentation

◆ EFsmEvent

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
enum stk::Kernel::EFsmEvent : int8_t
protected

Finite-state machine (FSM) event. Computed by FetchNextEvent() each tick based on strategy output and current kernel state.

Enumerator
FSM_EVENT_SWITCH 

Strategy returned a runnable task, perform a context switch.

FSM_EVENT_SLEEP 

No runnable tasks, enter sleep trap.

FSM_EVENT_WAKE 

A task became runnable while the kernel was sleeping, wake from sleep trap.

FSM_EVENT_EXIT 

No tasks remain (KERNEL_DYNAMIC), exit scheduling and return from Start().

FSM_EVENT_MAX 

Sentinel: number of valid events (used to size the FSM table).

Definition at line 1828 of file stk.h.

1829 {
1830 FSM_EVENT_SWITCH = 0,
1835 };
@ FSM_EVENT_EXIT
No tasks remain (KERNEL_DYNAMIC), exit scheduling and return from Start().
Definition stk.h:1833
@ FSM_EVENT_WAKE
A task became runnable while the kernel was sleeping, wake from sleep trap.
Definition stk.h:1832
@ FSM_EVENT_SLEEP
No runnable tasks, enter sleep trap.
Definition stk.h:1831
@ FSM_EVENT_SWITCH
Strategy returned a runnable task, perform a context switch.
Definition stk.h:1830
@ FSM_EVENT_MAX
Sentinel: number of valid events (used to size the FSM table).
Definition stk.h:1834

◆ EFsmState

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
enum stk::Kernel::EFsmState : int8_t
protected

Finite-state machine (FSM) state. Encodes what the kernel is currently doing between two consecutive tick events.

Enumerator
FSM_STATE_NONE 

Sentinel / uninitialized value. Set by the constructor, replaced by FSM_STATE_SWITCHING on the first tick.

FSM_STATE_SWITCHING 

Normal operation: switching between runnable tasks each tick.

FSM_STATE_SLEEPING 

All tasks are sleeping, the sleep trap is executing (CPU in low-power state).

FSM_STATE_WAKING 

At least one task woke up, transitioning from sleep trap back to a user task.

FSM_STATE_EXITING 

All tasks exited (KERNEL_DYNAMIC only), executing the exit trap to return from Start().

FSM_STATE_MAX 

Sentinel: number of valid states (used to size the FSM table), denotes uninitialized state.

Definition at line 1814 of file stk.h.

1815 {
1816 FSM_STATE_NONE = -1,
1822 };
@ FSM_STATE_EXITING
All tasks exited (KERNEL_DYNAMIC only), executing the exit trap to return from Start().
Definition stk.h:1820
@ FSM_STATE_SLEEPING
All tasks are sleeping, the sleep trap is executing (CPU in low-power state).
Definition stk.h:1818
@ FSM_STATE_SWITCHING
Normal operation: switching between runnable tasks each tick.
Definition stk.h:1817
@ FSM_STATE_NONE
Sentinel / uninitialized value. Set by the constructor, replaced by FSM_STATE_SWITCHING on the first ...
Definition stk.h:1816
@ FSM_STATE_MAX
Sentinel: number of valid states (used to size the FSM table), denotes uninitialized state.
Definition stk.h:1821
@ FSM_STATE_WAKING
At least one task woke up, transitioning from sleep trap back to a user task.
Definition stk.h:1819

◆ EKernelState

enum stk::IKernel::EKernelState : uint8_t
inherited

Kernel state.

Enumerator
KSTATE_INACTIVE 

Not ready, IKernel::Initialize() must be called.

KSTATE_READY 

Ready to start, IKernel::Start() must be called.

KSTATE_RUNNING 

Initialized and running, IKernel::Start() was called successfully.

KSTATE_SUSPENDED 

Scheduling is suspended with IKernelService::Suspend().

Definition at line 1529 of file stk_common.h.

1530 {
1531 KSTATE_INACTIVE = 0,
1532 KSTATE_READY,
1535 };
@ KSTATE_RUNNING
Initialized and running, IKernel::Start() was called successfully.
@ KSTATE_SUSPENDED
Scheduling is suspended with IKernelService::Suspend().
@ KSTATE_INACTIVE
Not ready, IKernel::Initialize() must be called.
@ KSTATE_READY
Ready to start, IKernel::Start() must be called.

◆ ERequest

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
enum stk::Kernel::ERequest : uint8_t
protected

Bitmask flags for pending inter-task requests that must be processed by the kernel on the next tick (in UpdateTaskRequest()).

Enumerator
REQ_NONE 

No pending requests.

REQ_ADD_TASK 

An AddTask() request is pending from a running task (KERNEL_DYNAMIC only).

Definition at line 118 of file stk.h.

119 {
120 REQ_NONE = 0,
121 REQ_ADD_TASK = (1 << 0)
122 };
@ REQ_ADD_TASK
An AddTask() request is pending from a running task (KERNEL_DYNAMIC only).
Definition stk.h:121
@ REQ_NONE
No pending requests.
Definition stk.h:120

Constructor & Destructor Documentation

◆ Kernel()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
stk::Kernel< TMode, TSize, TStrategy, TPlatform >::Kernel ( )
inlineexplicit

Construct the kernel with all storage zero-initialized, m_request cleared to REQ_NONE, and m_kstate set to KSTATE_INACTIVE (indicating uninitialized state; advanced to KSTATE_READY by Initialize()).

Note
In debug builds also verifies that TPlatform derives from IPlatform and TStrategy from ITaskSwitchStrategy.
If TMode includes KERNEL_TICKLESS, a compile-time assertion fires unless STK_TICKLESS_IDLE is defined to 1 in stk_config.h.

Definition at line 1305 of file stk.h.

1307 {
1308 #ifdef _DEBUG
1309 // TPlatform must inherit IPlatform
1312
1313 // TStrategy must inherit ITaskSwitchStrategy
1316 #endif
1317
1318 #if !STK_TICKLESS_IDLE
1320 "STK_TICKLESS_IDLE must be defined to 1 for KERNEL_TICKLESS");
1321 #endif
1322 }
#define STK_UNUSED(X)
Explicitly marks a variable as unused to suppress compiler warnings.
Definition stk_defs.h:715
#define STK_STATIC_ASSERT_DESC(X, DESC)
Compile-time assertion with a custom error description. Produces a compilation error if X is false.
Definition stk_defs.h:536
volatile uint8_t m_request
Bitmask of pending ERequest flags from running tasks. Written by tasks, read/cleared by UpdateTaskReq...
Definition stk.h:3248
TStrategy m_strategy
Task-switching strategy (determines which task runs next).
Definition stk.h:3242
SleepTrapStack m_sleep_trap[1]
Sleep trap (always present): executed when all tasks are sleeping.
Definition stk.h:3245
volatile EKernelState m_kstate
Current kernel state.
Definition stk.h:3249
ExitTrapStack m_exit_trap[STK_ALLOCATE_COUNT< TMode, KERNEL_DYNAMIC, 1U, 0U >::Value]
Exit trap: zero-size in KERNEL_STATIC mode; one entry in KERNEL_DYNAMIC mode.
Definition stk.h:3246
TaskStorageType m_task_storage
Static pool of TSize KernelTask slots (free slots have m_user == nullptr).
Definition stk.h:3244
KernelTask * m_task_now
Currently executing task, or nullptr before Start() or after all tasks exit.
Definition stk.h:3243
TPlatform m_platform
Platform driver (SysTick, PendSV, context switch implementation).
Definition stk.h:3241
EFsmState m_fsm_state
Current FSM state. Drives context-switch decision on every tick.
Definition stk.h:3247

◆ ~Kernel()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
stk::Kernel< TMode, TSize, TStrategy, TPlatform >::~Kernel ( )
default

Destructor.

Note
MISRA deviation: [STK-DEV-005] Rule 10-3-2.

Member Function Documentation

◆ AddKernelTask()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::AddKernelTask ( KernelTask * task)
inlineprotected

Add kernel task to the scheduling strategy.

Parameters
[in]taskPointer to the kernel task.

Definition at line 1928 of file stk.h.

1929 {
1930 #if STK_SEGGER_SYSVIEW
1931 // start tracing new task
1932 SEGGER_SYSVIEW_OnTaskCreate(task->GetUserStackPtr()->tid);
1933 if (IsStarted())
1934 {
1936 }
1937 #endif
1938
1939 m_strategy.AddTask(task);
1940 }
bool IsStarted() const
Check whether scheduler is currently running.
Definition stk.h:1782

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::AllocateAndAddNewTask(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::HrtAllocateAndAddNewTask().

Here is the caller graph for this function:

◆ AddTask() [1/2]

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::AddTask ( ITask * user_task)
inlineoverridevirtual

Register task for a soft real-time (SRT) scheduling.

Parameters
[in]user_taskUser task to add. Must not already be registered. Must not be nullptr.
Note
Before Start(): allocates a free KernelTask slot and adds it to the strategy immediately.
After Start() (KERNEL_DYNAMIC only): serialises the request via RequestAddTask() - the calling task yields and the kernel processes the request on the next tick.
Warning
Asserts if called in KERNEL_HRT mode (use the HRT overload instead), if called after Start() without KERNEL_DYNAMIC, or if TASKS_MAX is exceeded.

Implements stk::IKernel.

Definition at line 1375 of file stk.h.

1376 {
1378 {
1379 STK_ASSERT(user_task != nullptr);
1381
1382 // when started the operation must be serialized by switching out from processing until
1383 // kernel processes this request
1384 if (IsStarted())
1385 {
1387 {
1389 }
1390 else
1391 {
1392 STK_ASSERT(false);
1393 }
1394 }
1395 else
1396 {
1398 }
1399 }
1400 else
1401 {
1402 STK_ASSERT(false);
1403 }
1404 }
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:516
#define __stk_constexpr_cpp17
constexpr definition for C++17 and above.
Definition stk_defs.h:489
void RequestAddTask(ITask *const user_task)
Request to add new task.
Definition stk.h:1974
static constexpr bool IsHrtMode()
Definition stk.h:3158
void AllocateAndAddNewTask(ITask *user_task)
Allocate new instance of KernelTask and add it into the scheduling process.
Definition stk.h:1945
bool IsInitialized() const
Check whether Initialize() has been called and completed successfully.
Definition stk.h:3118
static constexpr bool IsDynamicMode()
Definition stk.h:3157

◆ AddTask() [2/2]

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::AddTask ( ITask * user_task,
Timeout periodicity_tc,
Timeout deadline_tc,
Timeout start_delay_tc )
inlineoverridevirtual

Register a task for hard real-time (HRT) scheduling.

Parameters
[in]user_taskUser task to add. Must not already be registered. Must not be nullptr.
[in]periodicity_tcActivation period in ticks. Must be > 0 and < INT32_MAX.
[in]deadline_tcMaximum allowed active duration in ticks. Must be > 0 and < INT32_MAX.
[in]start_delay_tcInitial sleep delay in ticks before the first activation. 0 means activate immediately.
Note
Must be called before Start(). Dynamic (post-Start) HRT task addition is not supported.
Warning
Asserts if called outside KERNEL_HRT mode (use the SRT overload instead) or after Start().

Implements stk::IKernel.

Definition at line 1414 of file stk.h.

1416 {
1418 {
1419 STK_ASSERT(user_task != nullptr);
1422
1424 }
1425 else
1426 {
1427 STK_ASSERT(false);
1428 }
1429 }
void HrtAllocateAndAddNewTask(ITask *user_task, Timeout periodicity_tc, Timeout deadline_tc, Timeout start_delay_tc)
Allocate new instance of KernelTask and add it into the HRT scheduling process.
Definition stk.h:1960

◆ AllocateAndAddNewTask()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::AllocateAndAddNewTask ( ITask * user_task)
inlineprotected

Allocate new instance of KernelTask and add it into the scheduling process.

Parameters
[in]user_taskUser task for which kernel task object is allocated.

Definition at line 1945 of file stk.h.

1946 {
1948 STK_ASSERT(task != nullptr);
1949
1951 }
KernelTask * AllocateNewTask(ITask *user_task)
Allocate new instance of KernelTask.
Definition stk.h:1888
void AddKernelTask(KernelTask *task)
Add kernel task to the scheduling strategy.
Definition stk.h:1928
Internal per-slot kernel descriptor that wraps a user ITask instance.
Definition stk.h:136

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::AddTask(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTaskRequest().

Here is the caller graph for this function:

◆ AllocateNewTask()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
KernelTask * stk::Kernel< TMode, TSize, TStrategy, TPlatform >::AllocateNewTask ( ITask * user_task)
inlineprotected

Allocate new instance of KernelTask.

Parameters
[in]user_taskUser task for which kernel task object is allocated.
Returns
Kernel task.

Definition at line 1888 of file stk.h.

1889 {
1890 // look for a free kernel task
1891 KernelTask *new_task = nullptr;
1892 for (size_t i = 0U; i < TASKS_MAX; ++i)
1893 {
1894 KernelTask *const task = &m_task_storage[i];
1895 if (task->IsBusy())
1896 {
1897 // avoid task collision
1898 STK_ASSERT(task->m_user != user_task);
1899
1900 // avoid stack collision
1901 STK_ASSERT(task->m_user->GetStack() != user_task->GetStack());
1902 }
1903 else
1904 if (new_task == nullptr)
1905 {
1906 new_task = task;
1907 #if defined(NDEBUG) && !defined(_STK_ASSERT_REDIRECT)
1908 break; // break if assertions are inactive and do not try to validate collision with existing tasks
1909 #endif
1910 }
1911 else
1912 {
1913 // noop, continue to the next slot
1914 }
1915 }
1916
1917 // if nullptr - exceeded max supported kernel task count, application design failure
1918 STK_ASSERT(new_task != nullptr);
1919
1920 new_task->Bind(&m_platform, user_task);
1921
1922 return new_task;
1923 }
static constexpr size_t TASKS_MAX
Maximum number of concurrently registered tasks. Fixed at compile time. Exceeding this limit in AddTa...
Definition stk.h:1295

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::AllocateAndAddNewTask(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::HrtAllocateAndAddNewTask().

Here is the caller graph for this function:

◆ CancelTaskWait()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::CancelTaskWait ( ITask * user_task)
inlineoverridevirtual

Cancel task's in-progress wait on a synchronization object.

Parameters
[in]user_taskPointer to the user task whose wait should be cancelled.

Implements stk::IKernel.

Definition at line 1579 of file stk.h.

1580 {
1581 STK_ASSERT(user_task != nullptr);
1582
1584 if (task != nullptr)
1585 {
1586 // critical section: avoid race with OnTick
1587
1589
1590 bool canceled_wait = false;
1591
1593 {
1594 // a task blocked in OnTaskWait() also counts as sleeping (ScheduleSleep(WAIT_INFINITE)), but
1595 // its WaitObject is still linked into the sync object's wait list: waking only the task
1596 // would leave a stale entry behind (later signaled or ticked as a timeout while the task is
1597 // not waiting), so cancel the wait itself, this unlinks it, records WAIT_RESULT_CANCELED
1598 // and wakes the task
1599 canceled_wait = task->m_wait_obj[0].CancelIfWaiting();
1600 }
1601
1602 if (!canceled_wait && task->IsSleeping())
1603 {
1604 task->Wake();
1605 }
1606 }
1607 }
static constexpr bool IsSyncMode()
Definition stk.h:3159
KernelTask * FindTaskByUserTask(const ITask *user_task)
Find kernel task by the bound ITask instance (Non-const version).
Definition stk.h:2028

◆ EnumerateKernelTasks()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
size_t stk::Kernel< TMode, TSize, TStrategy, TPlatform >::EnumerateKernelTasks ( ArrayView< IKernelTask * > tasks)
inlineoverridevirtual

Enumerate kernel tasks.

Parameters
[in]tasksReference to the ArrayView of IKernelTask pointers.
Returns
Number of tasks in the array.

Implements stk::IKernel.

Definition at line 1699 of file stk.h.

1700 {
1701 size_t count = 0U;
1702 const size_t limit = Min(tasks.GetSize(), TASKS_MAX);
1703
1704 // critical section: avoid race with OnTick
1705 {
1707
1708 for (size_t i = 0U; i < limit; ++i)
1709 {
1711 if (task.IsBusy())
1712 {
1713 tasks[count++] = &task;
1714 }
1715 }
1716 }
1717
1718 return count;
1719 }
static constexpr T Min(T a, T b) noexcept
Compile-time minimum of two values.
Definition stk_defs.h:753

◆ EnumerateTasks()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
size_t stk::Kernel< TMode, TSize, TStrategy, TPlatform >::EnumerateTasks ( ArrayView< ITask * > user_tasks)
inlineoverridevirtual

Enumerate user tasks.

Parameters
[in]user_tasksReference to the ArrayView of ITask pointers.
Returns
Number of tasks in the array.

Implements stk::IKernel.

Definition at line 1725 of file stk.h.

1726 {
1727 size_t count = 0U;
1728 const size_t limit = Min(user_tasks.GetSize(), TASKS_MAX);
1729
1730 // critical section: avoid race with OnTick
1731 {
1733
1734 for (size_t i = 0U; i < limit; ++i)
1735 {
1737 if (task.IsBusy())
1738 {
1739 user_tasks[count++] = task.GetUserTask();
1740 }
1741 }
1742 }
1743
1744 return count;
1745 }

◆ EnumerateTasksT()

template<size_t TMaxCount, typename TCallback>
size_t stk::IKernel::EnumerateTasksT ( TCallback && callback)
inlineinherited

Enumerate tasks, invoking a callback for each active task.

Template Parameters
TMaxCountMaximum number of tasks to enumerate. Should match or exceed the kernel's task capacity. Determines the size of the internal stack-allocated buffer (TMaxCount * sizeof(ITask*) bytes on the stack).
TCallbackCallable type, deduced automatically. Must satisfy: bool(ITask*)
Parameters
[in]callbackCallable invoked for each active task. Return true to continue, false to stop early.
Returns
Number of tasks visited (up to TMaxCount).
Warning
ISR-safe.

Example:

kernel.EnumerateTasks<_STK_KERNEL_TASKS_COUNT>([](ITask *t) {
Log(t->GetTraceName());
return true; // continue
});
Interface for a user task.
Definition stk_common.h:824

Definition at line 1674 of file stk_common.h.

1675 {
1676 STK_STATIC_ASSERT(TMaxCount > 0U);
1677
1678 ITask *tasks[TMaxCount] = {};
1679 size_t count = EnumerateTasks(ArrayView<ITask *>(tasks, TMaxCount));
1680 size_t i = 0U;
1681 bool fetch_next = true;
1682
1683 while ((i < count) && fetch_next)
1684 {
1685 fetch_next = callback(tasks[i]);
1686 ++i;
1687 }
1688
1689 return i;
1690 }
#define STK_STATIC_ASSERT(X)
Compile-time assertion. Produces a compilation error if X is false.
Definition stk_defs.h:553
virtual size_t EnumerateTasks(ArrayView< ITask * > user_tasks)=0
Enumerate user tasks.

References EnumerateTasks(), and STK_STATIC_ASSERT.

Here is the call graph for this function:

◆ FetchNextEvent()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
EFsmEvent stk::Kernel< TMode, TSize, TStrategy, TPlatform >::FetchNextEvent ( KernelTask *& next)
inlineprotected

Fetch next event for the FSM.

Parameters
[out]nextNext kernel task to which Kernel can switch.
Returns
FSM event.

Definition at line 2884 of file stk.h.

2885 {
2887
2888 // try getting next task for scheduling
2890
2891 // sleep-aware strategy returns nullptr if no active tasks available
2892 if (next != nullptr)
2893 {
2894 // strategy must provide active-only task
2895 STK_ASSERT(!next->IsSleeping());
2896
2897 // if was sleeping, process wake event first
2899 }
2900 // start sleeping
2901 else
2902 {
2904 {
2905 // if nullptr is returned then either strategy has all tasks sleeping or none left,
2906 // if KERNEL_DYNAMIC mode and no tasks left then exit from scheduling
2907 if (m_strategy.GetSize() == 0U)
2908 {
2909 next = nullptr;
2911 }
2912 }
2913 }
2914
2915 return type;
2916 }
EFsmEvent
Finite-state machine (FSM) event. Computed by FetchNextEvent() each tick based on strategy output and...
Definition stk.h:1829
static __stk_forceinline TTargetType * ListEntryToParent(TSourceType *const lentry)
Safely casts an intrusive list entry to its concrete parent container object type.

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::GetNewFsmState().

Here is the caller graph for this function:

◆ FindTaskBySP()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
KernelTask * stk::Kernel< TMode, TSize, TStrategy, TPlatform >::FindTaskBySP ( Word SP)
inlineprotected

Find kernel task for a Stack Pointer (SP).

Parameters
[in]SPStack pointer.
Returns
Kernel task.

Definition at line 2067 of file stk.h.

2068 {
2069 STK_ASSERT(m_task_now != nullptr);
2070
2071 KernelTask *found_task = nullptr;
2072
2073 if (m_task_now->IsMemoryOfSP(SP))
2074 {
2076 }
2077 else
2078 {
2079 for (size_t i = 0U; i < TASKS_MAX; ++i)
2080 {
2081 KernelTask *const task = &m_task_storage[i];
2082
2083 // skip finished tasks (applicable only for KERNEL_DYNAMIC mode)
2085 {
2086 if (!task->IsBusy())
2087 {
2088 continue;
2089 }
2090 }
2091
2092 if (task->IsMemoryOfSP(SP))
2093 {
2094 found_task = task;
2095 break;
2096 }
2097 }
2098 }
2099
2100 return found_task;
2101 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnGetTid(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSleep(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSleepUntil(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSwitch(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskWait(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::RequestAddTask().

Here is the caller graph for this function:

◆ FindTaskByStack()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
KernelTask * stk::Kernel< TMode, TSize, TStrategy, TPlatform >::FindTaskByStack ( const Stack * stack)
inlineprotected

Find kernel task by the bound Stack instance.

Parameters
[in]stackStack.
Returns
Kernel task.

Definition at line 2046 of file stk.h.

2047 {
2048 KernelTask *found_task = nullptr;
2049
2050 for (size_t i = 0U; i < TASKS_MAX; ++i)
2051 {
2052 KernelTask *const task = &m_task_storage[i];
2053 if (task->GetUserStackPtr() == stack)
2054 {
2055 found_task = task;
2056 break;
2057 }
2058 }
2059
2060 return found_task;
2061 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskExit().

Here is the caller graph for this function:

◆ FindTaskByUserTask() [1/2]

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
KernelTask * stk::Kernel< TMode, TSize, TStrategy, TPlatform >::FindTaskByUserTask ( const ITask * user_task)
inlineprotected

Find kernel task by the bound ITask instance (Non-const version).

Parameters
[in]user_taskUser task.
Returns
Kernel task (mutable).

Definition at line 2028 of file stk.h.

2029 {
2031 }
static TaskPtr FindTaskByUserTaskImpl(const ITask *user_task, Storage &task_storage)
Definition stk.h:2006

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::CancelTaskWait(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::GetTaskState(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnInheritWeight(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnRestoreWeight(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnSetTimeSlice(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnSetWeight(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::RemoveTask(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::ResumeTask(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::ScheduleTaskRemoval(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::SuspendTask().

Here is the caller graph for this function:

◆ FindTaskByUserTask() [2/2]

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
const KernelTask * stk::Kernel< TMode, TSize, TStrategy, TPlatform >::FindTaskByUserTask ( const ITask * user_task) const
inlineprotected

Find kernel task by the bound ITask instance (Const version).

Parameters
[in]user_taskUser task.
Returns
Kernel task (const).

Definition at line 2037 of file stk.h.

◆ FindTaskByUserTaskImpl()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
template<typename TaskPtr, typename Storage>
TaskPtr stk::Kernel< TMode, TSize, TStrategy, TPlatform >::FindTaskByUserTaskImpl ( const ITask * user_task,
Storage & task_storage )
inlinestaticprotected

Definition at line 2006 of file stk.h.

2007 {
2008 TaskPtr found_task = nullptr;
2009
2010 for (size_t i = 0U; i < TASKS_MAX; ++i)
2011 {
2012 TaskPtr const task = &task_storage[i];
2013
2014 if (task->GetUserTask() == user_task)
2015 {
2016 found_task = task;
2017 break;
2018 }
2019 }
2020
2021 return found_task;
2022 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::FindTaskByUserTask(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::FindTaskByUserTask().

Here is the caller graph for this function:

◆ GetNewFsmState()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
EFsmState stk::Kernel< TMode, TSize, TStrategy, TPlatform >::GetNewFsmState ( KernelTask *& next)
inlineprotected

Get new FSM state.

Parameters
[out]nextNext kernel task to which Kernel can switch.
Returns
FSM state.

Definition at line 2925 of file stk.h.

2926 {
2929 }
static bool IsValidFsmState(EFsmState state)
Check if FSM state is valid.
Definition stk.h:1847
const EFsmState m_fsm[FSM_STATE_MAX][FSM_EVENT_MAX]
Definition stk.h:3252
EFsmEvent FetchNextEvent(KernelTask *&next)
Fetch next event for the FSM.
Definition stk.h:2884

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnStart(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateFsmState().

Here is the caller graph for this function:

◆ GetPlatform()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
IPlatform * stk::Kernel< TMode, TSize, TStrategy, TPlatform >::GetPlatform ( )
inlineoverridevirtual

Get platform driver instance owned by this kernel.

Returns
Pointer to the internal TPlatform cast to IPlatform*.

Implements stk::IKernel.

Definition at line 1790 of file stk.h.

1790{ return &m_platform; }

◆ GetState()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
EKernelState stk::Kernel< TMode, TSize, TStrategy, TPlatform >::GetState ( ) const
inlineoverridevirtual

Get kernel state.

Implements stk::IKernel.

Definition at line 1799 of file stk.h.

1799{ return m_kstate; }

◆ GetSwitchStrategy()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
ITaskSwitchStrategy * stk::Kernel< TMode, TSize, TStrategy, TPlatform >::GetSwitchStrategy ( )
inlineoverridevirtual

Get task-switching strategy instance owned by this kernel.

Returns
Pointer to the internal TStrategy cast to ITaskSwitchStrategy*.

Implements stk::IKernel.

Definition at line 1795 of file stk.h.

1795{ return &m_strategy; }

◆ GetTaskState()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::GetTaskState ( ITask * user_task,
TaskStateInfo & info ) const
inlineoverridevirtual

Get a snapshot of the kernel-side state of a task.

Parameters
[in]user_taskPointer to the user task to query. Must not be nullptr.
[out]infoReceives the snapshot. Written only if the function returns true.
Returns
true on success, false if user_task is nullptr or the kernel is built without KERNEL_TELEMETRY (info is left unchanged). See IKernel::GetTaskState().
Note
The order of the checks matters: SuspendTask() and OnTaskWait() both put the task to an infinite sleep (ScheduleSleep), so IsSleeping() is also true for suspended and blocked tasks.
KERNEL_TELEMETRY mode only.

Implements stk::IKernel.

Definition at line 1618 of file stk.h.

1619 {
1620 bool result;
1621
1622 if (IsTelemetryMode())
1623 {
1624 if (user_task != nullptr)
1625 {
1626 info.state = TASK_STATE_REMOVED;
1627 info.wait_obj = nullptr;
1628 info.remaining = WAIT_INFINITE;
1629
1630 // critical section: consistent view against OnTick
1632
1634 if (task != nullptr)
1635 {
1636 bool resolved = false;
1637
1638 if ((task->m_state & KernelTask::STATE_REMOVE_PENDING) != 0U)
1639 {
1640 info.state = TASK_STATE_EXITING;
1641 resolved = true;
1642 }
1643 else if ((task->m_state & KernelTask::STATE_SUSPENDED) != 0U)
1644 {
1645 info.state = TASK_STATE_SUSPENDED;
1646 resolved = true;
1647 }
1648 else
1649 {
1651 {
1652 const typename KernelTask::WaitObject &wait_obj = task->m_wait_obj[0];
1653
1654 if (wait_obj.IsWaiting())
1655 {
1656 info.state = TASK_STATE_WAITING;
1657 info.wait_obj = wait_obj.m_sync_obj;
1658 info.remaining = wait_obj.m_time_wait;
1659 resolved = true;
1660 }
1661 }
1662 }
1663
1664 if (!resolved)
1665 {
1666 const Timeout time_sleep = task->m_time_sleep;
1667
1668 if (time_sleep < 0)
1669 {
1670 info.state = TASK_STATE_SLEEPING;
1671 info.remaining = -time_sleep; // -(-WAIT_INFINITE) == WAIT_INFINITE for an infinite sleep
1672 }
1673 else
1674 {
1675 info.state = TASK_STATE_READY;
1676 }
1677 }
1678 }
1679
1680 result = true;
1681 }
1682 else
1683 {
1684 result = false;
1685 }
1686 }
1687 else
1688 {
1689 result = false;
1690 }
1691
1692 return result;
1693 }
static constexpr bool IsTelemetryMode()
Definition stk.h:3162
@ STATE_REMOVE_PENDING
Task returned from its Run function; slot will be freed on the next tick (KERNEL_DYNAMIC only).
Definition stk.h:146
@ STATE_SUSPENDED
Task is suspended by SuspendTask.
Definition stk.h:149
Concrete implementation of IWaitObject, embedded in each KernelTask slot.
Definition stk.h:525

◆ HrtAllocateAndAddNewTask()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::HrtAllocateAndAddNewTask ( ITask * user_task,
Timeout periodicity_tc,
Timeout deadline_tc,
Timeout start_delay_tc )
inlineprotected

Allocate new instance of KernelTask and add it into the HRT scheduling process.

Note
Related to stk::KERNEL_HRT mode only.
Parameters
[in]user_taskUser task for which kernel task object is allocated.
[in]periodicity_tcPeriodicity time at which task is scheduled (ticks).
[in]deadline_tcDeadline time within which a task must complete its work (ticks).
[in]start_delay_tcInitial start delay for the task (ticks).

Definition at line 1960 of file stk.h.

1961 {
1963 STK_ASSERT(task != nullptr);
1964
1966
1968 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::AddTask().

Here is the caller graph for this function:

◆ Initialize()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::Initialize ( uint32_t resolution_us = PERIODICITY_DEFAULT)
inlineoverridevirtual

Initialize kernel.

Parameters
[in]resolution_usResolution of the system tick (SysTick) timer in microseconds. Defaults to PERIODICITY_DEFAULT (1000 µs = 1 ms).
Note
Must be called before AddTask() and Start().
If running on an STM32 device with HAL driver or on QEMU, do not change the default resolution (PERIODICITY_DEFAULT). STM32's HAL expects 1 millisecond resolution and QEMU does not have enough resolution on Windows to operate correctly at sub-millisecond resolution.
Kernel must be in KSTATE_INACTIVE state.

Implements stk::IKernel.

Definition at line 1338 of file stk.h.

1339 {
1343
1344 // reinitialize key state variables
1345 m_task_now = nullptr;
1348
1349 // exit trap is required only for KERNEL_DYNAMIC mode
1352 {
1353 exit_trap = &m_exit_trap[0].stack;
1354 }
1355 else
1356 {
1357 exit_trap = nullptr;
1358 }
1359
1360 m_service.Initialize(this);
1361 m_platform.Initialize(this, &m_service, resolution_us, exit_trap);
1362
1363 // now ready to Start()
1365 }
KernelService m_service
Kernel service singleton exposed to running tasks via IKernelService::GetInstance().
Definition stk.h:3240

◆ InitTraps()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::InitTraps ( )
inlineprotected

Initialize stack of the traps.

Definition at line 1854 of file stk.h.

1855 {
1856 // init stack for a Sleep trap
1857 {
1859
1861 sleep.stack.access_mode = ACCESS_PRIVILEGED;
1862 #if STK_STACK_NEEDS_TASK_ID
1863 sleep.stack.tid = SYS_TASK_ID_SLEEP;
1864 #endif
1865
1866 STK_UNUSED(m_platform.InitStack(STACK_SLEEP_TRAP, &sleep.stack, &wrapper, nullptr));
1867 }
1868
1869 // init stack for an Exit trap
1871 {
1873
1875 exit.stack.access_mode = ACCESS_PRIVILEGED;
1876 #if STK_STACK_NEEDS_TASK_ID
1877 exit.stack.tid = SYS_TASK_ID_EXIT;
1878 #endif
1879
1880 STK_UNUSED(m_platform.InitStack(STACK_EXIT_TRAP, &exit.stack, &wrapper, nullptr));
1881 }
1882 }
StackMemoryWrapper< STACK_SIZE_MIN > ExitTrapStackMemory
Stack memory wrapper type for the exit trap.
Definition stk.h:112
StackMemoryWrapper<((32U))> SleepTrapStackMemory
Stack memory wrapper type for the sleep trap.
Definition stk.h:106
Storage bundle for the sleep trap: a Stack descriptor paired with its backing memory.
Definition stk.h:3210
Storage bundle for the exit trap: a Stack descriptor paired with its backing memory.
Definition stk.h:3226

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::Start().

Here is the caller graph for this function:

◆ IsDynamicMode()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
constexpr bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsDynamicMode ( )
inlinestaticconstexprprotected

Definition at line 3157 of file stk.h.

3157{ return ((TMode & KERNEL_DYNAMIC) != 0U); }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::AddTask(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::FetchNextEvent(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::FindTaskBySP(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::Initialize(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::InitTraps(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnStop(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskExit(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::RemoveTask(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::ScheduleTaskRemoval(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::StateExit(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTaskRequest(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTaskState().

Here is the caller graph for this function:

◆ IsHrtMode()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
constexpr bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsHrtMode ( )
inlinestaticconstexprprotected

Definition at line 3158 of file stk.h.

3158{ return ((TMode & KERNEL_HRT) != 0U); }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::AddTask(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::AddTask(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelTask::GetHrtDeadline(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelTask::GetHrtPeriodicity(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelTask::GetHrtRelativeDeadline(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnStart(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSleep(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSwitch(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelTask::ScheduleRemoval(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelService::Sleep(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelService::SleepCancel(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelService::SleepUntil(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::StateSleep(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::StateSwitch(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::StateWake(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelTask::Unbind(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTaskRequest(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTaskState().

Here is the caller graph for this function:

◆ IsInitialized()

◆ IsStarted()

◆ IsStaticMode()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
constexpr bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsStaticMode ( )
inlinestaticconstexprprotected

Definition at line 3156 of file stk.h.

3156{ return ((TMode & KERNEL_STATIC) != 0U); }

◆ IsSyncMode()

◆ IsTelemetryMode()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
constexpr bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsTelemetryMode ( )
inlinestaticconstexprprotected

Definition at line 3162 of file stk.h.

3162{ return ((TMode & KERNEL_TELEMETRY) != 0U); }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::GetTaskState().

Here is the caller graph for this function:

◆ IsTicklessMode()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
constexpr bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsTicklessMode ( )
inlinestaticconstexprprotected

◆ IsTimesliceMode()

◆ IsValidFsmState()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsValidFsmState ( EFsmState state)
inlinestaticprotected

Check if FSM state is valid.

Definition at line 1847 of file stk.h.

1848 {
1849 return ((state > FSM_STATE_NONE) && (state < FSM_STATE_MAX));
1850 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::GetNewFsmState().

Here is the caller graph for this function:

◆ OnForceContextSwitch()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnForceContextSwitch ( TId id,
Stack *& idle,
Stack *& active )
inlineprotectedvirtual

Called when task state change forces a context switch (Sleep, SleepUntil, Wait).

Parameters
[in]idTask id causing this forced context switch.
[out]idleStack of the task which must enter Idle state.
[out]activeStack of the task which must enter Active state (to which context will switch).
Returns
True if context switch is required, False otherwise.

Implements stk::IPlatform::IEventHandler.

Definition at line 2260 of file stk.h.

2261 {
2262 bool switch_context = false;
2263 KernelTask *const task = m_task_now;
2264
2265 STK_ASSERT(task != nullptr);
2266
2267 // note: called from inside ISR, therefore protection by critical section is not needed
2268
2269 if (task->GetTid() == id)
2270 {
2271 // current task is busy-waiting to be de-scheduled
2272 if (task->IsSleeping())
2273 {
2274 if ((task->m_state & KernelTask::STATE_SLEEP_PENDING) != 0U)
2275 {
2277
2279 }
2280 }
2281 else
2282 {
2284 {
2285 // current task yielded and stays runnable: let the strategy pick the next task
2286 if ((task->m_state & KernelTask::STATE_YIELD_PENDING) != 0U)
2287 {
2289
2291 }
2292 }
2293 }
2294 }
2295
2296 return switch_context;
2297 }
bool UpdateFsmState(Stack *&idle, Stack *&active)
Update FSM state.
Definition stk.h:2936
void ProcessTaskPendingSleep(KernelTask *const task)
Definition stk.h:2668
void ProcessTaskPendingYield(KernelTask *const task)
Definition stk.h:2679
@ STATE_YIELD_PENDING
Task called Yield() and the strategy handled it via OnTaskYield() (task stays runnable); cleared by t...
Definition stk.h:150
@ STATE_SLEEP_PENDING
Task called Sleep/SleepUntil/Yield; strategy's OnTaskSleep() will be invoked on the next tick (sleep-...
Definition stk.h:147

◆ OnGetTid()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
TId stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnGetTid ( Word caller_SP)
inlineoverrideprotectedvirtual

Called from the Thread process when for getting task/thread id of the process.

Parameters
[in]caller_SPValue of Stack Pointer (SP) register (for locating the calling process inside the kernel).
Returns
Task/thread id of the process (returns always valid TId belonging to a task).

Implements stk::IPlatform::IEventHandler.

Definition at line 2505 of file stk.h.

2506 {
2508 STK_ASSERT(task != nullptr);
2509
2510 return task->GetTid();
2511 }
KernelTask * FindTaskBySP(Word SP)
Find kernel task for a Stack Pointer (SP).
Definition stk.h:2067

◆ OnInheritWeight()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnInheritWeight ( TId tid,
Weight weight )
inlineprotected

Definition at line 2538 of file stk.h.

2539 {
2542
2543 if (weight != NO_WEIGHT)
2544 {
2546 STK_ASSERT(task != nullptr);
2547
2548 const Weight prev_weight = task->GetWeight();
2549
2550 if (prev_weight < weight)
2551 {
2552 task->SetCurrentWeight(weight);
2553 m_strategy.OnTaskWeightChange(task, prev_weight);
2554 }
2555 }
2556 }
static constexpr ITask * GetUserTaskFromTid(TId task_id) noexcept
Get task instance from its identifier.
Definition stk_arch.h:725

◆ OnRestoreWeight()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnRestoreWeight ( TId tid,
ISyncObject * sobj )
inlineprotected

Definition at line 2634 of file stk.h.

2635 {
2638
2640 STK_ASSERT(task != nullptr);
2641
2642 const Weight prev_weight = task->GetWeight();
2643
2644 // restore to original or boost from wait objects
2645 task->SetCurrentWeight(sobj != nullptr ? sobj->FindWeightHigherThan(task->GetWeight()) : NO_WEIGHT);
2646
2647 m_strategy.OnTaskWeightChange(task, prev_weight);
2648 }

◆ OnSetTimeSlice()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
Timeout stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnSetTimeSlice ( TId tid,
Timeout ticks )
inlineprotected

Definition at line 2585 of file stk.h.

2586 {
2589
2591 STK_ASSERT(task != nullptr);
2592
2593 typename KernelTask::TsInfo &ts = task->m_ts[0];
2594
2595 const Timeout prev = ts.quantum;
2596
2597 ts.quantum = ticks;
2598 ts.Reload();
2599
2600 return prev;
2601 }
Per-task time-slice (KERNEL_TIMESLICE) metadata.
Definition stk.h:495

◆ OnSetWeight()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
Weight stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnSetWeight ( TId tid,
Weight weight )
inlineprotected

Definition at line 2558 of file stk.h.

2559 {
2563
2565 STK_ASSERT(task != nullptr);
2566
2567 const Weight prev_weight = task->GetWeight(); // effective weight (base or inherited)
2568 const Weight prev_base = task->GetBaseWeight();
2569
2570 task->SetBaseWeight(weight);
2571
2572 // an inherited weight that does not exceed the new base weight is no longer a boost
2573 if ((task->GetCurrentWeight() != NO_WEIGHT) && (task->GetCurrentWeight() <= weight))
2574 {
2575 task->SetCurrentWeight(NO_WEIGHT);
2576 }
2577
2578 // always notify: the strategy may depend on parts of the weight that do not change
2579 // the effective weight while a boost is active (e.g. preemption-threshold)
2580 m_strategy.OnTaskWeightChange(task, prev_weight);
2581
2582 return prev_base;
2583 }

◆ OnStart()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnStart ( Stack *& active)
inlineoverrideprotectedvirtual

Called by platform driver immediately after a scheduler start (first tick).

Parameters
[out]activeSet to the stack of the first task to run, or to the sleep-trap stack if all tasks are initially sleeping.
Note
Delivers initial OnTaskSleep notifications to sleep-aware strategies for any tasks that were added in a sleeping state before Start() was called.
Selects the first runnable task via GetNewFsmState() and transitions the kernel to KSTATE_RUNNING.
If STK_SEGGER_SYSVIEW is enabled, emits a task-start trace event for the first task.
Warning
At least one task must have been added via AddTask(); asserts if the strategy pool is empty.

Implements stk::IPlatform::IEventHandler.

Definition at line 2132 of file stk.h.

2133 {
2134 STK_ASSERT(m_strategy.GetSize() != 0);
2135
2136 // iterate tasks and generate OnTaskSleep for a strategy for all initially sleeping tasks
2137 for (size_t i = 0U; i < TASKS_MAX; ++i)
2138 {
2139 KernelTask *const task = &m_task_storage[i];
2140
2141 if ((task->m_state & KernelTask::STATE_SLEEP_PENDING) != 0U)
2142 {
2143 STK_ASSERT(task->IsSleeping());
2144
2146
2147 // notify strategy that task is sleeping
2149 {
2150 m_strategy.OnTaskSleep(task);
2151 }
2152 }
2153 }
2154
2155 // get initial state and first task
2156 {
2158
2159 KernelTask *next = nullptr;
2161
2162 // expecting only SLEEPING or SWITCHING states
2164
2166 {
2167 m_task_now = next;
2168 active = next->GetUserStackPtr();
2169
2171 {
2172 next->HrtOnSwitchedIn();
2173 }
2174 }
2175 else
2177 {
2179 active = &m_sleep_trap[0].stack;
2180 }
2181 else
2182 {
2183 // unexpected state
2185 }
2186 }
2187
2188 // is in running state
2190 }
static void STK_KERNEL_PANIC(stk::EKernelPanicId id)
Called when the kernel detects an unrecoverable internal fault.
Definition stk_arch.h:183
EFsmState GetNewFsmState(KernelTask *&next)
Get new FSM state.
Definition stk.h:2925

◆ OnStop()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnStop ( )
inlineoverrideprotectedvirtual

Called by the platform driver after a scheduler stop (all tasks have exited).

Note
KERNEL_DYNAMIC mode only: resets FSM to FSM_STATE_NONE and transitions kernel back to KSTATE_READY so Start() may be called again.
Has no effect in KERNEL_STATIC mode (static kernels never stop).

Implements stk::IPlatform::IEventHandler.

Definition at line 2197 of file stk.h.

2198 {
2200 {
2202
2203 // is in stopped state, i.e. is ready to Start() again
2205 }
2206 }

◆ OnSuspend()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnSuspend ( bool suspended)
inlineoverrideprotectedvirtual

Called from the Thread process to suspend scheduling.

Parameters
[in]suspendedtrue if scheduling was successfully suspended, false otherwise.

Implements stk::IPlatform::IEventHandler.

Definition at line 2513 of file stk.h.

2514 {
2515 // toggle kernel state
2516 if (suspended)
2517 {
2518 if (m_kstate == KSTATE_RUNNING)
2519 {
2521 }
2522 }
2523 else
2524 {
2525 if (m_kstate == KSTATE_SUSPENDED)
2526 {
2528 }
2529 }
2530
2531 // force yield for a currently active task
2532 if (!m_task_now->IsSleeping())
2533 {
2534 m_task_now->ScheduleSleep(YIELD_TICKS);
2535 }
2536 }
static constexpr Timeout YIELD_TICKS
Ticks to yield.
Definition stk.h:1843

◆ OnTaskExit()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnTaskExit ( Stack * stack)
inlineoverrideprotectedvirtual

Called from the Thread process when task finished (its Run function exited by return).

Parameters
[out]stackStack of the exited task.

Implements stk::IPlatform::IEventHandler.

Definition at line 2415 of file stk.h.

2416 {
2418 {
2420 STK_ASSERT(task != nullptr);
2421
2422 // task is being stopped and will terminate
2423 #if STK_SEGGER_SYSVIEW
2425 #endif
2426
2427 // critical section: avoid race with OnTick
2428 {
2429 // make change to HRT/sleep/removal state atomic (same as OnTaskSleep/OnTaskSleepUntil)
2431
2432 // notify kernel to execute removal (asynchronous operation)
2433 task->ScheduleRemoval(this);
2434 }
2435 }
2436 else
2437 {
2438 // kernel operating mode must be KERNEL_DYNAMIC for tasks to be able to exit
2440 }
2441 }
KernelTask * FindTaskByStack(const Stack *stack)
Find kernel task by the bound Stack instance.
Definition stk.h:2046

◆ OnTaskSleep()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnTaskSleep ( Word caller_SP,
Timeout ticks )
inlineoverrideprotectedvirtual

Called by Thread process (via IKernelService::Sleep) for exclusion of the calling process from scheduling (sleeping).

Parameters
[in]caller_SPValue of Stack Pointer (SP) register (for locating the calling process inside the kernel).
[in]ticksTime to sleep (ticks).

Implements stk::IPlatform::IEventHandler.

Definition at line 2347 of file stk.h.

2348 {
2350 STK_ASSERT(task != nullptr);
2351
2352 // // critical section: make change to HRT state and sleep time atomic
2353 {
2355
2357 {
2358 task->HrtOnWorkCompleted();
2359 }
2360
2361 if (ticks > 0)
2362 {
2363 task->ScheduleSleep(ticks);
2364
2365 // trace blocked on Sleep
2366 #if STK_SEGGER_SYSVIEW
2367 SEGGER_SYSVIEW_OnTaskStopReady(task->GetUserStackPtr()->tid, TRACE_EVENT_SLEEP);
2368 #endif
2369 }
2370 }
2371
2372 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
2373 task->BusyWaitWhileSleeping(this);
2374 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSwitch().

Here is the caller graph for this function:

◆ OnTaskSleepUntil()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnTaskSleepUntil ( Word caller_SP,
Ticks timestamp )
inlineoverrideprotectedvirtual

Called by Thread process (via IKernelService::SleepUntil) for exclusion of the calling process from scheduling (sleeping).

Parameters
[in]caller_SPValue of Stack Pointer (SP) register (for locating the calling process inside the kernel).
[in]timestampAbsolute timestamp (ticks).
Returns
True if sleep succeeded, false otherwise.

Implements stk::IPlatform::IEventHandler.

Definition at line 2376 of file stk.h.

2377 {
2379 STK_ASSERT(task != nullptr);
2380
2381 bool result = true;
2382
2383 // critical section: make change to HRT state and sleep time atomic
2384 {
2386
2387 // calculate signed delta (handles wrap-around correctly)
2388 const Ticks delta = timestamp - m_service.m_ticks;
2389
2390 if (delta > 0)
2391 {
2393 task->ScheduleSleep(static_cast<Timeout>(Min(delta, infinite_ticks)));
2394
2395 // trace blocked on on SleepUntil
2396 #if STK_SEGGER_SYSVIEW
2397 SEGGER_SYSVIEW_OnTaskStopReady(task->GetUserStackPtr()->tid, TRACE_EVENT_SLEEP);
2398 #endif
2399 }
2400 else
2401 {
2402 result = false; // deadline already hit or passed
2403 }
2404 }
2405
2406 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
2407 if (result)
2408 {
2409 task->BusyWaitWhileSleeping(this);
2410 }
2411
2412 return result;
2413 }

◆ OnTaskSwitch()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnTaskSwitch ( Word caller_SP)
inlineoverrideprotectedvirtual

Called by Thread process (via IKernelService::SwitchToNext) to switch to a next task.

Parameters
[in]caller_SPValue of Stack Pointer (SP) register (for locating the calling process inside the kernel).

Implements stk::IPlatform::IEventHandler.

Definition at line 2299 of file stk.h.

2300 {
2301 // let the strategy handle the yield without putting the task to sleep (e.g. to hand
2302 // the CPU to same-priority peers only), not applicable in HRT mode where Yield()
2303 // means work completion
2305 {
2307 STK_ASSERT(task != nullptr);
2308
2309 if (task != nullptr)
2310 {
2311 bool handled = false;
2312
2313 // critical section: avoid race with OnTick
2314 {
2316
2317 if (!task->IsSleeping())
2318 {
2319 if (m_strategy.OnTaskYield(task))
2320 {
2321 task->ScheduleYield();
2322 handled = true;
2323 }
2324 }
2325 }
2326
2327 if (handled)
2328 {
2329 task->BusyWaitWhileYielding(this);
2330 }
2331 else
2332 {
2334 }
2335 }
2336 else
2337 {
2338 // defensive: do nothing on null task
2339 }
2340 }
2341 else
2342 {
2344 }
2345 }
void OnTaskSleep(Word caller_SP, Timeout ticks) override
Called by Thread process (via IKernelService::Sleep) for exclusion of the calling process from schedu...
Definition stk.h:2347

◆ OnTaskWait()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
EWaitResult stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnTaskWait ( Word caller_SP,
ISyncObject * sync_obj,
IMutex * mutex,
Timeout timeout )
inlineoverrideprotectedvirtual

Called from the Thread process when task needs to wait.

Parameters
[in]caller_SPValue of Stack Pointer (SP) register (for locating the calling process inside the kernel).
[in]sync_objISyncObject instance (passed by Wait).
[in]mutexIMutex instance (passed by Wait).
[in]timeoutTime to sleep (ticks).

Implements stk::IPlatform::IEventHandler.

Definition at line 2443 of file stk.h.

2444 {
2446 {
2447 STK_ASSERT(timeout != 0); // API contract: caller must not be in ISR
2448 STK_ASSERT(sync_obj != nullptr); // API contract: ISyncObject instance must be provided
2449 STK_ASSERT(mutex != nullptr); // API contract: IMutex instance must be provided
2450 STK_ASSERT((sync_obj->GetHead() == nullptr) || (sync_obj->GetHead() == &m_sync_list[0]));
2451
2453 STK_ASSERT(task != nullptr);
2454
2455 typename KernelTask::WaitObject &wait_obj = task->m_wait_obj[0];
2456
2457 // critical section: avoid race with OnTick
2458 {
2459 // keep the task from being de-scheduled between ScheduleSleep() and the end of mutex->Unlock():
2460 // otherwise a tick can switch it out (sleeping) while it still owns the mutex
2462
2463 // configure waiting
2464 wait_obj.SetupWait(sync_obj, timeout);
2465
2466 // register ISyncObject if not yet
2467 if (sync_obj->GetHead() == nullptr)
2468 {
2469 m_sync_list->LinkBack(sync_obj);
2470 }
2471
2472 // start sleeping infinitely, we rely on a Wake call via WaitObject
2473 task->ScheduleSleep(WAIT_INFINITE);
2474
2475 // trace blocked on sync object's Wait
2476 #if STK_SEGGER_SYSVIEW
2477 SEGGER_SYSVIEW_OnTaskStopReady(task->GetUserStackPtr()->tid, TRACE_EVENT_WAIT);
2478 #endif
2479
2480 // unlock mutex locked externally, so that we could wait in a busy-waiting loop
2481 mutex->Unlock();
2482 }
2483
2484 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
2485 task->BusyWaitWhileSleeping(this);
2486
2487 // extract & clear this wait's result BEFORE mutex->Lock(): a contended Lock() recurses
2488 // into OnTaskWait() and reuses this same per-task WaitObject, which would otherwise
2489 // silently overwrite/clear our still-unread result
2490 const EWaitResult result = wait_obj.GetWaitResult();
2491 wait_obj.ClearState();
2492
2493 // re-lock mutex when returning to the task's execution space
2494 mutex->Lock();
2495
2496 return result;
2497 }
2498 else
2499 {
2500 STK_ASSERT(false);
2501 return WAIT_RESULT_FAIL;
2502 }
2503 }
SyncObjectList m_sync_list[STK_ALLOCATE_COUNT< TMode, KERNEL_SYNC, 1U, 0U >::Value]
List of active sync objects. Zero-size (no memory) if KERNEL_SYNC is not set.
Definition stk.h:3250

◆ OnTick()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnTick ( Stack *& idle,
Stack *& active,
Timeout & ticks )
inlineoverrideprotectedvirtual

Process one scheduler tick. Called from the platform timer/tick ISR.

Parameters
[out]idleStack descriptor to context-switch out (nullptr if no switch needed).
[out]activeStack descriptor to context-switch in (nullptr if no switch needed).
[in,out]ticks(KERNEL_TICKLESS builds only) On entry: actual number of ticks elapsed since the last call, as measured by the platform driver. On return: the number of ticks the hardware timer may suppress before the next required wakeup, computed as the minimum remaining sleep across all active tasks, clamped to [1, STK_TICKLESS_TICKS_MAX]. The platform driver programs this value into the timer to avoid unnecessary wakeups. This parameter is absent in non-tickless builds.
Returns
true if a context switch is required (idle and active are valid); false if the current task continues running.
Note
In non-tickless mode the internal tick counter always advances by exactly 1 per call.
In tickless mode (KERNEL_TICKLESS) the counter advances by the ticks value supplied by the platform driver, which may be greater than 1 after a suppressed interval.

Implements stk::IPlatform::IEventHandler.

Definition at line 2224 of file stk.h.

2229 {
2230 #if !STK_TICKLESS_IDLE
2231 // in non-tickless mode kernel is advancing strictly by 1 tick on every OnTick call
2232 enum { ticks = 1 };
2233 #endif
2234
2235 // elapsed ticks must be captured here: in tickless mode "ticks" is overwritten below
2236 const Timeout elapsed_ticks = ticks;
2237
2238 // advance internal timestamp
2239 m_service.IncrementTicks(elapsed_ticks);
2240
2241 // consume elapsed and update to ticks to sleep
2242 #if STK_TICKLESS_IDLE
2243 ticks = (
2244 #else
2245 // notify compiler that we ignore a return value of UpdateTasks
2246 STK_UNUSED(
2247 #endif
2249
2250 // time-slice accounting for the task that just ran (after sleep/wake updates, before the FSM picks next)
2252 {
2254 }
2255
2256 // decide on a context switch
2257 return UpdateFsmState(idle, active);
2258 }
static constexpr bool IsTimesliceMode()
Definition stk.h:3161
Timeout UpdateTasks(const Timeout elapsed_ticks)
Update tasks (sleep, requests).
Definition stk.h:2652
void UpdateTimeslice(const Timeout elapsed_ticks)
Charge the running task and rotate it behind its same-priority peers when its slice expires.
Definition stk.h:2607

◆ ProcessTaskPendingSleep()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::ProcessTaskPendingSleep ( KernelTask *const task)
inlineprotected

◆ ProcessTaskPendingYield()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::ProcessTaskPendingYield ( KernelTask *const task)
inlineprotected

◆ RemoveTask() [1/2]

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::RemoveTask ( ITask * user_task)
inlineoverridevirtual

Remove a previously added task from the kernel when it is not started.

Parameters
[in]user_taskUser task to remove. Must not be nullptr.
Note
Only valid before Start() (i.e. while the kernel is not running). To remove tasks after Start() the task should return from its Run function (in KERNEL_DYNAMIC mode the slot is freed automatically on the next tick).
Warning
KERNEL_DYNAMIC mode only. Asserts if called in KERNEL_STATIC or KERNEL_HRT mode, or if called after Start().

Implements stk::IKernel.

Definition at line 1439 of file stk.h.

1440 {
1442 {
1443 STK_ASSERT(user_task != nullptr);
1445
1447 if (task != nullptr)
1448 {
1450 }
1451 }
1452 else
1453 {
1454 // kernel operating mode must be KERNEL_DYNAMIC for tasks to be able to be removed
1455 STK_ASSERT(false);
1456 }
1457 }
void RemoveTask(ITask *user_task) override
Remove a previously added task from the kernel when it is not started.
Definition stk.h:1439

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::RemoveTask(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTaskState().

Here is the caller graph for this function:

◆ RemoveTask() [2/2]

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::RemoveTask ( KernelTask * task)
inlineprotected

Remove kernel task.

Note
Removal of the kernel task means releasing it from the user task details.
Parameters
[in]taskKernel task.

Definition at line 2107 of file stk.h.

2108 {
2109 STK_ASSERT(task != nullptr);
2110
2111 #if STK_SEGGER_SYSVIEW
2112 SEGGER_SYSVIEW_OnTaskTerminate(task->GetUserStackPtr()->tid);
2113 #endif
2114
2115 // notify task about pending exit
2116 task->GetUserTask()->OnExit();
2117
2118 m_strategy.RemoveTask(task);
2119 task->Unbind();
2120 }

◆ RequestAddTask()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::RequestAddTask ( ITask *const user_task)
inlineprotected

Request to add new task.

Note
Must be called by the task process only!
Parameters
[in]user_taskUser task to add.

Definition at line 1974 of file stk.h.

1975 {
1976 KernelTask *const caller = FindTaskBySP(m_platform.GetCallerSP());
1977 STK_ASSERT(caller != nullptr);
1978
1979 typename KernelTask::SrtInfo &srt = caller->m_srt[0];
1980
1981 typename KernelTask::AddTaskRequest req = { .user_task = user_task };
1982 srt.add_task_req = &req;
1983
1984 // notify kernel
1986
1987 // switch out and wait for completion (due to context switch request could be processed here)
1988 if (srt.add_task_req != nullptr)
1989 {
1990 m_service.SwitchToNext();
1991 }
1992
1993 // wait until request is consumed
1995 {
1996 while (srt.add_task_req != nullptr)
1997 {
1999 }
2000 }
2001
2002 STK_ASSERT(srt.add_task_req == nullptr);
2003 }
void ScheduleAddTask()
Signal the kernel to process a pending AddTask request on the next tick.
Definition stk.h:3124
Payload for an in-flight AddTask() request issued by a running task.
Definition stk.h:162
Per-task soft real-time (SRT) metadata.
Definition stk.h:446

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::AddTask().

Here is the caller graph for this function:

◆ ResumeTask()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::ResumeTask ( ITask * user_task)
inlineoverridevirtual

Resume task.

Parameters
[in]user_taskPointer to the user task to resume.
Warning
Must not be called on a task blocked in OnTaskWait() on a sync object - asserts. Use CancelTaskWait() instead.

Implements stk::IKernel.

Definition at line 1551 of file stk.h.

1552 {
1553 STK_ASSERT(user_task != nullptr);
1554
1555 // critical section: avoid race with OnTick
1556
1558
1560 STK_ASSERT(task != nullptr);
1561
1562 // must be suspended by SuspendTask, otherwise noop
1563 if ((task->m_state & KernelTask::STATE_SUSPENDED) != 0U)
1564 {
1565 // clear state
1567
1568 // wake up
1569 if (task->IsSleeping())
1570 {
1571 task->Wake();
1572 }
1573 }
1574 }

◆ ScheduleAddTask()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::ScheduleAddTask ( )
inlineprotected

Signal the kernel to process a pending AddTask request on the next tick.

Note
Sets the REQ_ADD_TASK bit in m_request under a hw::CriticalSection::ScopedLock, so the ISR-side tick handler observes the flag safely without a data race.

Definition at line 3124 of file stk.h.

3125 {
3126 // critical section: avoid race with OnTick
3127 {
3129
3131 }
3132 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::RequestAddTask().

Here is the caller graph for this function:

◆ ScheduleTaskRemoval()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::ScheduleTaskRemoval ( ITask * user_task)
inlineoverridevirtual

Schedule task removal from scheduling (exit).

Parameters
[in]user_taskUser task to remove. Must not be nullptr.
Warning
KERNEL_DYNAMIC mode only. Asserts if called in KERNEL_STATIC or KERNEL_HRT mode, or if called after Start().

Implements stk::IKernel.

Definition at line 1464 of file stk.h.

1465 {
1467 {
1468 STK_ASSERT(user_task != nullptr);
1470
1471 // critical section: avoid race with OnTick
1472
1474
1476 if (task != nullptr)
1477 {
1478 task->ScheduleRemoval(this);
1479 }
1480 }
1481 else
1482 {
1483 // kernel operating mode must be KERNEL_DYNAMIC for tasks to be able to be removed
1484 STK_ASSERT(false);
1485 }
1486 }

◆ Start()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::Start ( )
inlineoverridevirtual

Start the scheduler. This call does not return until all tasks have exited (KERNEL_DYNAMIC mode) or indefinitely (KERNEL_STATIC mode).

Note
Re-initializes trap stacks on every call so Start() can be called again after a previous scheduling session ended.
If STK_SEGGER_SYSVIEW is enabled, starts tracing and registers all pre-added tasks.
Warning
At least one task must have been added via AddTask() before calling Start(). Asserts if called before Initialize().

Implements stk::IKernel.

Definition at line 1755 of file stk.h.

1756 {
1758
1759 // stacks of the traps must be re-initilized on every subsequent Start
1760 InitTraps();
1761
1762 // start tracing
1763 #if STK_SEGGER_SYSVIEW
1765 for (size_t i = 0U; i < TASKS_MAX; ++i)
1766 {
1768 if (task->IsBusy())
1769 {
1771 }
1772 }
1773 #endif
1774
1775 m_platform.Start();
1776 }
void InitTraps()
Initialize stack of the traps.
Definition stk.h:1854

◆ StateExit()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::StateExit ( KernelTask * now,
KernelTask * next,
Stack *& idle,
Stack *& active )
inlineprotected

Exits from scheduling.

Note
FSM state: stk::FSM_STATE_EXITING.
Exits only if stk::KERNEL_DYNAMIC mode is specified, otherwise ignored.
Parameters
[in]nowCurrently active kernel task (ignored).
[in]nextNext kernel task (ignored).
[out]idleStack of the task which must enter Idle state.
[out]activeStack of the task which must enter Active state (to which context will switch).

Definition at line 3089 of file stk.h.

3090 {
3091 STK_UNUSED(now);
3093
3095 {
3096 // dynamic tasks are not supported if main processes's stack memory is not provided in Start()
3097 STK_ASSERT(m_exit_trap[0].stack.SP != 0);
3098
3099 idle = nullptr;
3100 active = &m_exit_trap[0].stack;
3101
3102 m_task_now = nullptr;
3103
3104 m_platform.Stop();
3105 }
3106 else
3107 {
3110 }
3111
3112 return false;
3113 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateFsmState().

Here is the caller graph for this function:

◆ StateSleep()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::StateSleep ( KernelTask * now,
KernelTask * next,
Stack *& idle,
Stack *& active )
inlineprotected

Enters into a sleeping mode.

Note
FSM state: stk::FSM_STATE_SLEEPING.
Parameters
[in]nowCurrently active kernel task.
[in]nextNext kernel task (ignored).
[out]idleStack of the task which must enter Idle state.
[out]activeStack of the task which must enter Active state (to which context will switch).

Definition at line 3058 of file stk.h.

3059 {
3061
3062 STK_ASSERT(now != nullptr);
3063 STK_ASSERT(m_sleep_trap[0].stack.SP != 0);
3064
3065 idle = now->GetUserStackPtr();
3066 active = &m_sleep_trap[0].stack;
3067
3069
3071 {
3072 if (!now->IsPendingRemoval())
3073 {
3074 now->HrtOnSwitchedOut();
3075 }
3076 }
3077
3078 return true; // switch context
3079 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateFsmState().

Here is the caller graph for this function:

◆ StateSwitch()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::StateSwitch ( KernelTask * now,
KernelTask * next,
Stack *& idle,
Stack *& active )
inlineprotected

Switches contexts.

Note
FSM state: stk::FSM_STATE_SWITCHING.
Parameters
[in]nowCurrently active kernel task.
[in]nextNext kernel task.
[out]idleStack of the task which must enter Idle state.
[out]activeStack of the task which must enter Active state (to which context will switch).

Definition at line 2979 of file stk.h.

2980 {
2981 STK_ASSERT(now != nullptr);
2982 STK_ASSERT(next != nullptr);
2983
2984 bool switch_context = false;
2985
2986 // if equal: do not switch context because task did not change
2987 if (next != now)
2988 {
2989 idle = now->GetUserStackPtr();
2990 active = next->GetUserStackPtr();
2991
2992 // if stack memory is exceeded these assertions will be hit
2993 #if STK_STACK_GUARD
2994 if (now->IsBusy())
2995 {
2996 // current task could exit, thus we check it with IsBusy to avoid referencing nullptr returned by GetUserTask()
2997 STK_ASSERT(now->GetUserTask()->GetStack()[0] == STK_STACK_MEMORY_FILLER);
2998 }
2999 STK_ASSERT(next->GetUserTask()->GetStack()[0] == STK_STACK_MEMORY_FILLER);
3000 #endif
3001
3002 m_task_now = next;
3003
3005 {
3006 if (now->m_hrt[0].done)
3007 {
3008 now->HrtOnSwitchedOut();
3009 next->HrtOnSwitchedIn();
3010 }
3011 }
3012
3013 switch_context = true;
3014 }
3015
3016 return switch_context;
3017 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateFsmState().

Here is the caller graph for this function:

◆ StateWake()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::StateWake ( KernelTask * now,
KernelTask * next,
Stack *& idle,
Stack *& active )
inlineprotected

Wakes up after sleeping.

Note
FSM state: stk::FSM_STATE_WAKING.
Parameters
[in]nowCurrently active kernel task (ignored).
[in]nextNext kernel task.
[out]idleStack of the task which must enter Idle state.
[out]activeStack of the task which must enter Active state (to which context will switch).

Definition at line 3026 of file stk.h.

3027 {
3028 STK_UNUSED(now);
3029
3030 STK_ASSERT(next != nullptr);
3031
3032 idle = &m_sleep_trap[0].stack;
3033 active = next->GetUserStackPtr();
3034
3035 // if stack memory is exceeded these assertions will be hit
3037 #if STK_STACK_GUARD
3038 STK_ASSERT(next->GetUserTask()->GetStack()[0] == STK_STACK_MEMORY_FILLER);
3039 #endif
3040
3041 m_task_now = next;
3042
3044 {
3045 next->HrtOnSwitchedIn();
3046 }
3047
3048 return true; // switch context
3049 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateFsmState().

Here is the caller graph for this function:

◆ SuspendTask()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::SuspendTask ( ITask * user_task,
bool & suspended )
inlineoverridevirtual

Suspend task.

Parameters
[in]user_taskPointer to the user task to suspend.
[out]suspendedSet to true if task is suspended.
Note
hw::CriticalSection must not be active otherwise a deadlock will happen if task is suspending self.

Implements stk::IKernel.

Definition at line 1494 of file stk.h.

1495 {
1496 STK_ASSERT(user_task != nullptr);
1497
1498 bool self = false;
1499 KernelTask *self_task = nullptr;
1500
1501 // critical section: avoid race with OnTick
1502 {
1504
1506 STK_ASSERT(task != nullptr);
1507
1508 // nesting not supported, must not be suspended by SuspendTask
1509 STK_ASSERT((task->m_state & KernelTask::STATE_SUSPENDED) == 0U);
1510
1511 // only suspend if the task is currently awake: if it is already sleeping
1512 // (e.g. blocked on a mutex or timed Sleep), do not overwrite m_time_sleep,
1513 // that would corrupt the original sleep state and, for sync-object waits,
1514 // would interfere with WaitObject::Tick()
1515 suspended = !task->IsSleeping();
1516 if (suspended == true)
1517 {
1518 task->ScheduleSleep(WAIT_INFINITE);
1519
1520 // check if suspending self
1521 self = (task == m_task_now);
1522
1523 // trace blocked via Suspend
1524 if (self)
1525 {
1526 // keep the pointer: m_task_now may change as soon as the critical section is released
1527 self_task = task;
1528
1529 #if STK_SEGGER_SYSVIEW
1531 #endif
1532 }
1533
1534 // set state
1536 }
1537 }
1538
1539 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
1540 if (self_task != nullptr)
1541 {
1542 self_task->BusyWaitWhileSleeping(this);
1543 }
1544 }

◆ UpdateFsmState()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::UpdateFsmState ( Stack *& idle,
Stack *& active )
inlineprotected

Update FSM state.

Parameters
[out]idleStack of the task which must enter Idle state.
[out]activeStack of the task which must enter Active state (to which context will switch).
Returns
FSM state.

Definition at line 2936 of file stk.h.

2937 {
2938 KernelTask *const now = m_task_now, *next = nullptr;
2939 bool switch_context = false;
2940
2942
2943 switch (new_state)
2944 {
2948 break;
2949 case FSM_STATE_SLEEPING:
2952 break;
2953 case FSM_STATE_WAKING:
2956 break;
2957 case FSM_STATE_EXITING:
2960 break;
2961 case FSM_STATE_NONE:
2962 break; // valid intermittent non-persisting state: no-transition
2963 case FSM_STATE_MAX:
2964 default: // invalid state value
2966 break;
2967 }
2968
2969 return switch_context;
2970 }
EFsmState
Finite-state machine (FSM) state. Encodes what the kernel is currently doing between two consecutive ...
Definition stk.h:1815
bool StateWake(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Wakes up after sleeping.
Definition stk.h:3026
bool StateExit(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Exits from scheduling.
Definition stk.h:3089
bool StateSwitch(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Switches contexts.
Definition stk.h:2979
bool StateSleep(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Enters into a sleeping mode.
Definition stk.h:3058

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnForceContextSwitch(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTick().

Here is the caller graph for this function:

◆ UpdateSyncObjects()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::UpdateSyncObjects ( const Timeout elapsed_ticks)
inlineprotected

Update synchronization objects.

Definition at line 2831 of file stk.h.

2832 {
2834
2835 while (itr != nullptr)
2836 {
2837 ISyncObject::ListEntryType *const next = itr->GetNext();
2838
2840 {
2841 m_sync_list->Unlink(itr);
2842 }
2843
2844 itr = next;
2845 }
2846 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTasks().

Here is the caller graph for this function:

◆ UpdateTaskRequest()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::UpdateTaskRequest ( )
inlineprotected

Update pending task requests.

Definition at line 2850 of file stk.h.

2851 {
2852 // process AddTask requests coming from tasks (KERNEL_DYNAMIC mode only, KERNEL_HRT is
2853 // excluded as we assume that HRT tasks must be known to the kernel before a Start())
2855 {
2856 // process serialized AddTask request made from another active task, requesting process
2857 // is currently waiting due to SwitchToNext()
2858 if ((m_request & REQ_ADD_TASK) != 0U)
2859 {
2861
2862 for (size_t i = 0U; i < TASKS_MAX; ++i)
2863 {
2864 KernelTask *const task = &m_task_storage[i];
2865
2866 typename KernelTask::SrtInfo &srt = task->m_srt[0];
2867
2868 if (srt.add_task_req != nullptr)
2869 {
2870 AllocateAndAddNewTask(srt.add_task_req->user_task);
2871
2872 srt.add_task_req = nullptr;
2874 }
2875 }
2876 }
2877 }
2878 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTasks().

Here is the caller graph for this function:

◆ UpdateTasks()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
Timeout stk::Kernel< TMode, TSize, TStrategy, TPlatform >::UpdateTasks ( const Timeout elapsed_ticks)
inlineprotected

Update tasks (sleep, requests).

Definition at line 2652 of file stk.h.

2653 {
2654 // sync objects are updated before UpdateTaskRequest which may add a new object (newly added object must become 1 tick older)
2656 {
2658 }
2659
2660 if (m_request != REQ_NONE)
2661 {
2663 }
2664
2666 }
void UpdateTaskRequest()
Update pending task requests.
Definition stk.h:2850
Timeout UpdateTaskState(const Timeout elapsed_ticks)
Update task state: process removals, deliver sleep/wake notifications, advance sleep timers,...
Definition stk.h:2715
void UpdateSyncObjects(const Timeout elapsed_ticks)
Update synchronization objects.
Definition stk.h:2831

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTick().

Here is the caller graph for this function:

◆ UpdateTaskState()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
Timeout stk::Kernel< TMode, TSize, TStrategy, TPlatform >::UpdateTaskState ( const Timeout elapsed_ticks)
inlineprotected

Update task state: process removals, deliver sleep/wake notifications, advance sleep timers, and track HRT durations.

Parameters
[in]elapsed_ticksNumber of ticks elapsed since the previous call. Always 1 in non-tickless mode, may be >1 in tickless mode.
Returns
In non-tickless mode: always 1. In tickless mode (KERNEL_TICKLESS): the minimum remaining sleep ticks across all active tasks, clamped to [1, STK_TICKLESS_TICKS_MAX]. The platform driver uses this value to program the next timer wakeup interval, suppressing timer/tick ISR for that many ticks when the system would otherwise be idle.
Note
Sleep entry/exit protocol: ScheduleSleep() sets STATE_SLEEP_PENDING and stores m_time_sleep = -ticks. This function's first pass over a newly-sleeping task (the "entry tick") consumes STATE_SLEEP_PENDING and delivers OnTaskSleep() to the strategy, but does NOT also advance m_time_sleep on that same pass - doing both in one call would let a 1-tick sleep collapse to zero elapsed time (OnTaskSleep and OnTaskWake firing back-to-back before the task was ever excluded from scheduling). The entry tick is therefore required to be a single, uncoalesced tick (asserted below); this holds because a task can only enter STATE_SLEEP_PENDING by putting itself to sleep, which means it was actively running (not idle) up to that point, so tickless coalescing, which only suppresses ticks while the CPU is idle, cannot have applied yet. If Wake()/SleepCancel() races in before the entry tick runs, STATE_WAKE_PENDING is set alongside STATE_SLEEP_PENDING. The entry tick then delivers OnTaskSleep() followed immediately by the normal advance (and OnTaskWake(), since m_time_sleep was already primed to -1 by Wake()) in the same pass, so the task still resumes on the next tick as promised, with the two notifications correctly paired instead of an orphaned OnTaskWake(). Tasks sleeping via WAIT_INFINITE (IsSleepInfinite()) are excluded from the per-tick advance entirely so they never spuriously time out; only an explicit Wake() (which directly sets m_time_sleep = -1) ends an infinite sleep.

Definition at line 2715 of file stk.h.

2716 {
2718
2719 for (size_t i = 0U; i < TASKS_MAX; ++i)
2720 {
2721 KernelTask *const task = &m_task_storage[i];
2722
2724 {
2725 // a pending yield is consumed by this tick (the strategy already moved its cursor)
2726 if ((task->m_state & KernelTask::STATE_YIELD_PENDING) != 0U)
2727 {
2729 }
2730 }
2731
2732 if (task->IsSleeping())
2733 {
2735 {
2736 // task is pending removal, wait until it is switched out
2737 if (task->IsPendingRemoval())
2738 {
2739 const size_t tasks_left = m_strategy.GetSize();
2740
2741 if ((task != m_task_now) ||
2742 ((tasks_left == 1U) && (m_fsm_state == FSM_STATE_SLEEPING)))
2743 {
2745 continue;
2746 }
2747 }
2748 }
2749
2750 bool just_entered_sleep = false;
2751
2752 // note: only currently scheduled task can be pending to sleep
2753 if ((task->m_state & KernelTask::STATE_SLEEP_PENDING) != 0U)
2754 {
2755 STK_ASSERT(elapsed_ticks == 1); // entry tick must be a single, uncoalesced tick
2756
2757 // if Wake() raced in before this entry tick ran, STATE_WAKE_PENDING is set:
2758 // deliver OnTaskSleep() below as usual, then fall through to the advance block
2759 // in this same pass instead of waiting an extra tick, so the paired OnTaskWake()
2760 // still fires on schedule.
2761 const bool wake_pending = ((task->m_state & KernelTask::STATE_WAKE_PENDING) != 0U);
2762
2764
2766 }
2767
2768 if (!just_entered_sleep && !task->IsSleepInfinite())
2769 {
2770 // advance sleep time by number of elapsed ticks (always 1 if non-Tickless)
2771 task->m_time_sleep += elapsed_ticks;
2772
2773 // deliver sleep event to the strategy
2775 {
2776 // notify strategy that the task woke up
2777 if (!task->IsSleeping())
2778 {
2779 m_strategy.OnTaskWake(task);
2780 }
2781 }
2782 }
2783 }
2784 else
2785 {
2787 {
2788 // in HRT mode we trace how long task spent in active state (doing some work)
2789 if (task->IsBusy())
2790 {
2791 typename KernelTask::HrtInfo &hrt = task->m_hrt[0];
2792
2793 hrt.duration += elapsed_ticks;
2794
2795 // check if deadline is missed (HRT failure)
2796 if (task->HrtIsDeadlineMissed(hrt.duration))
2797 {
2798 // report deadline overrun to the strategy which supports overrun recovery
2800 {
2801 if (!m_strategy.OnTaskDeadlineMissed(task))
2802 {
2803 // report failure if it could not be recovered by the scheduling strategy
2804 task->HrtHardFailDeadline(&m_platform);
2805 }
2806 }
2807 else
2808 {
2809 task->HrtHardFailDeadline(&m_platform);
2810 }
2811 }
2812 }
2813 }
2814 }
2815
2816 // get the number of ticks the driver has to keep CPU in Idle
2818 {
2819 if ((sleep_ticks > 1) && task->IsBusy())
2820 {
2821 sleep_ticks = task->GetSleepTicks(sleep_ticks);
2822 }
2823 }
2824 }
2825
2826 return sleep_ticks;
2827 }
Timeout GetInitialSleepTicks()
static constexpr bool IsTicklessMode()
Definition stk.h:3160
Per-task Hard Real-Time (HRT) scheduling metadata.
Definition stk.h:470

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTasks().

Here is the caller graph for this function:

◆ UpdateTimeslice()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::UpdateTimeslice ( const Timeout elapsed_ticks)
inlineprotected

Charge the running task and rotate it behind its same-priority peers when its slice expires.

Note
KERNEL_TIMESLICE only. Called from OnTick() after UpdateTasks() and before UpdateFsmState().
Parameters
[in]elapsed_ticksTicks since the previous OnTick() (always 1 in non-tickless mode).

Definition at line 2607 of file stk.h.

2608 {
2609 KernelTask *const task = m_task_now;
2610
2611 // only a real, runnable task is charged: not the sleep trap, not a task which is leaving
2612 if ((task != nullptr) &&
2614 task->IsBusy() && !task->IsSleeping())
2615 {
2616 typename KernelTask::TsInfo &ts = task->m_ts[0];
2617
2618 if (ts.quantum != NO_TIME_SLICE)
2619 {
2620 ts.left -= elapsed_ticks;
2621
2622 if (ts.left <= 0)
2623 {
2624 ts.Reload();
2625
2626 // strategy rotates to a same-priority peer if there is one, otherwise (or if the
2627 // task is not eligible) the task keeps running with a fresh slice
2628 STK_UNUSED(m_strategy.OnTaskTimeSlice(task));
2629 }
2630 }
2631 }
2632 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTick().

Here is the caller graph for this function:

Member Data Documentation

◆ m_exit_trap

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
ExitTrapStack stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_exit_trap[STK_ALLOCATE_COUNT< TMode, KERNEL_DYNAMIC, 1U, 0U >::Value]
protected

Exit trap: zero-size in KERNEL_STATIC mode; one entry in KERNEL_DYNAMIC mode.

Definition at line 3246 of file stk.h.

◆ m_fsm

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
const EFsmState stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_fsm[FSM_STATE_MAX][FSM_EVENT_MAX]
protected
Initial value:

Compile-time FSM transition table. Indexed as m_fsm[current_state][event] -> next_state. FSM_STATE_NONE as a next-state means "no transition": the FSM stays in the current state. Updated by UpdateFsmState() each tick via GetNewFsmState() -> FetchNextEvent().

Definition at line 3252 of file stk.h.

3252 {
3253 // FSM_EVENT_SWITCH FSM_EVENT_SLEEP FSM_EVENT_WAKE FSM_EVENT_EXIT
3258 };

◆ m_fsm_state

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
EFsmState stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_fsm_state
protected

Current FSM state. Drives context-switch decision on every tick.

Definition at line 3247 of file stk.h.

◆ m_kstate

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
volatile EKernelState stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_kstate
protected

Current kernel state.

Definition at line 3249 of file stk.h.

◆ m_platform

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
TPlatform stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_platform
protected

◆ m_request

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
volatile uint8_t stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_request
protected

Bitmask of pending ERequest flags from running tasks. Written by tasks, read/cleared by UpdateTaskRequest() in tick context.

Definition at line 3248 of file stk.h.

◆ m_service

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
KernelService stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_service
protected

Kernel service singleton exposed to running tasks via IKernelService::GetInstance().

Definition at line 3240 of file stk.h.

◆ m_sleep_trap

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
SleepTrapStack stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_sleep_trap[1]
protected

Sleep trap (always present): executed when all tasks are sleeping.

Definition at line 3245 of file stk.h.

◆ m_strategy

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
TStrategy stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_strategy
protected

Task-switching strategy (determines which task runs next).

Definition at line 3242 of file stk.h.

◆ m_sync_list

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
SyncObjectList stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_sync_list[STK_ALLOCATE_COUNT< TMode, KERNEL_SYNC, 1U, 0U >::Value]
protected

List of active sync objects. Zero-size (no memory) if KERNEL_SYNC is not set.

Definition at line 3250 of file stk.h.

◆ m_task_now

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
KernelTask* stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_task_now
protected

Currently executing task, or nullptr before Start() or after all tasks exit.

Definition at line 3243 of file stk.h.

Referenced by stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelTask::ScheduleRemoval().

◆ m_task_storage

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
TaskStorageType stk::Kernel< TMode, TSize, TStrategy, TPlatform >::m_task_storage
protected

Static pool of TSize KernelTask slots (free slots have m_user == nullptr).

Definition at line 3244 of file stk.h.

◆ TASKS_MAX

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
size_t stk::Kernel< TMode, TSize, TStrategy, TPlatform >::TASKS_MAX = TSize
staticconstexpr

Maximum number of concurrently registered tasks. Fixed at compile time. Exceeding this limit in AddTask() triggers a compile-time assert (TASKS_MAX > 0) and a runtime STK_ASSERT.

Definition at line 1295 of file stk.h.

◆ YIELD_TICKS

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
Timeout stk::Kernel< TMode, TSize, TStrategy, TPlatform >::YIELD_TICKS = 1
staticconstexprprotected

Ticks to yield.

Yield with 2 ticks: 1 will be incremented on the next OnTick call by UpdateTasks and remaining 1 will cause a context switch by UpdateFsmState when strategy detects it as a sleeping test.

Definition at line 1843 of file stk.h.


The documentation for this class was generated from the following file: