SuperTinyKernel™ RTOS 1.06.0
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 Reference

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  EState : uint8_t {
  STATE_INACTIVE = 0 ,
  STATE_READY ,
  STATE_RUNNING ,
  STATE_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 REQUEST_NONE by Initialize()).
 ~Kernel ()
 Destructor.
void Initialize (uint32_t resolution_us=PERIODICITY_DEFAULT)
 Initialize kernel.
void AddTask (ITask *user_task)
 Register task for a soft real-time (SRT) scheduling.
void AddTask (ITask *user_task, Timeout periodicity_tc, Timeout deadline_tc, Timeout start_delay_tc)
 Register a task for hard real-time (HRT) scheduling.
void RemoveTask (ITask *user_task)
 Remove a previously added task from the kernel before Start().
void ScheduleTaskRemoval (ITask *user_task)
 Schedule task removal from scheduling (exit).
void SuspendTask (ITask *user_task, bool &suspended)
 Suspend task.
void ResumeTask (ITask *user_task)
 Resume task.
size_t EnumerateTasks (ITask **user_tasks, const size_t max_size)
 Enumerate tasks.
void Start ()
 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 ()
 Get platform driver instance owned by this kernel.
ITaskSwitchStrategyGetSwitchStrategy ()
 Get task-switching strategy instance owned by this kernel.
EState GetState () const
 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 uint32_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 {
  REQUEST_NONE = 0 ,
  REQUEST_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 *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)
 Called by platform driver immediately after a scheduler start (first tick).
void OnStop ()
 Called by the platform driver after a scheduler stop (all tasks have exited).
bool OnTick (Stack *&idle, Stack *&active)
 Process one scheduler tick. Called from the platform timer/tick ISR.
void OnTaskSwitch (Word caller_SP)
 Called by Thread process (via IKernelService::SwitchToNext) to switch to a next task.
void OnTaskSleep (Word caller_SP, Timeout ticks)
 Called by Thread process (via IKernelService::Sleep) for exclusion of the calling process from scheduling (sleeping).
void OnTaskSleepUntil (Word caller_SP, Ticks timestamp)
 Called by Thread process (via IKernelService::SleepUntil) for exclusion of the calling process from scheduling (sleeping).
void OnTaskExit (Stack *stack)
 Called from the Thread process when task finished (its Run function exited by return).
IWaitObjectOnTaskWait (Word caller_SP, ISyncObject *sync_obj, IMutex *mutex, Timeout timeout)
 Called from the Thread process when task needs to wait.
TId OnGetTid (Word caller_SP)
 Called from the Thread process when for getting task/thread id of the process.
void OnSuspend (bool suspended)
 Called from the Thread process to suspend scheduling.
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 bool IsStaticMode ()
static bool IsDynamicMode ()
static bool IsHrtMode ()
static bool IsSyncMode ()
static 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 [((((TMode) &(KERNEL_DYNAMIC)) !=0U) ?(1) :(0))]
 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 EState m_state
 Current kernel state.
SyncObjectList m_sync_list [((((TMode) &(KERNEL_SYNC)) !=0U) ?(1) :(0))]
 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:81
void Initialize(uint32_t resolution_us=PERIODICITY_DEFAULT)
Initialize kernel.
Definition stk.h:832
void Start()
Start the scheduler. This call does not return until all tasks have exited (KERNEL_DYNAMIC mode) or i...
Definition stk.h:1050
void AddTask(ITask *user_task)
Register task for a soft real-time (SRT) scheduling.
Definition stk.h:859

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 93 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 87 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 2097 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 2059 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 1113 of file stk.h.

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

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

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

◆ 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
REQUEST_NONE 

No pending requests.

REQUEST_ADD_TASK 

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

Definition at line 99 of file stk.h.

100 {
101 REQUEST_NONE = 0,
102 REQUEST_ADD_TASK = (1 << 0)
103 };
@ REQUEST_NONE
No pending requests.
Definition stk.h:101
@ REQUEST_ADD_TASK
An AddTask() request is pending from a running task (KERNEL_DYNAMIC only).
Definition stk.h:102

◆ EState

enum stk::IKernel::EState : uint8_t
inherited

Kernel state.

Enumerator
STATE_INACTIVE 

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

STATE_READY 

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

STATE_RUNNING 

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

STATE_SUSPENDED 

Scheduling is suspended with IKernelService::Suspend().

Definition at line 966 of file stk_common.h.

967 {
968 STATE_INACTIVE = 0,
972 };
@ STATE_INACTIVE
Not ready, IKernel::Initialize() must be called.
Definition stk_common.h:968
@ STATE_READY
Ready to start, IKernel::Start() must be called.
Definition stk_common.h:969
@ STATE_SUSPENDED
Scheduling is suspended with IKernelService::Suspend().
Definition stk_common.h:971
@ STATE_RUNNING
Initialized and running, IKernel::Start() was called successfully.
Definition stk_common.h:970

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

800 {
801 #ifdef _DEBUG
802 // TPlatform must inherit IPlatform
805
806 // TStrategy must inherit ITaskSwitchStrategy
809 #endif
810
811 #if !STK_TICKLESS_IDLE
813 "STK_TICKLESS_IDLE must be defined to 1 for KERNEL_TICKLESS");
814 #endif
815 }
#define STK_UNUSED(X)
Explicitly marks a variable as unused to suppress compiler warnings.
Definition stk_defs.h:524
#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:350
volatile uint8_t m_request
Bitmask of pending ERequest flags from running tasks. Written by tasks, read/cleared by UpdateTaskReq...
Definition stk.h:2107
TStrategy m_strategy
Task-switching strategy (determines which task runs next).
Definition stk.h:2101
volatile EState m_state
Current kernel state.
Definition stk.h:2108
SleepTrapStack m_sleep_trap[1]
Sleep trap (always present): executed when all tasks are sleeping.
Definition stk.h:2104
ExitTrapStack m_exit_trap[((((TMode) &(KERNEL_DYNAMIC)) !=0U) ?(1) :(0))]
Exit trap: zero-size in KERNEL_STATIC mode; one entry in KERNEL_DYNAMIC mode.
Definition stk.h:2105
TaskStorageType m_task_storage
Static pool of TSize KernelTask slots (free slots have m_user == nullptr).
Definition stk.h:2103
KernelTask * m_task_now
Currently executing task, or nullptr before Start() or after all tasks exit.
Definition stk.h:2102
TPlatform m_platform
Platform driver (SysTick, PendSV, context switch implementation).
Definition stk.h:2100
EFsmState m_fsm_state
Current FSM state. Drives context-switch decision on every tick.
Definition stk.h:2106

◆ ~Kernel()

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

Destructor.

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

Definition at line 820 of file stk.h.

821 {}

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

1211 {
1212 #if STK_SEGGER_SYSVIEW
1213 // start tracing new task
1214 SEGGER_SYSVIEW_OnTaskCreate(task->GetUserStack()->tid);
1215 if (IsStarted())
1217 #endif
1218
1219 m_strategy.AddTask(task);
1220 }
bool IsStarted() const
Check whether scheduler is currently running.
Definition stk.h:1075

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::AllocateAndAddNewTask(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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)
inlinevirtual

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

860 {
861 if (!IsHrtMode())
862 {
863 STK_ASSERT(user_task != nullptr);
865
866 // when started the operation must be serialized by switching out from processing until
867 // kernel processes this request
868 if (IsStarted())
869 {
870 if (IsDynamicMode())
871 {
873 }
874 else
875 {
876 STK_ASSERT(false);
877 }
878 }
879 else
880 {
882 }
883 }
884 else
885 {
886 STK_ASSERT(false);
887 }
888 }
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:330
void RequestAddTask(ITask *user_task)
Request to add new task.
Definition stk.h:1256
static bool IsHrtMode()
Definition stk.h:2033
static bool IsDynamicMode()
Definition stk.h:2032
void AllocateAndAddNewTask(ITask *user_task)
Allocate new instance of KernelTask and add it into the scheduling process.
Definition stk.h:1226
bool IsInitialized() const
Check whether Initialize() has been called and completed successfully.
Definition stk.h:1997

◆ 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 )
inlinevirtual

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

899 {
900 if (IsHrtMode())
901 {
902 STK_ASSERT(user_task != nullptr);
905
907 }
908 else
909 {
910 STK_ASSERT(false);
911 }
912 }
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:1242

◆ 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.
Returns
Kernel task.

Definition at line 1226 of file stk.h.

1227 {
1229 STK_ASSERT(task != nullptr);
1230
1232 }
KernelTask * AllocateNewTask(ITask *user_task)
Allocate new instance of KernelTask.
Definition stk.h:1174
void AddKernelTask(KernelTask *task)
Add kernel task to the scheduling strategy.
Definition stk.h:1210
Internal per-slot kernel descriptor that wraps a user ITask instance.
Definition stk.h:117

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::AddTask(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1174 of file stk.h.

1175 {
1176 // look for a free kernel task
1177 KernelTask *new_task = nullptr;
1178 for (uint32_t i = 0U; i < TASKS_MAX; ++i)
1179 {
1181 if (task->IsBusy())
1182 {
1183 // avoid task collision
1184 STK_ASSERT(task->m_user != user_task);
1185
1186 // avoid stack collision
1187 STK_ASSERT(task->m_user->GetStack() != user_task->GetStack());
1188 }
1189 else
1190 if (new_task == nullptr)
1191 {
1192 new_task = task;
1193 #if defined(NDEBUG) && !defined(_STK_ASSERT_REDIRECT)
1194 break; // break if assertions are inactive and do not try to validate collision with existing tasks
1195 #endif
1196 }
1197 }
1198
1199 // if nullptr - exceeded max supported kernel task count, application design failure
1200 STK_ASSERT(new_task != nullptr);
1201
1202 new_task->Bind(&m_platform, user_task);
1203
1204 return new_task;
1205 }
static constexpr uint32_t TASKS_MAX
Maximum number of concurrently registered tasks. Fixed at compile time. Exceeding this limit in AddTa...
Definition stk.h:789

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

Here is the caller graph for this function:

◆ EnumerateTasks()

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

Enumerate tasks.

Parameters
[in,out]user_tasksPointer to the array for ITask pointers.
[in]max_sizeMax size of the provided array.
Returns
Number of tasks in the array.

Implements stk::IKernel.

Definition at line 1025 of file stk.h.

1026 {
1027 size_t count = 0U;
1028
1029 // avoid race with OnTick
1031
1033 {
1035 if (task->IsBusy())
1036 user_tasks[count++] = task->GetUserTask();
1037 }
1038
1039 return count;
1040 }

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

Definition at line 1062 of file stk_common.h.

1063 {
1064 STK_STATIC_ASSERT(TMaxCount > 0);
1065
1066 ITask *tasks[TMaxCount] = {};
1067 size_t i = 0, count = EnumerateTasks(tasks, TMaxCount);
1068
1069 while (i < count)
1070 {
1071 if (!callback(tasks[i++]))
1072 break;
1073 }
1074
1075 return i;
1076 }
#define STK_STATIC_ASSERT(X)
Compile-time assertion. Produces a compilation error if X is false.
Definition stk_defs.h:367
virtual size_t EnumerateTasks(ITask **user_tasks, size_t max_size)=0
Enumerate 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 1765 of file stk.h.

1766 {
1768 KernelTask *itr = nullptr;
1769
1770 // check if no tasks left in KERNEL_DYNAMIC mode and exit, if KERNEL_DYNAMIC is not
1771 // set then 'is_empty' will always be false
1772 bool is_empty = IsDynamicMode() && (m_strategy.GetSize() == 0U);
1773
1774 if (!is_empty)
1775 {
1776 // MISRA 5-2-3 deviation: GetNext/GetFirst returns IKernelTask*, all objects in
1777 // the strategy pool are KernelTask instances - downcast is guaranteed safe.
1778 itr = static_cast<KernelTask *>(m_strategy.GetNext());
1779
1780 // sleep-aware strategy returns nullptr if no active tasks available, start sleeping
1781 if (itr == nullptr)
1782 {
1784 }
1785 else
1786 {
1787 // strategy must provide active-only task
1788 STK_ASSERT(!itr->IsSleeping());
1789
1790 // if was sleeping, process wake event first
1792 }
1793 }
1794
1795 next = itr;
1796 return type;
1797 }
EFsmEvent
Finite-state machine (FSM) event. Computed by FetchNextEvent() each tick based on strategy output and...
Definition stk.h:1114

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1312 of file stk.h.

1313 {
1314 STK_ASSERT(m_task_now != nullptr);
1315
1316 if (m_task_now->IsMemoryOfSP(SP))
1317 return m_task_now;
1318
1319 for (uint32_t i = 0U; i < TASKS_MAX; ++i)
1320 {
1322
1323 // skip finished tasks (applicable only for KERNEL_DYNAMIC mode)
1324 if (IsDynamicMode() && !task->IsBusy())
1325 continue;
1326
1327 if (task->IsMemoryOfSP(SP))
1328 return task;
1329 }
1330
1331 return nullptr;
1332 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnGetTid(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSleep(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSleepUntil(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskWait(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1296 of file stk.h.

1297 {
1298 for (uint32_t i = 0U; i < TASKS_MAX; ++i)
1299 {
1301 if (task->GetUserStack() == stack)
1302 return task;
1303 }
1304
1305 return nullptr;
1306 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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

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

1807 {
1810 }
static bool IsValidFsmState(EFsmState state)
Check if FSM state is valid.
Definition stk.h:1132
const EFsmState m_fsm[FSM_STATE_MAX][FSM_EVENT_MAX]
Definition stk.h:2111
EFsmEvent FetchNextEvent(KernelTask *&next)
Fetch next event for the FSM.
Definition stk.h:1765

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnStart(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 ( )
inlinevirtual

Get platform driver instance owned by this kernel.

Returns
Pointer to the internal TPlatform cast to IPlatform*.

Implements stk::IKernel.

Definition at line 1083 of file stk.h.

1083{ return &m_platform; }

◆ GetState()

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

Get kernel state.

Implements stk::IKernel.

Definition at line 1092 of file stk.h.

1092{ return m_state; }

◆ GetSwitchStrategy()

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

Get task-switching strategy instance owned by this kernel.

Returns
Pointer to the internal TStrategy cast to ITaskSwitchStrategy*.

Implements stk::IKernel.

Definition at line 1088 of file stk.h.

1088{ 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).
Returns
Kernel task.

Definition at line 1242 of file stk.h.

1243 {
1245 STK_ASSERT(task != nullptr);
1246
1248
1250 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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)
inlinevirtual

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

833 {
837
838 // reinitialize key state variables
839 m_task_now = nullptr;
842
843 m_service.Initialize(&m_platform);
844
845 m_platform.Initialize(this, &m_service, resolution_us, (IsDynamicMode() ? &m_exit_trap[0].stack : nullptr));
846
847 // now ready to Start()
849 }
KernelService m_service
Kernel service singleton exposed to running tasks via IKernelService::GetInstance().
Definition stk.h:2099

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

1141 {
1142 // init stack for a Sleep trap
1143 {
1145
1147 sleep.stack.mode = ACCESS_PRIVILEGED;
1148 #if STK_NEED_TASK_ID
1149 sleep.stack.tid = SYS_TASK_ID_SLEEP;
1150 #endif
1151
1152 m_platform.InitStack(STACK_SLEEP_TRAP, &sleep.stack, &wrapper, nullptr);
1153 }
1154
1155 // init stack for an Exit trap
1156 if (IsDynamicMode())
1157 {
1159
1161 exit.stack.mode = ACCESS_PRIVILEGED;
1162 #if STK_NEED_TASK_ID
1163 exit.stack.tid = SYS_TASK_ID_EXIT;
1164 #endif
1165
1166 m_platform.InitStack(STACK_EXIT_TRAP, &exit.stack, &wrapper, nullptr);
1167 }
1168 }
StackMemoryWrapper< STACK_SIZE_MIN > ExitTrapStackMemory
Stack memory wrapper type for the exit trap.
Definition stk.h:93
StackMemoryWrapper<(32U)> SleepTrapStackMemory
Stack memory wrapper type for the sleep trap.
Definition stk.h:87
Storage bundle for the sleep trap: a Stack descriptor paired with its backing memory.
Definition stk.h:2069
Storage bundle for the exit trap: a Stack descriptor paired with its backing memory.
Definition stk.h:2085

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsDynamicMode ( )
inlinestaticprotected

Definition at line 2032 of file stk.h.

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

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::AddTask(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::FetchNextEvent(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::FindTaskBySP(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::Initialize(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::InitTraps(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnStop(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskExit(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::RemoveTask(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::RequestAddTask(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::ScheduleTaskRemoval(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::StateExit(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTaskRequest(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsHrtMode ( )
inlinestaticprotected

Definition at line 2033 of file stk.h.

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

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::AddTask(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnStart(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSleep(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::OnTaskSleepUntil(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelTask::ScheduleRemoval(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelService::Sleep(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelService::SleepUntil(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::StateSleep(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::StateSwitch(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::StateWake(), stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelTask::Unbind(), stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTaskRequest(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::UpdateTaskState().

Here is the caller graph for this function:

◆ IsInitialized()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsInitialized ( ) const
inlineprotected

◆ IsStarted()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
bool stk::Kernel< TMode, TSize, TStrategy, TPlatform >::IsStarted ( ) const
inline

◆ IsStaticMode()

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

Definition at line 2031 of file stk.h.

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

◆ IsSyncMode()

◆ IsTicklessMode()

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

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

1133 {
1134 return (state > FSM_STATE_NONE) &&
1135 (state < FSM_STATE_MAX);
1136 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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)
inlineprotectedvirtual

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

1588 {
1590 STK_ASSERT(task != nullptr);
1591
1592 return task->GetTid();
1593 }
KernelTask * FindTaskBySP(Word SP)
Find kernel task for a Stack Pointer (SP).
Definition stk.h:1312

◆ OnStart()

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

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

1364 {
1365 STK_ASSERT(m_strategy.GetSize() != 0);
1366
1367 // iterate tasks and generate OnTaskSleep for a strategy for all initially sleeping tasks
1369 {
1370 for (uint32_t i = 0U; i < TASKS_MAX; ++i)
1371 {
1373
1374 if (task->IsSleeping())
1375 {
1377 {
1379
1380 // notify strategy that task is sleeping
1381 m_strategy.OnTaskSleep(task);
1382 }
1383 }
1384 }
1385 }
1386
1387 // get initial state and first task
1388 {
1390
1391 KernelTask *next = nullptr;
1393
1394 // expecting only SLEEPING or SWITCHING states
1396
1398 {
1399 m_task_now = next;
1400
1401 active = next->GetUserStack();
1402
1403 if (IsHrtMode())
1404 next->HrtOnSwitchedIn();
1405 }
1406 else
1408 {
1409 // MISRA 5-2-3 deviation: GetNext/GetFirst returns IKernelTask*, all objects in
1410 // the strategy pool are KernelTask instances - downcast is guaranteed safe.
1411 m_task_now = static_cast<KernelTask *>(m_strategy.GetFirst());
1412
1413 active = &m_sleep_trap[0].stack;
1414 }
1415 }
1416
1417 // is in running state
1419
1420 #if STK_SEGGER_SYSVIEW
1422 #endif
1423 }
EFsmState GetNewFsmState(KernelTask *&next)
Get new FSM state.
Definition stk.h:1806
@ STATE_SLEEP_PENDING
Task called Sleep/SleepUntil/Yield; strategy's OnTaskSleep() will be invoked on the next tick (sleep-...
Definition stk.h:128

◆ OnStop()

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

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

1431 {
1432 if (IsDynamicMode())
1433 {
1435
1436 // is in stopped state, i.e. is ready to Start() again
1438 }
1439 }

◆ OnSuspend()

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

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

1596 {
1597 if (suspended)
1599 else
1601 }

◆ OnTaskExit()

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

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

1531 {
1532 if (IsDynamicMode())
1533 {
1535 STK_ASSERT(task != nullptr);
1536
1537 // notify kernel to execute removal
1538 task->ScheduleRemoval();
1539 }
1540 else
1541 {
1542 // kernel operating mode must be KERNEL_DYNAMIC for tasks to be able to exit
1544 }
1545 }
#define STK_KERNEL_PANIC(id)
Called when the kernel detects an unrecoverable internal fault.
Definition stk_arch.h:63
KernelTask * FindTaskByStack(const Stack *stack)
Find kernel task by the bound Stack instance.
Definition stk.h:1296

◆ 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 )
inlineprotectedvirtual

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

1490 {
1492 STK_ASSERT(task != nullptr);
1493
1494 // make change to HRT state and sleep time atomic
1495 {
1497
1498 if (IsHrtMode())
1499 task->HrtOnWorkCompleted();
1500
1501 if (ticks > 0)
1502 task->ScheduleSleep(ticks);
1503 }
1504
1505 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
1506 task->BusyWaitWhileSleeping();
1507 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::OnTaskSleepUntil ( Word caller_SP,
Ticks timestamp )
inlineprotectedvirtual

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

Implements stk::IPlatform::IEventHandler.

Definition at line 1509 of file stk.h.

1510 {
1512
1514 STK_ASSERT(task != nullptr);
1515
1516 // make change to HRT state and sleep time atomic
1517 {
1519
1520 Timeout ticks = Max(static_cast<Timeout>(0), static_cast<Timeout>(timestamp - m_service.m_ticks));
1521
1522 if (ticks > 0)
1523 task->ScheduleSleep(ticks);
1524 }
1525
1526 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
1527 task->BusyWaitWhileSleeping();
1528 }
static constexpr T Max(T a, T b)
Compile-time maximum of two values.
Definition stk_defs.h:541

◆ OnTaskSwitch()

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

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

1485 {
1487 }
static constexpr Timeout YIELD_TICKS
Ticks to yield.
Definition stk.h:1128
void OnTaskSleep(Word caller_SP, Timeout ticks)
Called by Thread process (via IKernelService::Sleep) for exclusion of the calling process from schedu...
Definition stk.h:1489

◆ OnTaskWait()

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

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

1548 {
1549 if (IsSyncMode())
1550 {
1551 STK_ASSERT(timeout != 0); // API contract: caller must not be in ISR
1552 STK_ASSERT(sync_obj != nullptr); // API contract: ISyncObject instance must be provided
1553 STK_ASSERT(mutex != nullptr); // API contract: IMutex instance must be provided
1554 STK_ASSERT((sync_obj->GetHead() == nullptr) || (sync_obj->GetHead() == &m_sync_list[0]));
1555
1557 STK_ASSERT(task != nullptr);
1558
1559 // configure waiting
1560 task->m_wait_obj->SetupWait(sync_obj, timeout);
1561
1562 // register ISyncObject if not yet
1563 if (sync_obj->GetHead() == nullptr)
1564 m_sync_list->LinkBack(sync_obj);
1565
1566 // start sleeping infinitely, we rely on a Wake call via WaitObject
1567 task->ScheduleSleep(WAIT_INFINITE);
1568
1569 // unlock mutex locked externally, so that we could wait in a busy-waiting loop
1570 mutex->Unlock();
1571
1572 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
1573 task->BusyWaitWhileSleeping();
1574
1575 // re-lock mutex when returning to the task's execution space
1576 mutex->Lock();
1577
1578 return task->m_wait_obj;
1579 }
1580 else
1581 {
1582 STK_ASSERT(false);
1583 return nullptr;
1584 }
1585 }
static bool IsSyncMode()
Definition stk.h:2034
SyncObjectList m_sync_list[((((TMode) &(KERNEL_SYNC)) !=0U) ?(1) :(0))]
List of active sync objects. Zero-size (no memory) if KERNEL_SYNC is not set.
Definition stk.h:2109

◆ OnTick()

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

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

1462 {
1463 #if !STK_TICKLESS_IDLE
1464 // in non-tickless mode kernel is advancing strictly by 1 tick on every OnTick call
1465 enum { ticks = 1 };
1466 #endif
1467
1468 // advance internal timestamp
1469 m_service.IncrementTicks(ticks);
1470
1471 // consume elapsed and update to ticks to sleep
1472 #if STK_TICKLESS_IDLE
1473 ticks = (
1474 #else
1475 // notify compiler that we ignore a return value of UpdateTasks
1476 static_cast<void>(
1477 #endif
1479
1480 // decide on a context switch
1481 return UpdateFsmState(idle, active);
1482 }
bool UpdateFsmState(Stack *&idle, Stack *&active)
Update FSM state.
Definition stk.h:1817
Timeout UpdateTasks(const Timeout elapsed_ticks)
Update tasks (sleep, requests).
Definition stk.h:1605

◆ 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)
inlinevirtual

Remove a previously added task from the kernel before Start().

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

923 {
924 if (IsDynamicMode())
925 {
926 STK_ASSERT(user_task != nullptr);
928
930 if (task != nullptr)
932 }
933 else
934 {
935 // kernel operating mode must be KERNEL_DYNAMIC for tasks to be able to be removed
936 STK_ASSERT(false);
937 }
938 }
KernelTask * FindTaskByUserTask(const ITask *user_task)
Find kernel task by the bound ITask instance.
Definition stk.h:1280
void RemoveTask(ITask *user_task)
Remove a previously added task from the kernel before Start().
Definition stk.h:922

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 16U, stk::SwitchStrategyFP32, stk::PlatformDefault >::RemoveTask(), and stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1338 of file stk.h.

1339 {
1340 STK_ASSERT(task != nullptr);
1341
1342 #if STK_SEGGER_SYSVIEW
1343 SEGGER_SYSVIEW_OnTaskTerminate(task->GetUserStack()->tid);
1344 #endif
1345
1346 // notify task about pending exit
1347 task->GetUserTask()->OnExit();
1348
1349 m_strategy.RemoveTask(task);
1350 task->Unbind();
1351 }

◆ RequestAddTask()

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
void stk::Kernel< TMode, TSize, TStrategy, TPlatform >::RequestAddTask ( ITask * 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 1256 of file stk.h.

1257 {
1259
1260 KernelTask *caller = FindTaskBySP(m_platform.GetCallerSP());
1261 STK_ASSERT(caller != nullptr);
1262
1263 typename KernelTask::AddTaskRequest req = { .user_task = user_task };
1264 caller->m_srt[0].add_task_req = &req;
1265
1266 // notify kernel
1268
1269 // switch out and wait for completion (due to context switch request could be processed here)
1270 if (caller->m_srt[0].add_task_req != nullptr)
1271 m_service.SwitchToNext();
1272
1273 STK_ASSERT(caller->m_srt[0].add_task_req == nullptr);
1274 }
void ScheduleAddTask()
Signal the kernel to process a pending AddTask request on the next tick.
Definition stk.h:2003
Payload for an in-flight AddTask() request issued by a running task.
Definition stk.h:140

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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)
inlinevirtual

Resume task.

Parameters
[in]user_taskPointer to the user task to resume.

Implements stk::IKernel.

Definition at line 1006 of file stk.h.

1007 {
1008 STK_ASSERT(user_task != nullptr);
1009
1010 // avoid race with OnTick
1012
1014 STK_ASSERT(task != nullptr);
1015
1016 if (task->IsSleeping())
1017 task->Wake();
1018 }

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

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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)
inlinevirtual

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

946 {
947 if (IsDynamicMode())
948 {
949 STK_ASSERT(user_task != nullptr);
951
953
955 if (task != nullptr)
956 task->ScheduleRemoval();
957 }
958 else
959 {
960 // kernel operating mode must be KERNEL_DYNAMIC for tasks to be able to be removed
961 STK_ASSERT(false);
962 }
963 }

◆ Start()

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

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

1051 {
1053
1054 // stacks of the traps must be re-initilized on every subsequent Start
1055 InitTraps();
1056
1057 // start tracing
1058 #if STK_SEGGER_SYSVIEW
1060 for (uint32_t i = 0U; i < TASKS_MAX; ++i)
1061 {
1063 if (task->IsBusy())
1065 }
1066 #endif
1067
1068 m_platform.Start();
1069 }
void InitTraps()
Initialize stack of the traps.
Definition stk.h:1140

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

1969 {
1970 STK_UNUSED(now);
1972
1973 if (IsDynamicMode())
1974 {
1975 // dynamic tasks are not supported if main processes's stack memory is not provided in Start()
1976 STK_ASSERT(m_exit_trap[0].stack.SP != 0);
1977
1978 idle = nullptr;
1979 active = &m_exit_trap[0].stack;
1980
1981 m_task_now = nullptr;
1982
1983 m_platform.Stop();
1984 }
1985 else
1986 {
1989 }
1990
1991 return false;
1992 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1935 of file stk.h.

1936 {
1938
1939 STK_ASSERT(now != nullptr);
1940 STK_ASSERT(m_sleep_trap[0].stack.SP != 0);
1941
1942 idle = now->GetUserStack();
1943 active = &m_sleep_trap[0].stack;
1944
1945 m_task_now = static_cast<KernelTask *>(m_strategy.GetFirst());
1946
1947 #if STK_SEGGER_SYSVIEW
1949 #endif
1950
1951 if (IsHrtMode())
1952 {
1953 if (!now->IsPendingRemoval())
1954 now->HrtOnSwitchedOut(&m_platform);
1955 }
1956
1957 return true; // switch context
1958 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1857 of file stk.h.

1858 {
1859 STK_ASSERT(now != nullptr);
1860 STK_ASSERT(next != nullptr);
1861
1862 // do not switch context because task did not change
1863 if (next == now)
1864 return false;
1865
1866 idle = now->GetUserStack();
1867 active = next->GetUserStack();
1868
1869 // if stack memory is exceeded these assertions will be hit
1870 if (now->IsBusy())
1871 {
1872 // current task could exit, thus we check it with IsBusy to avoid referencing nullptr returned by GetUserTask()
1873 STK_ASSERT(now->GetUserTask()->GetStack()[0] == STK_STACK_MEMORY_FILLER);
1874 }
1875 STK_ASSERT(next->GetUserTask()->GetStack()[0] == STK_STACK_MEMORY_FILLER);
1876
1877 m_task_now = next;
1878
1879 if ((IsHrtMode()))
1880 {
1881 if (now->m_hrt[0].done)
1882 {
1883 now->HrtOnSwitchedOut(&m_platform);
1884 next->HrtOnSwitchedIn();
1885 }
1886 }
1887
1888 #if STK_SEGGER_SYSVIEW
1890 SEGGER_SYSVIEW_OnTaskStartReady(next->GetUserStack()->tid);
1891 #endif
1892
1893 return true; // switch context
1894 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1903 of file stk.h.

1904 {
1905 STK_UNUSED(now);
1906
1907 STK_ASSERT(next != nullptr);
1908
1909 idle = &m_sleep_trap[0].stack;
1910 active = next->GetUserStack();
1911
1912 // if stack memory is exceeded these assertions will be hit
1914 STK_ASSERT(next->GetUserTask()->GetStack()[0] == STK_STACK_MEMORY_FILLER);
1915
1916 m_task_now = next;
1917
1918 #if STK_SEGGER_SYSVIEW
1919 SEGGER_SYSVIEW_OnTaskStartReady(next->GetUserStack()->tid);
1920 #endif
1921
1922 if ((IsHrtMode()))
1923 next->HrtOnSwitchedIn();
1924
1925 return true; // switch context
1926 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 )
inlinevirtual

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

972 {
973 STK_ASSERT(user_task != nullptr);
974
975 bool self = false;
976 KernelTask *task = nullptr;
977
978 // avoid race with OnTick
979 {
981
983 STK_ASSERT(task != nullptr);
984
985 // only suspend if the task is currently awake: if it is already sleeping
986 // (e.g. blocked on a mutex or timed Sleep), do not overwrite m_time_sleep,
987 // that would corrupt the original sleep state and, for sync-object waits,
988 // would interfere with WaitObject::Tick()
989 if ((suspended = !task->IsSleeping()) == true)
990 {
991 task->ScheduleSleep(WAIT_INFINITE);
992
993 // check if suspending self
994 self = (task == m_task_now);
995 }
996 }
997
998 // note: we do not spin long here, kernel will switch this task out from scheduling on the next tick
999 if (self)
1000 task->BusyWaitWhileSleeping();
1001 }

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

1818 {
1819 KernelTask *now = m_task_now, *next = nullptr;
1820 bool switch_context = false;
1821
1823
1824 switch (new_state)
1825 {
1828 break;
1829 case FSM_STATE_SLEEPING:
1831 break;
1832 case FSM_STATE_WAKING:
1834 break;
1835 case FSM_STATE_EXITING:
1837 break;
1838 case FSM_STATE_NONE:
1839 return switch_context; // valid intermittent non-persisting state: no-transition
1840 case FSM_STATE_MAX:
1841 default: // invalid state value
1843 break;
1844 }
1845
1847 return switch_context;
1848 }
EFsmState
Finite-state machine (FSM) state. Encodes what the kernel is currently doing between two consecutive ...
Definition stk.h:1100
bool StateWake(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Wakes up after sleeping.
Definition stk.h:1903
bool StateExit(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Exits from scheduling.
Definition stk.h:1968
bool StateSwitch(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Switches contexts.
Definition stk.h:1857
bool StateSleep(KernelTask *now, KernelTask *next, Stack *&idle, Stack *&active)
Enters into a sleeping mode.
Definition stk.h:1935

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1709 of file stk.h.

1710 {
1712
1714
1715 while (itr != nullptr)
1716 {
1717 ISyncObject::ListEntryType *next = itr->GetNext();
1718
1719 // MISRA 5-2-3 deviation: GetNext/GetFirst returns ISyncObject*, all objects in
1720 // m_sync_list are ISyncObject instances - downcast is guaranteed safe
1721 if (!static_cast<ISyncObject *>(itr)->Tick(elapsed_ticks))
1722 m_sync_list->Unlink(itr);
1723
1724 itr = next;
1725 }
1726 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1730 of file stk.h.

1731 {
1732 if (m_request == REQUEST_NONE)
1733 return;
1734
1735 // process AddTask requests coming from tasks (KERNEL_DYNAMIC mode only, KERNEL_HRT is
1736 // excluded as we assume that HRT tasks must be known to the kernel before a Start())
1737 if (IsDynamicMode() && !IsHrtMode())
1738 {
1739 // process serialized AddTask request made from another active task, requesting process
1740 // is currently waiting due to SwitchToNext()
1741 if ((m_request & REQUEST_ADD_TASK) != 0U)
1742 {
1744
1745 for (uint32_t i = 0U; i < TASKS_MAX; ++i)
1746 {
1748
1749 if (task->m_srt[0].add_task_req != nullptr)
1750 {
1751 AllocateAndAddNewTask(task->m_srt[0].add_task_req->user_task);
1752
1753 task->m_srt[0].add_task_req = nullptr;
1755 }
1756 }
1757 }
1758 }
1759 }

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1605 of file stk.h.

1606 {
1607 // sync objects are updated before UpdateTaskRequest which may add a new object (newly added object must become 1 tick older)
1608 if (IsSyncMode())
1610
1612
1614 }
void UpdateTaskRequest()
Update pending task requests.
Definition stk.h:1730
Timeout UpdateTaskState(const Timeout elapsed_ticks)
Update task state: process removals, advance sleep timers, and track HRT durations.
Definition stk.h:1625
void UpdateSyncObjects(const Timeout elapsed_ticks)
Update synchronization objects.
Definition stk.h:1709

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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 1625 of file stk.h.

1626 {
1628
1629 for (uint32_t i = 0U; i < TASKS_MAX; ++i)
1630 {
1632
1633 if (task->IsSleeping())
1634 {
1635 if (IsDynamicMode())
1636 {
1637 // task is pending removal, wait until it is switched out
1638 if (task->IsPendingRemoval())
1639 {
1640 if ((task != m_task_now) ||
1641 ((m_strategy.GetSize() == 1) && (m_fsm_state == FSM_STATE_SLEEPING)))
1642 {
1644 continue;
1645 }
1646 }
1647 }
1648
1649 // deliver sleep event to strategy
1650 // note: only currently scheduled task can be pending to sleep
1652 {
1654 {
1656
1657 // notify strategy that task is sleeping
1658 m_strategy.OnTaskSleep(task);
1659 }
1660 }
1661
1662 // advance sleep time by a tick
1663 task->m_time_sleep += elapsed_ticks;
1664
1665 // deliver sleep event to strategy
1667 {
1668 // notify strategy that task woke up
1669 if (task->m_time_sleep >= 0)
1670 m_strategy.OnTaskWake(task);
1671 }
1672 }
1673 else
1674 if (IsHrtMode())
1675 {
1676 // in HRT mode we trace how long task spent in active state (doing some work)
1677 if (task->IsBusy())
1678 {
1679 task->m_hrt[0].duration += elapsed_ticks;
1680
1681 // check if deadline is missed (HRT failure)
1682 if (task->HrtIsDeadlineMissed(task->m_hrt[0].duration))
1683 {
1684 bool can_recover = false;
1685
1686 // report deadline overrun to a strategy which supports overrun recovery
1688 can_recover = m_strategy.OnTaskDeadlineMissed(task);
1689
1690 // report failure if it could not be recovered by a scheduling strategy
1691 if (!can_recover)
1692 task->HrtHardFailDeadline(&m_platform);
1693 }
1694 }
1695 }
1696
1697 // get the number ticks the driver has to keep CPU in Idle
1698 if (IsTicklessMode() && (sleep_ticks > 1) && task->IsBusy())
1699 {
1700 sleep_ticks = task->GetSleepTicks(sleep_ticks);
1701 }
1702 }
1703
1704 return sleep_ticks;
1705 }
static bool IsTicklessMode()
Definition stk.h:2035

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC, 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[((((TMode) &(KERNEL_DYNAMIC)) !=0U) ?(1) :(0))]
protected

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

Definition at line 2105 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 2111 of file stk.h.

2111 {
2112 // FSM_EVENT_SWITCH FSM_EVENT_SLEEP FSM_EVENT_WAKE FSM_EVENT_EXIT
2117 };

◆ 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 2106 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 2100 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 2107 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 2099 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 2104 of file stk.h.

◆ m_state

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

Current kernel state.

Definition at line 2108 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 2101 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[((((TMode) &(KERNEL_SYNC)) !=0U) ?(1) :(0))]
protected

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

Definition at line 2109 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 2102 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 2103 of file stk.h.

◆ TASKS_MAX

template<uint8_t TMode, uint32_t TSize, class TStrategy, class TPlatform>
uint32_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 789 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 1128 of file stk.h.


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