SuperTinyKernel™ RTOS 1.06.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 and the request flag set to ~0 (indicating uninitialized state; cleared to REQ_NONE 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.
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.
IPlatformGetPlatform () override
 Get platform driver instance owned by this kernel.
ITaskSwitchStrategyGetSwitchStrategy () 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_MINExitTrapStackMemory
 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.
KernelTaskAllocateNewTask (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.
KernelTaskFindTaskByUserTask (const ITask *user_task)
 Find kernel task by the bound ITask instance.
KernelTaskFindTaskByStack (const Stack *stack)
 Find kernel task by the bound Stack instance.
KernelTaskFindTaskBySP (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.
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 OnTaskSleepCancel (TId task_id)
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)
void OnRestoreWeight (TId tid, ISyncObject *sobj)
Timeout UpdateTasks (const Timeout elapsed_ticks)
 Update tasks (sleep, requests).
Timeout UpdateTaskState (const Timeout elapsed_ticks)
 Update task state: process removals, 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.
static constexpr bool IsStaticMode ()
static constexpr bool IsDynamicMode ()
static constexpr bool IsHrtMode ()
static constexpr bool IsSyncMode ()
static constexpr bool IsTicklessMode ()

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).
KernelTaskm_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 = 2
 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_STATIC and KERNEL_DYNAMIC are mutually exclusive.
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:85
void AddTask(ITask *user_task) override
Register task for a soft real-time (SRT) scheduling.
Definition stk.h:1027
void Start() override
Start the scheduler. This call does not return until all tasks have exited (KERNEL_DYNAMIC mode) or i...
Definition stk.h:1253
void Initialize(uint32_t resolution_us=PERIODICITY_DEFAULT) override
Initialize kernel.
Definition stk.h:990

Definition at line 80 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 97 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 91 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 2441 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 2403 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 1318 of file stk.h.

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

◆ 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 1304 of file stk.h.

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

◆ 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 1208 of file stk_common.h.

1209 {
1210 KSTATE_INACTIVE = 0,
1211 KSTATE_READY,
1214 };
@ 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 103 of file stk.h.

104 {
105 REQ_NONE = 0,
106 REQ_ADD_TASK = (1 << 0)
107 };
@ REQ_ADD_TASK
An AddTask() request is pending from a running task (KERNEL_DYNAMIC only).
Definition stk.h:106
@ REQ_NONE
No pending requests.
Definition stk.h:105

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 and the request flag set to ~0 (indicating uninitialized state; cleared to REQ_NONE 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 957 of file stk.h.

959 {
960 #ifdef _DEBUG
961 // TPlatform must inherit IPlatform
964
965 // TStrategy must inherit ITaskSwitchStrategy
968 #endif
969
970 #if !STK_TICKLESS_IDLE
972 "STK_TICKLESS_IDLE must be defined to 1 for KERNEL_TICKLESS");
973 #endif
974 }
#define STK_UNUSED(X)
Explicitly marks a variable as unused to suppress compiler warnings.
Definition stk_defs.h:608
#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:429
volatile uint8_t m_request
Bitmask of pending ERequest flags from running tasks. Written by tasks, read/cleared by UpdateTaskReq...
Definition stk.h:2451
TStrategy m_strategy
Task-switching strategy (determines which task runs next).
Definition stk.h:2445
SleepTrapStack m_sleep_trap[1]
Sleep trap (always present): executed when all tasks are sleeping.
Definition stk.h:2448
volatile EKernelState m_kstate
Current kernel state.
Definition stk.h:2452
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:2449
TaskStorageType m_task_storage
Static pool of TSize KernelTask slots (free slots have m_user == nullptr).
Definition stk.h:2447
KernelTask * m_task_now
Currently executing task, or nullptr before Start() or after all tasks exit.
Definition stk.h:2446
TPlatform m_platform
Platform driver (SysTick, PendSV, context switch implementation).
Definition stk.h:2444
EFsmState m_fsm_state
Current FSM state. Drives context-switch decision on every tick.
Definition stk.h:2450

◆ ~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 1419 of file stk.h.

1420 {
1421 #if STK_SEGGER_SYSVIEW
1422 // start tracing new task
1423 SEGGER_SYSVIEW_OnTaskCreate(task->GetUserStackPtr()->tid);
1424 if (IsStarted())
1426 #endif
1427
1428 m_strategy.AddTask(task);
1429 }
bool IsStarted() const
Check whether scheduler is currently running.
Definition stk.h:1280

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 1027 of file stk.h.

1028 {
1030 {
1031 STK_ASSERT(user_task != nullptr);
1033
1034 // when started the operation must be serialized by switching out from processing until
1035 // kernel processes this request
1036 if (IsStarted())
1037 {
1039 {
1041 }
1042 else
1043 {
1044 STK_ASSERT(false);
1045 }
1046 }
1047 else
1048 {
1050 }
1051 }
1052 else
1053 {
1054 STK_ASSERT(false);
1055 }
1056 }
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:409
#define __stk_constexpr_cpp17
constexpr definition for C++17 and above.
Definition stk_defs.h:382
void RequestAddTask(ITask *const user_task)
Request to add new task.
Definition stk.h:1463
static constexpr bool IsHrtMode()
Definition stk.h:2373
void AllocateAndAddNewTask(ITask *user_task)
Allocate new instance of KernelTask and add it into the scheduling process.
Definition stk.h:1434
bool IsInitialized() const
Check whether Initialize() has been called and completed successfully.
Definition stk.h:2337
static constexpr bool IsDynamicMode()
Definition stk.h:2372

◆ 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 1066 of file stk.h.

1068 {
1070 {
1071 STK_ASSERT(user_task != nullptr);
1074
1076 }
1077 else
1078 {
1079 STK_ASSERT(false);
1080 }
1081 }
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:1449

◆ 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 1434 of file stk.h.

1435 {
1437 STK_ASSERT(task != nullptr);
1438
1440 }
KernelTask * AllocateNewTask(ITask *user_task)
Allocate new instance of KernelTask.
Definition stk.h:1379
void AddKernelTask(KernelTask *task)
Add kernel task to the scheduling strategy.
Definition stk.h:1419
Internal per-slot kernel descriptor that wraps a user ITask instance.
Definition stk.h:121

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 1379 of file stk.h.

1380 {
1381 // look for a free kernel task
1382 KernelTask *new_task = nullptr;
1383 for (size_t i = 0U; i < TASKS_MAX; ++i)
1384 {
1385 KernelTask *const task = &m_task_storage[i];
1386 if (task->IsBusy())
1387 {
1388 // avoid task collision
1389 STK_ASSERT(task->m_user != user_task);
1390
1391 // avoid stack collision
1392 STK_ASSERT(task->m_user->GetStack() != user_task->GetStack());
1393 }
1394 else
1395 if (new_task == nullptr)
1396 {
1397 new_task = task;
1398 #if defined(NDEBUG) && !defined(_STK_ASSERT_REDIRECT)
1399 break; // break if assertions are inactive and do not try to validate collision with existing tasks
1400 #endif
1401 }
1402 else
1403 {
1404 // noop, continue to the next slot
1405 }
1406 }
1407
1408 // if nullptr - exceeded max supported kernel task count, application design failure
1409 STK_ASSERT(new_task != nullptr);
1410
1411 new_task->Bind(&m_platform, user_task);
1412
1413 return new_task;
1414 }
static constexpr size_t TASKS_MAX
Maximum number of concurrently registered tasks. Fixed at compile time. Exceeding this limit in AddTa...
Definition stk.h:948

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:

◆ 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 1201 of file stk.h.

1202 {
1203 size_t count = 0U;
1204 const size_t limit = Min(tasks.GetSize(), TASKS_MAX);
1205
1206 // avoid race with OnTick
1208
1209 for (size_t i = 0U; i < limit; ++i)
1210 {
1211 KernelTask *const task = &m_task_storage[i];
1212 if (task->IsBusy())
1213 {
1214 tasks[count++] = task;
1215 }
1216 }
1217
1218 return count;
1219 }
static constexpr T Min(T a, T b)
Compile-time minimum of two values.
Definition stk_defs.h:639

◆ 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 1225 of file stk.h.

1226 {
1227 size_t count = 0U;
1228 const size_t limit = Min(user_tasks.GetSize(), TASKS_MAX);
1229
1230 // avoid race with OnTick
1232
1233 for (size_t i = 0U; i < limit; ++i)
1234 {
1235 KernelTask *const task = &m_task_storage[i];
1236 if (task->IsBusy())
1237 {
1238 user_tasks[count++] = task->GetUserTask();
1239 }
1240 }
1241
1242 return count;
1243 }

◆ 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:670

Definition at line 1312 of file stk_common.h.

1313 {
1314 STK_STATIC_ASSERT(TMaxCount > 0U);
1315
1316 ITask *tasks[TMaxCount] = {};
1317 size_t count = EnumerateTasks(ArrayView<ITask *>(tasks, TMaxCount));
1318 size_t i = 0U;
1319 bool fetch_next = true;
1320
1321 while ((i < count) && fetch_next)
1322 {
1323 fetch_next = callback(tasks[i]);
1324 ++i;
1325 }
1326
1327 return i;
1328 }
#define STK_STATIC_ASSERT(X)
Compile-time assertion. Produces a compilation error if X is false.
Definition stk_defs.h:446
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 2094 of file stk.h.

2095 {
2097
2098 // try getting next task for scheduling
2100
2101 // sleep-aware strategy returns nullptr if no active tasks available
2102 if (next != nullptr)
2103 {
2104 // strategy must provide active-only task
2105 STK_ASSERT(!next->IsSleeping());
2106
2107 // if was sleeping, process wake event first
2109 }
2110 // start sleeping
2111 else
2112 {
2114 {
2115 // if nullptr is returned then either strategy has all tasks sleeping or none left,
2116 // if KERNEL_DYNAMIC mode and no tasks left then exit from scheduling
2117 if (m_strategy.GetSize() == 0U)
2118 {
2119 next = nullptr;
2121 }
2122 }
2123 }
2124
2125 return type;
2126 }
EFsmEvent
Finite-state machine (FSM) event. Computed by FetchNextEvent() each tick based on strategy output and...
Definition stk.h:1319
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 1529 of file stk.h.

1530 {
1531 STK_ASSERT(m_task_now != nullptr);
1532
1533 KernelTask *found_task = nullptr;
1534
1535 if (m_task_now->IsMemoryOfSP(SP))
1536 {
1538 }
1539 else
1540 {
1541 for (size_t i = 0U; i < TASKS_MAX; ++i)
1542 {
1543 KernelTask *const task = &m_task_storage[i];
1544
1545 // skip finished tasks (applicable only for KERNEL_DYNAMIC mode)
1547 {
1548 if (!task->IsBusy())
1549 {
1550 continue;
1551 }
1552 }
1553
1554 if (task->IsMemoryOfSP(SP))
1555 {
1556 found_task = task;
1557 break;
1558 }
1559 }
1560 }
1561
1562 return found_task;
1563 }

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 >::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 1508 of file stk.h.

1509 {
1510 KernelTask *found_task = nullptr;
1511
1512 for (size_t i = 0U; i < TASKS_MAX; ++i)
1513 {
1514 KernelTask *const task = &m_task_storage[i];
1515 if (task->GetUserStackPtr() == stack)
1516 {
1517 found_task = task;
1518 break;
1519 }
1520 }
1521
1522 return found_task;
1523 }

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()

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.

Parameters
[in]user_taskUser task.
Returns
Kernel task.

Definition at line 1487 of file stk.h.

1488 {
1489 KernelTask *found_task = nullptr;
1490
1491 for (size_t i = 0U; i < TASKS_MAX; ++i)
1492 {
1493 KernelTask *const task = &m_task_storage[i];
1494 if (task->GetUserTask() == user_task)
1495 {
1496 found_task = task;
1497 break;
1498 }
1499 }
1500
1501 return found_task;
1502 }

Referenced by 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 >::OnTaskSleepCancel(), 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:

◆ 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 2135 of file stk.h.

2136 {
2139 }
static bool IsValidFsmState(EFsmState state)
Check if FSM state is valid.
Definition stk.h:1337
const EFsmState m_fsm[FSM_STATE_MAX][FSM_EVENT_MAX]
Definition stk.h:2455
EFsmEvent FetchNextEvent(KernelTask *&next)
Fetch next event for the FSM.
Definition stk.h:2094

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 1288 of file stk.h.

1288{ 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 1297 of file stk.h.

1297{ 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 1293 of file stk.h.

1293{ return &m_strategy; }

◆ 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 1449 of file stk.h.

1450 {
1452 STK_ASSERT(task != nullptr);
1453
1455
1457 }

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 STATE_INACTIVE state.

Implements stk::IKernel.

Definition at line 990 of file stk.h.

991 {
995
996 // reinitialize key state variables
997 m_task_now = nullptr;
1000
1001 // exit trap is required only for KERNEL_DYNAMIC mode
1004 {
1005 exit_trap = &m_exit_trap[0].stack;
1006 }
1007 else
1008 {
1009 exit_trap = nullptr;
1010 }
1011
1012 m_service.Initialize(this);
1013 m_platform.Initialize(this, &m_service, resolution_us, exit_trap);
1014
1015 // now ready to Start()
1017 }
KernelService m_service
Kernel service singleton exposed to running tasks via IKernelService::GetInstance().
Definition stk.h:2443

◆ 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 1345 of file stk.h.

1346 {
1347 // init stack for a Sleep trap
1348 {
1350
1352 sleep.stack.access_mode = ACCESS_PRIVILEGED;
1353 #if STK_NEED_TASK_ID
1354 sleep.stack.tid = SYS_TASK_ID_SLEEP;
1355 #endif
1356
1357 STK_UNUSED(m_platform.InitStack(STACK_SLEEP_TRAP, &sleep.stack, &wrapper, nullptr));
1358 }
1359
1360 // init stack for an Exit trap
1362 {
1364
1366 exit.stack.access_mode = ACCESS_PRIVILEGED;
1367 #if STK_NEED_TASK_ID
1368 exit.stack.tid = SYS_TASK_ID_EXIT;
1369 #endif
1370
1371 STK_UNUSED(m_platform.InitStack(STACK_EXIT_TRAP, &exit.stack, &wrapper, nullptr));
1372 }
1373 }
StackMemoryWrapper< STACK_SIZE_MIN > ExitTrapStackMemory
Stack memory wrapper type for the exit trap.
Definition stk.h:97
StackMemoryWrapper<((32U))> SleepTrapStackMemory
Stack memory wrapper type for the sleep trap.
Definition stk.h:91
Storage bundle for the sleep trap: a Stack descriptor paired with its backing memory.
Definition stk.h:2413
Storage bundle for the exit trap: a Stack descriptor paired with its backing memory.
Definition stk.h:2429

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 2372 of file stk.h.

2372{ 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 2373 of file stk.h.

2373{ 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< 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 2371 of file stk.h.

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

◆ IsSyncMode()

◆ IsTicklessMode()

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

◆ 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 1337 of file stk.h.

1338 {
1339 return (state > FSM_STATE_NONE) &&
1340 (state < FSM_STATE_MAX);
1341 }

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:

◆ 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 1850 of file stk.h.

1851 {
1853 STK_ASSERT(task != nullptr);
1854
1855 return task->GetTid();
1856 }
KernelTask * FindTaskBySP(Word SP)
Find kernel task for a Stack Pointer (SP).
Definition stk.h:1529

◆ 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 1883 of file stk.h.

1884 {
1887
1888 if (weight != NO_WEIGHT)
1889 {
1891 STK_ASSERT(task != nullptr);
1892
1893 const Weight prev_weight = task->GetWeight();
1894
1895 if (prev_weight < weight)
1896 {
1897 task->SetCurrentWeight(weight);
1898 m_strategy.OnTaskWeightChange(task, prev_weight);
1899 }
1900 }
1901 }
static constexpr ITask * GetUserTaskFromTid(TId task_id) noexcept
Get task instance from its identifier.
Definition stk_arch.h:532
KernelTask * FindTaskByUserTask(const ITask *user_task)
Find kernel task by the bound ITask instance.
Definition stk.h:1487

◆ 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 1903 of file stk.h.

1904 {
1907
1909 STK_ASSERT(task != nullptr);
1910
1911 const Weight prev_weight = task->GetWeight();
1912
1913 // restore to original or boost from wait objects
1914 task->SetCurrentWeight(sobj != nullptr ? sobj->FindWeightHigherThan(task->GetWeight()) : NO_WEIGHT);
1915
1916 m_strategy.OnTaskWeightChange(task, prev_weight);
1917 }

◆ 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 STATE_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 1594 of file stk.h.

1595 {
1596 STK_ASSERT(m_strategy.GetSize() != 0);
1597
1598 // iterate tasks and generate OnTaskSleep for a strategy for all initially sleeping tasks
1600 {
1601 for (size_t i = 0U; i < TASKS_MAX; ++i)
1602 {
1603 KernelTask *const task = &m_task_storage[i];
1604
1605 if (task->IsSleeping())
1606 {
1607 if ((task->m_state & KernelTask::STATE_SLEEP_PENDING) != 0U)
1608 {
1610
1611 // notify strategy that task is sleeping
1612 m_strategy.OnTaskSleep(task);
1613 }
1614 }
1615 }
1616 }
1617
1618 // get initial state and first task
1619 {
1621
1622 KernelTask *next = nullptr;
1624
1625 // expecting only SLEEPING or SWITCHING states
1627
1629 {
1630 m_task_now = next;
1631 active = next->GetUserStackPtr();
1632
1634 {
1635 next->HrtOnSwitchedIn();
1636 }
1637 }
1638 else
1640 {
1642 active = &m_sleep_trap[0].stack;
1643 }
1644 else
1645 {
1646 // unexpected state
1648 }
1649 }
1650
1651 // is in running state
1653
1654 #if STK_SEGGER_SYSVIEW
1656 #endif
1657 }
static __stk_forceinline void STK_KERNEL_PANIC(stk::EKernelPanicId id)
Called when the kernel detects an unrecoverable internal fault.
Definition stk_arch.h:75
EFsmState GetNewFsmState(KernelTask *&next)
Get new FSM state.
Definition stk.h:2135
@ STATE_SLEEP_PENDING
Task called Sleep/SleepUntil/Yield; strategy's OnTaskSleep() will be invoked on the next tick (sleep-...
Definition stk.h:132

◆ 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 STATE_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 1664 of file stk.h.

1665 {
1667 {
1669
1670 // is in stopped state, i.e. is ready to Start() again
1672 }
1673 }

◆ 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 1858 of file stk.h.

1859 {
1860 // toggle kernel state
1861 if (suspended)
1862 {
1863 if (m_kstate == KSTATE_RUNNING)
1864 {
1866 }
1867 }
1868 else
1869 {
1870 if (m_kstate == KSTATE_SUSPENDED)
1871 {
1873 }
1874 }
1875
1876 // force yield for a currently active task
1877 if (!m_task_now->IsSleeping())
1878 {
1879 m_task_now->ScheduleSleep(YIELD_TICKS);
1880 }
1881 }
static constexpr Timeout YIELD_TICKS
Ticks to yield.
Definition stk.h:1333

◆ 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 1791 of file stk.h.

1792 {
1794 {
1796 STK_ASSERT(task != nullptr);
1797
1798 // notify kernel to execute removal
1799 task->ScheduleRemoval();
1800 }
1801 else
1802 {
1803 // kernel operating mode must be KERNEL_DYNAMIC for tasks to be able to exit
1805 }
1806 }
KernelTask * FindTaskByStack(const Stack *stack)
Find kernel task by the bound Stack instance.
Definition stk.h:1508

◆ 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 1723 of file stk.h.

1724 {
1726 STK_ASSERT(task != nullptr);
1727
1728 // make change to HRT state and sleep time atomic
1729 {
1731
1733 {
1734 task->HrtOnWorkCompleted();
1735 }
1736
1737 if (ticks > 0)
1738 {
1739 task->ScheduleSleep(ticks);
1740 }
1741 }
1742
1743 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
1744 task->BusyWaitWhileSleeping();
1745 }

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:

◆ OnTaskSleepCancel()

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

Definition at line 1777 of file stk.h.

1778 {
1780 if (task != nullptr)
1781 {
1783
1784 if (task->IsSleeping())
1785 {
1786 task->Wake();
1787 }
1788 }
1789 }

◆ 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 1747 of file stk.h.

1748 {
1750 STK_ASSERT(task != nullptr);
1751
1752 bool result = true;
1753
1754 // make change to HRT state and sleep time atomic
1755 {
1757
1758 // calculate signed delta (handles wrap-around correctly)
1759 const Ticks delta = timestamp - m_service.m_ticks;
1760
1761 if (delta > 0)
1762 {
1764 task->ScheduleSleep(static_cast<Timeout>(Min(delta, infinite_ticks)));
1765 }
1766 else
1767 {
1768 result = false; // deadline already hit or passed
1769 }
1770 }
1771
1772 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
1773 task->BusyWaitWhileSleeping();
1774 return result;
1775 }

◆ 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 1718 of file stk.h.

1719 {
1721 }
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:1723

◆ 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 1808 of file stk.h.

1809 {
1811 {
1812 STK_ASSERT(timeout != 0); // API contract: caller must not be in ISR
1813 STK_ASSERT(sync_obj != nullptr); // API contract: ISyncObject instance must be provided
1814 STK_ASSERT(mutex != nullptr); // API contract: IMutex instance must be provided
1815 STK_ASSERT((sync_obj->GetHead() == nullptr) || (sync_obj->GetHead() == &m_sync_list[0]));
1816
1818 STK_ASSERT(task != nullptr);
1819
1820 // configure waiting
1821 task->m_wait_obj->SetupWait(sync_obj, timeout);
1822
1823 // register ISyncObject if not yet
1824 if (sync_obj->GetHead() == nullptr)
1825 {
1826 m_sync_list->LinkBack(sync_obj);
1827 }
1828
1829 // start sleeping infinitely, we rely on a Wake call via WaitObject
1830 task->ScheduleSleep(WAIT_INFINITE);
1831
1832 // unlock mutex locked externally, so that we could wait in a busy-waiting loop
1833 mutex->Unlock();
1834
1835 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
1836 task->BusyWaitWhileSleeping();
1837
1838 // re-lock mutex when returning to the task's execution space
1839 mutex->Lock();
1840
1841 return (task->m_wait_obj->IsTimeout() ? WAIT_RESULT_TIMEOUT : WAIT_RESULT_SIGNAL);
1842 }
1843 else
1844 {
1845 STK_ASSERT(false);
1846 return WAIT_RESULT_FAIL;
1847 }
1848 }
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:2453
static constexpr bool IsSyncMode()
Definition stk.h:2374

◆ 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 1691 of file stk.h.

1696 {
1697 #if !STK_TICKLESS_IDLE
1698 // in non-tickless mode kernel is advancing strictly by 1 tick on every OnTick call
1699 enum { ticks = 1 };
1700 #endif
1701
1702 // advance internal timestamp
1703 m_service.IncrementTicks(ticks);
1704
1705 // consume elapsed and update to ticks to sleep
1706 #if STK_TICKLESS_IDLE
1707 ticks = (
1708 #else
1709 // notify compiler that we ignore a return value of UpdateTasks
1710 STK_UNUSED(
1711 #endif
1713
1714 // decide on a context switch
1715 return UpdateFsmState(idle, active);
1716 }
bool UpdateFsmState(Stack *&idle, Stack *&active)
Update FSM state.
Definition stk.h:2146
Timeout UpdateTasks(const Timeout elapsed_ticks)
Update tasks (sleep, requests).
Definition stk.h:1921

◆ 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 1091 of file stk.h.

1092 {
1094 {
1095 STK_ASSERT(user_task != nullptr);
1097
1099 if (task != nullptr)
1100 {
1102 }
1103 }
1104 else
1105 {
1106 // kernel operating mode must be KERNEL_DYNAMIC for tasks to be able to be removed
1107 STK_ASSERT(false);
1108 }
1109 }
void RemoveTask(ITask *user_task) override
Remove a previously added task from the kernel when it is not started.
Definition stk.h:1091

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 1569 of file stk.h.

1570 {
1571 STK_ASSERT(task != nullptr);
1572
1573 #if STK_SEGGER_SYSVIEW
1574 SEGGER_SYSVIEW_OnTaskTerminate(task->GetUserStackPtr()->tid);
1575 #endif
1576
1577 // notify task about pending exit
1578 task->GetUserTask()->OnExit();
1579
1580 m_strategy.RemoveTask(task);
1581 task->Unbind();
1582 }

◆ 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 1463 of file stk.h.

1464 {
1465 KernelTask *const caller = FindTaskBySP(m_platform.GetCallerSP());
1466 STK_ASSERT(caller != nullptr);
1467
1468 typename KernelTask::AddTaskRequest req = { .user_task = user_task };
1469 caller->m_srt[0].add_task_req = &req;
1470
1471 // notify kernel
1473
1474 // switch out and wait for completion (due to context switch request could be processed here)
1475 if (caller->m_srt[0].add_task_req != nullptr)
1476 {
1477 m_service.SwitchToNext();
1478 }
1479
1480 STK_ASSERT(caller->m_srt[0].add_task_req == nullptr);
1481 }
void ScheduleAddTask()
Signal the kernel to process a pending AddTask request on the next tick.
Definition stk.h:2343
Payload for an in-flight AddTask() request issued by a running task.
Definition stk.h:144

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.

Implements stk::IKernel.

Definition at line 1181 of file stk.h.

1182 {
1183 STK_ASSERT(user_task != nullptr);
1184
1185 // avoid race with OnTick
1187
1189 STK_ASSERT(task != nullptr);
1190
1191 if (task->IsSleeping())
1192 {
1193 task->Wake();
1194 }
1195 }

◆ 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 and emits a full memory fence so the ISR-side tick handler observes the flag without delay.

Definition at line 2343 of file stk.h.

2344 {
2347 }

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 1116 of file stk.h.

1117 {
1119 {
1120 STK_ASSERT(user_task != nullptr);
1122
1124
1126 if (task != nullptr)
1127 {
1128 task->ScheduleRemoval();
1129 }
1130 }
1131 else
1132 {
1133 // kernel operating mode must be KERNEL_DYNAMIC for tasks to be able to be removed
1134 STK_ASSERT(false);
1135 }
1136 }

◆ 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 1253 of file stk.h.

1254 {
1256
1257 // stacks of the traps must be re-initilized on every subsequent Start
1258 InitTraps();
1259
1260 // start tracing
1261 #if STK_SEGGER_SYSVIEW
1263 for (size_t i = 0U; i < TASKS_MAX; ++i)
1264 {
1266 if (task->IsBusy())
1267 {
1269 }
1270 }
1271 #endif
1272
1273 m_platform.Start();
1274 }
void InitTraps()
Initialize stack of the traps.
Definition stk.h:1345

◆ 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 2308 of file stk.h.

2309 {
2310 STK_UNUSED(now);
2312
2314 {
2315 // dynamic tasks are not supported if main processes's stack memory is not provided in Start()
2316 STK_ASSERT(m_exit_trap[0].stack.SP != 0);
2317
2318 idle = nullptr;
2319 active = &m_exit_trap[0].stack;
2320
2321 m_task_now = nullptr;
2322
2323 m_platform.Stop();
2324 }
2325 else
2326 {
2329 }
2330
2331 return false;
2332 }

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 2273 of file stk.h.

2274 {
2276
2277 STK_ASSERT(now != nullptr);
2278 STK_ASSERT(m_sleep_trap[0].stack.SP != 0);
2279
2280 idle = now->GetUserStackPtr();
2281 active = &m_sleep_trap[0].stack;
2282
2284
2285 #if STK_SEGGER_SYSVIEW
2286 SEGGER_SYSVIEW_OnTaskStopReady(now->GetUserStackPtr()->tid, TRACE_EVENT_SLEEP);
2287 #endif
2288
2290 {
2291 if (!now->IsPendingRemoval())
2292 {
2293 now->HrtOnSwitchedOut();
2294 }
2295 }
2296
2297 return true; // switch context
2298 }

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 2189 of file stk.h.

2190 {
2191 STK_ASSERT(now != nullptr);
2192 STK_ASSERT(next != nullptr);
2193
2194 bool switch_context = false;
2195
2196 // if equal: do not switch context because task did not change
2197 if (next != now)
2198 {
2199 idle = now->GetUserStackPtr();
2200 active = next->GetUserStackPtr();
2201
2202 // if stack memory is exceeded these assertions will be hit
2203 if (now->IsBusy())
2204 {
2205 // current task could exit, thus we check it with IsBusy to avoid referencing nullptr returned by GetUserTask()
2206 STK_ASSERT(now->GetUserTask()->GetStack()[0] == STK_STACK_MEMORY_FILLER);
2207 }
2208 STK_ASSERT(next->GetUserTask()->GetStack()[0] == STK_STACK_MEMORY_FILLER);
2209
2210 m_task_now = next;
2211
2213 {
2214 if (now->m_hrt[0].done)
2215 {
2216 now->HrtOnSwitchedOut();
2217 next->HrtOnSwitchedIn();
2218 }
2219 }
2220
2221 #if STK_SEGGER_SYSVIEW
2222 SEGGER_SYSVIEW_OnTaskStopReady(now->GetUserStackPtr()->tid, TRACE_EVENT_SWITCH);
2223 SEGGER_SYSVIEW_OnTaskStartReady(next->GetUserStackPtr()->tid);
2224 #endif
2225
2226 switch_context = true;
2227 }
2228
2229 return switch_context;
2230 }

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 2239 of file stk.h.

2240 {
2241 STK_UNUSED(now);
2242
2243 STK_ASSERT(next != nullptr);
2244
2245 idle = &m_sleep_trap[0].stack;
2246 active = next->GetUserStackPtr();
2247
2248 // if stack memory is exceeded these assertions will be hit
2250 STK_ASSERT(next->GetUserTask()->GetStack()[0] == STK_STACK_MEMORY_FILLER);
2251
2252 m_task_now = next;
2253
2254 #if STK_SEGGER_SYSVIEW
2255 SEGGER_SYSVIEW_OnTaskStartReady(next->GetUserStackPtr()->tid);
2256 #endif
2257
2259 {
2260 next->HrtOnSwitchedIn();
2261 }
2262
2263 return true; // switch context
2264 }

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 1144 of file stk.h.

1145 {
1146 STK_ASSERT(user_task != nullptr);
1147
1148 bool self = false;
1149
1150 // avoid race with OnTick
1151 {
1153
1155 STK_ASSERT(task != nullptr);
1156
1157 // only suspend if the task is currently awake: if it is already sleeping
1158 // (e.g. blocked on a mutex or timed Sleep), do not overwrite m_time_sleep,
1159 // that would corrupt the original sleep state and, for sync-object waits,
1160 // would interfere with WaitObject::Tick()
1161 suspended = !task->IsSleeping();
1162 if (suspended == true)
1163 {
1164 task->ScheduleSleep(WAIT_INFINITE);
1165
1166 // check if suspending self
1167 self = (task == m_task_now);
1168 }
1169 }
1170
1171 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
1172 if (self)
1173 {
1174 m_task_now->BusyWaitWhileSleeping();
1175 }
1176 }

◆ 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 2146 of file stk.h.

2147 {
2148 KernelTask *const now = m_task_now, *next = nullptr;
2149 bool switch_context = false;
2150
2152
2153 switch (new_state)
2154 {
2158 break;
2159 case FSM_STATE_SLEEPING:
2162 break;
2163 case FSM_STATE_WAKING:
2166 break;
2167 case FSM_STATE_EXITING:
2170 break;
2171 case FSM_STATE_NONE:
2172 break; // valid intermittent non-persisting state: no-transition
2173 case FSM_STATE_MAX:
2174 default: // invalid state value
2176 break;
2177 }
2178
2179 return switch_context;
2180 }
EFsmState
Finite-state machine (FSM) state. Encodes what the kernel is currently doing between two consecutive ...
Definition stk.h:1305
bool StateWake(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Wakes up after sleeping.
Definition stk.h:2239
bool StateExit(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Exits from scheduling.
Definition stk.h:2308
bool StateSwitch(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Switches contexts.
Definition stk.h:2189
bool StateSleep(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Enters into a sleeping mode.
Definition stk.h:2273

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:

◆ 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 2043 of file stk.h.

2044 {
2046
2047 while (itr != nullptr)
2048 {
2049 ISyncObject::ListEntryType *const next = itr->GetNext();
2050
2052 {
2053 m_sync_list->Unlink(itr);
2054 }
2055
2056 itr = next;
2057 }
2058 }

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 2062 of file stk.h.

2063 {
2064 // process AddTask requests coming from tasks (KERNEL_DYNAMIC mode only, KERNEL_HRT is
2065 // excluded as we assume that HRT tasks must be known to the kernel before a Start())
2067 {
2068 // process serialized AddTask request made from another active task, requesting process
2069 // is currently waiting due to SwitchToNext()
2070 if ((m_request & REQ_ADD_TASK) != 0U)
2071 {
2073
2074 for (size_t i = 0U; i < TASKS_MAX; ++i)
2075 {
2076 KernelTask *const task = &m_task_storage[i];
2077
2078 if (task->m_srt[0].add_task_req != nullptr)
2079 {
2080 AllocateAndAddNewTask(task->m_srt[0].add_task_req->user_task);
2081
2082 task->m_srt[0].add_task_req = nullptr;
2084 }
2085 }
2086 }
2087 }
2088 }

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 1921 of file stk.h.

1922 {
1923 // sync objects are updated before UpdateTaskRequest which may add a new object (newly added object must become 1 tick older)
1925 {
1927 }
1928
1929 if (m_request != REQ_NONE)
1930 {
1932 }
1933
1935 }
void UpdateTaskRequest()
Update pending task requests.
Definition stk.h:2062
Timeout UpdateTaskState(const Timeout elapsed_ticks)
Update task state: process removals, advance sleep timers, and track HRT durations.
Definition stk.h:1946
void UpdateSyncObjects(const Timeout elapsed_ticks)
Update synchronization objects.
Definition stk.h:2043

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, 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.

Definition at line 1946 of file stk.h.

1947 {
1949
1950 for (size_t i = 0U; i < TASKS_MAX; ++i)
1951 {
1952 KernelTask *const task = &m_task_storage[i];
1953
1954 if (task->IsSleeping())
1955 {
1957 {
1958 // task is pending removal, wait until it is switched out
1959 if (task->IsPendingRemoval())
1960 {
1961 const size_t tasks_left = m_strategy.GetSize();
1962
1963 if ((task != m_task_now) ||
1964 ((tasks_left == 1U) && (m_fsm_state == FSM_STATE_SLEEPING)))
1965 {
1967 continue;
1968 }
1969 }
1970 }
1971
1972 // deliver sleep event to strategy
1973 // note: only currently scheduled task can be pending to sleep
1975 {
1976 if ((task->m_state & KernelTask::STATE_SLEEP_PENDING) != 0U)
1977 {
1979
1980 // notify strategy that task is sleeping
1981 m_strategy.OnTaskSleep(task);
1982 }
1983 }
1984
1985 // advance sleep time by a tick
1986 task->m_time_sleep += elapsed_ticks;
1987
1988 // deliver sleep event to strategy
1990 {
1991 // notify strategy that task woke up
1992 if (!task->IsSleeping())
1993 {
1994 m_strategy.OnTaskWake(task);
1995 }
1996 }
1997 }
1998 else
1999 {
2001 {
2002 // in HRT mode we trace how long task spent in active state (doing some work)
2003 if (task->IsBusy())
2004 {
2005 task->m_hrt[0].duration += elapsed_ticks;
2006
2007 // check if deadline is missed (HRT failure)
2008 if (task->HrtIsDeadlineMissed(task->m_hrt[0].duration))
2009 {
2010 // report deadline overrun to a strategy which supports overrun recovery
2012 {
2013 if (!m_strategy.OnTaskDeadlineMissed(task))
2014 {
2015 // report failure if it could not be recovered by the scheduling strategy
2016 task->HrtHardFailDeadline(&m_platform);
2017 }
2018 }
2019 else
2020 {
2021 task->HrtHardFailDeadline(&m_platform);
2022 }
2023 }
2024 }
2025 }
2026 }
2027
2028 // get the number ticks the driver has to keep CPU in Idle
2030 {
2031 if ((sleep_ticks > 1) && task->IsBusy())
2032 {
2033 sleep_ticks = task->GetSleepTicks(sleep_ticks);
2034 }
2035 }
2036 }
2037
2038 return sleep_ticks;
2039 }
Timeout GetInitialSleepTicks()
static constexpr bool IsTicklessMode()
Definition stk.h:2375

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:

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 2449 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 2455 of file stk.h.

2455 {
2456 // FSM_EVENT_SWITCH FSM_EVENT_SLEEP FSM_EVENT_WAKE FSM_EVENT_EXIT
2461 };

◆ 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 2450 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 2452 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

Platform driver (SysTick, PendSV, context switch implementation).

Definition at line 2444 of file stk.h.

◆ 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 2451 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 2443 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 2448 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 2445 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 2453 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 2446 of file stk.h.

◆ 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 2447 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 948 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 = 2
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 1333 of file stk.h.


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