19template <u
int8_t TMode, u
int32_t TSize,
class TStrategy,
class TPlatform>
59 const int32_t TASKS = 2;
63 CHECK_EQUAL(TASKS, result);
73 CHECK_TRUE(platform != NULL);
99 CHECK_TEXT(
false,
"duplicate Kernel::Initialize() did not fail");
117 CHECK_TEXT(
false,
"AddTask() did not fail");
134 CHECK_EQUAL_TEXT(0, strategy->
GetSize(),
"Expecting none kernel tasks");
138 CHECK_EQUAL_TEXT(1, strategy->
GetSize(),
"Expecting 1 kernel task");
141 CHECK_TRUE_TEXT(ktask != NULL,
"Expecting one kernel task");
143 CHECK_TRUE_TEXT(ktask->
GetUserTask() == &task,
"Expecting just added user task");
172 CHECK_TEXT(
false,
"expecting to fail adding task because max is 2 but adding 3-rd");
193 CHECK_TEXT(
false,
"expecting to fail adding the same task");
221 CHECK_EQUAL_TEXT(2,
strategy->GetSize(),
"task2 must be added within 1 tick");
244 CHECK_EQUAL_TEXT(1, strategy->
GetSize(),
"expecting task1 be added at this stage");
252 CHECK_EQUAL_TEXT(2, strategy->
GetSize(),
"task2 must be added");
271 CHECK_TEXT(
false,
"expecting to AddTask to fail when non KERNEL_DYNAMIC");
286 kernel.
AddTask(&task1, 1, 1, 0);
292 kernel.
AddTask(&task2, 1, 1, 0);
293 CHECK_TEXT(
false,
"expecting to AddTask to fail when KERNEL_HRT");
316 CHECK_EQUAL_TEXT(&task2, strategy->
GetFirst()->
GetUserTask(),
"Expecting task2 as first (duplicate task1 removal attempt)");
319 CHECK_EQUAL_TEXT(0, strategy->
GetSize(),
"Expecting none tasks");
332 CHECK_TEXT(
false,
"expecting to fail with NULL argument");
353 CHECK_TEXT(
false,
"expecting to fail in KERNEL_STATIC mode");
375 CHECK_TEXT(
false,
"expecting to fail when Kernel has started");
393 CHECK_TEXT(
false,
"expecting to fail with 0 periodicity");
405 CHECK_TEXT(
false,
"expecting to fail with too large periodicity");
422 CHECK_TEXT(
false,
"expecting to fail when not initialized");
441 CHECK_TEXT(
false,
"expecting to fail without tasks");
499 CHECK_TRUE(idle != NULL);
500 CHECK_TRUE(active != NULL);
503 CHECK_EQUAL(idle->
SP, (
size_t)task1.
GetStack());
506 CHECK_EQUAL(active->SP, (
size_t)task2.GetStack());
516 CHECK_TRUE(idle != NULL);
517 CHECK_TRUE(active != NULL);
520 CHECK_EQUAL(idle->
SP, (
size_t)task2.GetStack());
523 CHECK_EQUAL(active->SP, (
size_t)task1.
GetStack());
593 CHECK_EQUAL((
Stack *)NULL, idle);
597template <
class _SwitchStrategy>
631 CHECK_EQUAL((
Stack *)NULL, idle);
670 CHECK_TEXT(
false,
"expecting to fail on unknown stack");
682 CHECK_TEXT(
false,
"expecting to fail on NULL");
726 CHECK_TEXT(
false,
"non existent task must not succeed");
762 CHECK_TEXT(
false,
"exited task must be successfully skipped by FindTaskBySP()");
778 kernel.
AddTask(&task1, 1, 1, 0);
779 kernel.
AddTask(&task2, 2, 1, 0);
800 CHECK_TEXT(
false,
"non-HRT AddTask not supported in HRT mode");
819 kernel.
AddTask(&task, 1, 1, 0);
820 CHECK_TEXT(
false,
"HRT-related AddTask not supported in non-HRT mode");
835 kernel.
AddTask(&task, 1, 1, 0);
842 CHECK_TEXT(
false,
"IKernelService::Sleep not allowed in HRT mode");
854 CHECK_TEXT(
false,
"IKernelService::SleepUntil not allowed in HRT mode");
871 kernel.
AddTask(&task, 1, 1, 0);
874 CHECK_TRUE(strategy->
GetSize() != 0);
881 CHECK_EQUAL(0, strategy->
GetSize());
917 kernel.
AddTask(&task, 2, 1, 0);
942 kernel.
AddTask(&task, 2, 1, 0);
967 kernel.
AddTask(&task1, 2, 2, 3);
968 kernel.
AddTask(&task2, 3, 3, 0);
983 CHECK_EQUAL(0, task2.m_deadline_missed);
986template <
class _SwitchStrategy>
992 const _SwitchStrategy *strategy =
static_cast<const _SwitchStrategy *
>(kernel.
GetSwitchStrategy());
995 kernel.
AddTask(&task1, 1, 2, 0);
996 kernel.
AddTask(&task2, 1, 2, 2);
1014 CHECK_EQUAL(1, strategy->GetSize());
1044 kernel.
AddTask(&task, 1, 1, 1);
1068 CHECK_TRUE_TEXT(ktask !=
nullptr,
"Kernel task must exist");
1074 CHECK_TEXT(
false,
"HRT API can't be called in non-HRT mode");
1086 CHECK_TEXT(
false,
"HRT API can't be called in non-HRT mode");
1098 CHECK_TEXT(
false,
"HRT API can't be called in non-HRT mode");
1121 CHECK_TEXT(
false,
"kernel does not support waiting without KERNEL_SYNC");
1135 CHECK_TRUE_TEXT(wo ==
nullptr,
"expect NULL");
1141 CHECK_TEXT(
false,
"kernel does not support waiting without KERNEL_SYNC");
1155 CHECK_TRUE_TEXT(wo ==
nullptr,
"expect NULL");
1173 CHECK_TEXT(
false,
"sync object must not be NULL");
1197 CHECK_TEXT(
false,
"mutex must not be NULL");
1222 CHECK_TEXT(
false,
"must not be zero wait");
1247 CHECK_TEXT(
false,
"mutex must be locked");
1315 CHECK_EQUAL(2,
platform->m_ticks_count);
1326template <
bool TTickless>
1340 kernel.Initialize();
1341 kernel.AddTask(&task);
1349 CHECK_TRUE(wo !=
nullptr);
1352 CHECK_EQUAL(
true,
mutex.m_locked);
1394 CHECK_TRUE(wo !=
nullptr);
1397 CHECK_EQUAL(
true,
mutex.m_locked);
void(* g_RelaxCpuHandler)()
__stk_relax_cpu handler.
Namespace of STK package.
void Sleep(uint32_t ticks)
Put calling process into a sleep state.
Ticks GetTicks()
Get number of ticks elapsed since kernel start.
@ STACK_SLEEP_TRAP
Stack of the Sleep trap.
@ STACK_USER_TASK
Stack of the user task.
void Yield()
Notify scheduler to switch to the next runnable task.
void SleepUntil(Ticks timestamp)
Put calling process into a sleep state until the specified timestamp.
@ PERIODICITY_MAX
Maximum periodicity (microseconds), 99 milliseconds (note: this value is the highest working on a rea...
TId GetTid()
Get task/thread Id of the calling task.
SwitchStrategyRoundRobin SwitchStrategyRR
Shorthand alias for SwitchStrategyRoundRobin.
@ ACCESS_USER
Unprivileged access mode (access to some hardware is restricted, see CPU manual for details).
@ ACCESS_PRIVILEGED
Privileged access mode (access to hardware is fully unrestricted).
@ KERNEL_TICKLESS
Tickless mode. To use this mode STK_TICKLESS_IDLE must be defined to 1 in stk_config....
@ KERNEL_SYNC
Synchronization support (see Event).
@ KERNEL_STATIC
All tasks are static and can not exit.
@ KERNEL_PANIC_BAD_MODE
Kernel is in bad/unsupported mode for the current operation.
@ KERNEL_PANIC_NONE
Panic is absent (no fault).
@ KERNEL_PANIC_BAD_STATE
Kernel entered unexpected (bad) state.
Namespace of the test inventory.
static struct stk::test::SyncWaitRelaxCpuContext g_SyncWaitRelaxCpuContext
TestContext g_TestContext
Global instance of the TestContext.
static void SyncWaitRelaxCpu()
static struct stk::test::AddTaskWhenStartedRelaxCpuContext g_AddTaskWhenStartedRelaxCpuContext
IKernelService * g_KernelService
static struct stk::test::HrtTaskDeadlineMissedRelaxCpuContext g_HrtTaskDeadlineMissedRelaxCpuContext
EKernelPanicId g_PanicValue
Panic value.
static void HrtTaskDeadlineMissedRelaxCpu()
static void TestTaskExit()
static void AddTaskWhenStartedRelaxCpu()
static void TestHrtTaskExitDuringSleepState()
Concrete implementation of IKernel.
bool UpdateFsmState(Stack *&idle, Stack *&active)
Update FSM state.
EFsmState
Finite-state machine (FSM) state. Encodes what the kernel is currently doing between two consecutive ...
@ FSM_STATE_NONE
Sentinel / uninitialized value. Set by the constructor, replaced by FSM_STATE_SWITCHING on the first ...
@ FSM_STATE_MAX
Sentinel: number of valid states (used to size the FSM table), denotes uninitialized state.
EFsmState GetNewFsmState(KernelTask *&next)
Get new FSM state.
void Initialize(uint32_t resolution_us=PERIODICITY_DEFAULT)
Prepare kernel for use: reset state, configure the platform, and register the service singleton.
EState GetState() const
Get kernel state.
ITaskSwitchStrategy * GetSwitchStrategy()
Get task-switching strategy instance owned by this kernel.
void Start()
Start the scheduler. This call does not return until all tasks have exited (KERNEL_DYNAMIC mode) or i...
void RemoveTask(ITask *user_task)
Remove a previously added task from the kernel before Start().
KernelTask * m_task_now
Currently executing task, or nullptr before Start() or after all tasks exit.
IPlatform * GetPlatform()
Get platform driver instance owned by this kernel.
Kernel()
Construct the kernel with all storage zero-initialised and the request flag set to ~0 (indicating uni...
@ TASKS_MAX
Maximum number of concurrently registered tasks. Fixed at compile time. Exceeding this limit in AddTa...
void AddTask(ITask *user_task)
Register task for a soft real-time (SRT) scheduling.
Internal per-slot kernel descriptor that wraps a user ITask instance.
Word SP
Stack Pointer (SP) register (note: must be the first entry in this struct).
EAccessMode mode
access mode
virtual TId GetTid() const =0
Get thread Id of this task.
virtual bool IsTimeout() const =0
Check if task woke up due to a timeout.
Locks bound mutex within a scope of execution. Ensures the mutex is always unlocked when leaving the ...
Interface for a user task.
Scheduling-strategy-facing interface for a kernel task slot.
virtual Timeout GetHrtRelativeDeadline() const =0
Get HRT task's relative deadline.
virtual Timeout GetHrtDeadline() const =0
Get HRT task deadline (max allowed task execution time).
virtual Timeout GetHrtPeriodicity() const =0
Get HRT task execution periodicity.
virtual ITask * GetUserTask()=0
Get user task.
Interface for a task switching strategy implementation.
virtual size_t GetSize() const =0
Get number of tasks currently managed by this strategy.
virtual IKernelTask * GetFirst() const =0
Get first task.
@ 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
static IKernelService * GetInstance()
Get CPU-local instance of the kernel service.
virtual IWaitObject * Wait(ISyncObject *sobj, IMutex *mutex, Timeout timeout)=0
Put calling process into a waiting state until synchronization object is signaled or timeout occurs.
Word * GetStack() const
Get pointer to the stack memory.
BaseType::EFsmState GetNewFsmState(typename BaseType::KernelTask *&next) override
Kernel< TMode, TSize, TStrategy, TPlatform > BaseType
void ForceUpdateInvalidFsmState(bool max_val)
const ITaskSwitchStrategy * strategy
AddTaskWhenStartedRelaxCpuContext()
PlatformTestMock * platform
HrtTaskDeadlineMissedRelaxCpuContext()
PlatformTestMock * platform
PlatformTestMock * platform
SyncWaitRelaxCpuContext()
Throwable class for catching assertions from STK_ASSERT_HANDLER().
void EventTaskSwitch(size_t caller_SP)
void ProcessTick()
Process one tick.
void EventTaskExit(Stack *stack)
IWaitObject * EventTaskWait(size_t caller_SP, ISyncObject *sync_obj, IMutex *mutex, Timeout timeout)
IKernelService * m_service
uint32_t m_context_switch_nr
StackInfo m_stack_info[STACK_EXIT_TRAP+1]
uint32_t GetTickResolution() const
Get resolution of the system tick timer in microseconds. Resolution means a number of microseconds be...
uint32_t m_deadline_missed
duration of workload if deadline is missed in HRT mode