SuperTinyKernel™ RTOS 1.08.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk_c.cpp
Go to the documentation of this file.
1/*
2 * SuperTinyKernel(TM) RTOS: Lightweight High-Performance Deterministic C++ RTOS for Embedded Systems.
3 *
4 * Source: https://github.com/SuperTinyKernel-RTOS
5 *
6 * Copyright (c) 2022-2026 Neutron Code Limited <stk@neutroncode.com>. All Rights Reserved.
7 * License: MIT License, see LICENSE for a full text.
8 */
9
10#include <cstddef> // for std::size_t
11
12#include "stk.h"
13#include "sync/stk_sync.h"
14#include "memory/stk_memory.h"
15
16#include "stk_c.h"
17#include "stk_c_time.h"
18
19// Override STK_TIMER_COUNT_MAX with STK_C_TIMER_MAX.
20#undef STK_TIMER_COUNT_MAX
21#define STK_TIMER_COUNT_MAX (STK_C_TIMER_MAX)
22#include "time/stk_time.h"
23
24// Check correctness of stk_config.h
25#ifndef STK_C_KERNEL_TYPE_CPU_0
26#error "Missing STK_C_KERNEL_TYPE_CPU_0: Kernel type for CPU0 must be defined via stk_config.h or compiler flags."
27#endif
28#ifndef STK_C_CPU_COUNT
29#error "Missing STK_C_CPU_COUNT: CPU count must be defined via stk_config.h or compiler flags."
30#endif
31#ifndef STK_C_KERNEL_MAX_TASKS
32#error "Missing STK_C_KERNEL_MAX_TASKS: max task count must be defined via stk_config.h or compiler flags."
33#endif
34
35using namespace stk;
36
37#define STK_C_TASKS_MAX (STK_C_KERNEL_MAX_TASKS)
38
39// Forward decl.
40struct stk_task_t;
41
42// Cast from stk_kernel_t to IKernel without a warning.
44{
45 return reinterpret_cast<IKernel *>(reinterpret_cast<void *>(k));
46}
47
48// Cast from const stk_kernel_t to const IKernel without a warning.
50{
51 return reinterpret_cast<const IKernel *>(reinterpret_cast<const void *>(k));
52}
53
54// Cast from IKernel to stk_kernel_t without a warning.
56{
57 return reinterpret_cast<stk_kernel_t *>(reinterpret_cast<void *>(k));
58}
59
60// Interop-private helpers
61namespace stk {
63
65{
66 th->Initialize(CastCToKernelInterface(kernel), amode);
67}
68
69} // interop_c_helper
70} // stk
71
72static void FreeTask(const stk_task_t *tsk);
73
74class TaskWrapper final : public ITask
75{
76public:
77 explicit TaskWrapper() : m_func(nullptr), m_user_data(nullptr), m_stack(nullptr),
79 {}
80
85
86 // ITask
87 EAccessMode GetAccessMode() const override { return m_mode; }
88 int32_t GetWeight() const override { return m_weight; }
89 const char *GetTraceName() const override { return m_tname; }
90
91 // IStackMemory
92 const Word *GetStack() const override { return m_stack; }
93 size_t GetStackSize() const override { return m_stack_size; }
94
95 void Initialize(stk_task_entry_t const func, void *user_data, stk_word_t *stack,
96 size_t stack_size, EAccessMode mode)
97 {
98 m_func = func;
99 m_user_data = user_data;
100 m_stack = stack;
101 m_stack_size = stack_size;
102 m_mode = mode;
104 }
105
106 void SetWeight(Weight weight) { m_weight = weight; }
107 void SetName(const char *tname) { m_tname = tname; }
108
109private:
111
112 void Run() override { m_func(m_user_data); }
113 void OnExit() override;
114
121 const char *m_tname;
122};
123
128
129static struct TaskSlot
130{
131 TaskSlot() : busy(false), task()
132 {}
133
134 bool busy;
136}
138
139// Cast from stk_task_t to TaskWrapper without a warning.
141{
142 return reinterpret_cast<stk_task_t *>(reinterpret_cast<void *>(t));
143}
144
149
150// -----------------------------------------------------------------------------
151// EventOverriderWrapper - bridges stk_event_overrider_t callbacks into the
152// C++ IPlatform::IEventOverrider interface.
153//
154// One instance is embedded per kernel slot (indexed by core_nr). The wrapper
155// is stateless when m_c == nullptr, which makes it safe to construct at file
156// scope. SetC(nullptr) is equivalent to removing the overrider.
157// -----------------------------------------------------------------------------
158
160{
161public:
162 EventOverrider() : m_cb(nullptr)
163 {}
164
169
175
178 bool IsActive() const { return (m_cb != nullptr); }
179
180 // IPlatform::IEventOverrider
181 bool OnSleep(Timeout sleep_ticks) override
182 {
183 bool is_handled = false;
184
185 if ((m_cb != nullptr) && (m_cb->on_sleep != nullptr))
186 {
187 is_handled = m_cb->on_sleep(static_cast<stk_timeout_t>(sleep_ticks), m_cb->user_data);
188 }
189
190 return is_handled;
191 }
192 bool OnHardFault() override
193 {
194 bool is_handled = false;
195
196 if ((m_cb != nullptr) && (m_cb->on_hard_fault != nullptr))
197 {
198 is_handled = m_cb->on_hard_fault(m_cb->user_data);
199 }
200
201 return is_handled;
202 }
203
204private:
206};
207
217
218static void RegisterKernel(IKernel *k, uint8_t core_nr)
219{
220 STK_ASSERT(s_KernelMap[core_nr].kernel == nullptr);
221
222 s_KernelMap[core_nr].kernel = k;
223}
224
225static void UnregisterKernel(const IKernel *k)
226{
227 for (uint32_t i = 0U; i < STK_C_CPU_COUNT; ++i)
228 {
229 if (s_KernelMap[i].kernel == k)
230 {
231 s_KernelMap[i].event_cb.SetCallback(nullptr);
232 s_KernelMap[i].kernel = nullptr;
233 break;
234 }
235 }
236}
237
239{
240 bool found = false;
241
242 for (uint32_t i = 0U; (i < STK_C_CPU_COUNT) && (!found); ++i)
243 {
244 if (s_KernelMap[i].kernel == k)
245 {
246 s_KernelMap[i].event_cb.SetCallback(overrider);
248 (overrider != nullptr) ? &s_KernelMap[i].event_cb : nullptr);
249 found = true;
250 }
251 }
252
253 // Kernel not found: stk_kernel_set_event_overrider() called before
254 // stk_kernel_create() or after stk_kernel_destroy().
255 STK_ASSERT(found);
256}
257
258// -----------------------------------------------------------------------------
259// Helpers
260// -----------------------------------------------------------------------------
261
263 void *arg,
264 stk_word_t *stack,
265 uint32_t stack_size,
266 EAccessMode amode)
267{
268 stk_task_t *tsk = nullptr;
269
271
272 for (uint32_t i = 0U; i < STK_C_TASKS_MAX; ++i)
273 {
274 if (!s_Tasks[i].busy)
275 {
276 s_Tasks[i].busy = true;
277
278 tsk = &s_Tasks[i].task;
279 tsk->handle.Initialize(entry, arg, stack, stack_size, amode);
280 break;
281 }
282 }
283
284 STK_ASSERT(tsk != nullptr);
285 return tsk;
286}
287
288void FreeTask(const stk_task_t *tsk)
289{
290 bool found = false;
291
293
294 for (uint32_t i = 0U; ((i < STK_C_TASKS_MAX) && !found); ++i)
295 {
296 if (s_Tasks[i].busy && (tsk == &s_Tasks[i].task))
297 {
298 s_Tasks[i].busy = false;
299 found = true;
300 }
301 }
302
303 STK_ASSERT(found);
304}
305
306// =============================================================================
307// C-interface
308// =============================================================================
309extern "C" {
310
311// -----------------------------------------------------------------------------
312// Kernel create/destroy wrappers
313// -----------------------------------------------------------------------------
314#define STK_PP_CAT(A, B) A##B
315#define STK_PP_CAT_EXPAND(A, B) STK_PP_CAT(A, B)
316#define STK_KERNEL_TYPE(X) STK_PP_CAT(STK_C_KERNEL_TYPE_CPU_, X)
317#define STK_KERNEL_MEM(X) STK_PP_CAT_EXPAND(kernel_, STK_PP_CAT_EXPAND(X, _mem))
318#define STK_KERNEL_CASE(X) \
319 case X: \
320 { \
321 using KernelType_ = STK_KERNEL_TYPE(X); \
322 STK_STATIC_ASSERT_DESC(((sizeof(KernelType_) % sizeof(Word)) == 0U), \
323 "Kernel memory size must be multiple of Word"); \
324 alignas(alignof(KernelType_)) \
325 static Word STK_KERNEL_MEM(X)[sizeof(KernelType_) / sizeof(Word)]; \
326 k = new (STK_KERNEL_MEM(X)) KernelType_(); \
327 RegisterKernel(k, static_cast<uint8_t>(X)); \
328 break; \
329 }
330
332{
333 STK_STATIC_ASSERT((STK_C_CPU_COUNT <= 8U)); // switch (core_nr) below handles cases 0..7; STK_C_KERNEL_TYPE_CPU_N is only defined up to N=7
334 STK_ASSERT(core_nr < STK_C_CPU_COUNT);
335
336 IKernel *k;
337
338 switch (core_nr)
339 {
340#ifdef STK_C_KERNEL_TYPE_CPU_0
342#endif
343#ifdef STK_C_KERNEL_TYPE_CPU_1
345#endif
346#ifdef STK_C_KERNEL_TYPE_CPU_2
348#endif
349#ifdef STK_C_KERNEL_TYPE_CPU_3
351#endif
352#ifdef STK_C_KERNEL_TYPE_CPU_4
354#endif
355#ifdef STK_C_KERNEL_TYPE_CPU_5
357#endif
358#ifdef STK_C_KERNEL_TYPE_CPU_6
360#endif
361#ifdef STK_C_KERNEL_TYPE_CPU_7
363#endif
364 default: {
365 k = nullptr;
366 break; }
367 }
368
370}
371
373{
374 STK_ASSERT(core_nr < STK_C_CPU_COUNT);
375
376 IKernel *const k = s_KernelMap[core_nr].kernel;
377
378 // Kernel not found: stk_kernel_get_instance() called before
379 // stk_kernel_create() or after stk_kernel_destroy().
380 STK_ASSERT(k != nullptr);
381
382 return k;
383}
384
386{
387 STK_ASSERT(k != nullptr);
388
389 // Detach the event overrider and clear the registry entry BEFORE calling
390 // the destructor: the platform teardown inside ~IKernel() may still invoke
391 // GetPlatform() paths, and we must not leave a dangling overrider pointer
392 // registered at that point.
394}
395
396// -----------------------------------------------------------------------------
397// Kernel control wrappers
398// -----------------------------------------------------------------------------
399void stk_kernel_init(stk_kernel_t *k, uint32_t tick_period_us)
400{
401 STK_ASSERT(k != nullptr);
402
403 CastCToKernelInterface(k)->Initialize(tick_period_us);
404}
405
407{
408 STK_ASSERT(k != nullptr);
409
411}
412
414{
415 STK_ASSERT(k != nullptr);
416
418}
419
421{
422 STK_ASSERT(k != nullptr);
423
425 const_cast<IKernel *>(CastCToKernelInterfaceConst(k))->GetSwitchStrategy());
426}
427
429{
430 STK_ASSERT(k != nullptr);
431 STK_ASSERT(tsk != nullptr);
432
434}
435
437{
438 STK_ASSERT(k != nullptr);
439 STK_ASSERT(tsk != nullptr);
440
442}
443
445{
446 STK_ASSERT(k != nullptr);
447
450}
451
453{
454 STK_ASSERT(k != nullptr);
455 STK_ASSERT(tsk != nullptr);
456
458}
459
460void stk_kernel_suspend_task(stk_kernel_t *k, stk_task_t *tsk, bool *suspended)
461{
462 STK_ASSERT(k != nullptr);
463 STK_ASSERT(tsk != nullptr);
464 STK_ASSERT(suspended != nullptr);
465
466 CastCToKernelInterface(k)->SuspendTask(&tsk->handle, *suspended);
467}
468
470{
471 STK_ASSERT(k != nullptr);
472 STK_ASSERT(tsk != nullptr);
473
475}
476
477size_t stk_kernel_enumerate_tasks(stk_kernel_t *k, stk_task_t **tasks, size_t max_count)
478{
479 STK_ASSERT(k != nullptr);
480 STK_ASSERT(tasks != nullptr);
481
482 stk::ITask *itasks[STK_C_TASKS_MAX] = {};
483
484 // Determine the safe upper bound for the temporary buffer
485 const size_t requested_size = (max_count < static_cast<size_t>(STK_C_TASKS_MAX)) ? max_count :
486 static_cast<size_t>(STK_C_TASKS_MAX);
487
488 // Pass via ArrayView temporary object
489 const size_t ret_count = CastCToKernelInterface(k)->EnumerateTasks(
490 ArrayView<stk::ITask *>(itasks, requested_size));
491
492 ArrayView<stk_task_t *> output_view(tasks, max_count);
493 for (size_t i = 0U; i < ret_count; ++i)
494 {
495 output_view[i] = CastCppTaskInterfaceToC(itasks[i]);
496 }
497
498 return ret_count;
499}
500
502{
503 STK_ASSERT(k != nullptr);
504
505 return static_cast<stk_timeout_t>(CastCToKernelInterface(k)->GetPlatform()->Suspend());
506}
507
509{
510 STK_ASSERT(k != nullptr);
511
512 CastCToKernelInterface(k)->GetPlatform()->Resume(static_cast<stk::Timeout>(elapsed_ticks));
513}
514
516{
517 STK_ASSERT(k != nullptr);
518
520}
521
528
530{
531 STK_ASSERT(k != nullptr);
532
534}
535
537 stk_task_t *tsk,
538 int32_t periodicity_ticks,
539 int32_t deadline_ticks,
540 int32_t start_delay_ticks)
541{
542 STK_ASSERT(k != nullptr);
543 STK_ASSERT(tsk != nullptr);
544
546 &tsk->handle,
547 periodicity_ticks,
548 deadline_ticks,
549 start_delay_ticks);
550}
551
552// -----------------------------------------------------------------------------
553// Task creation
554// -----------------------------------------------------------------------------
556 void *arg,
557 stk_word_t *stack,
558 uint32_t stack_size)
559{
560 STK_ASSERT(entry != nullptr);
561 STK_ASSERT(stack != nullptr);
562 STK_ASSERT(stack_size != 0);
563
564 return AllocateTask(entry, arg, stack, stack_size, ACCESS_PRIVILEGED);
565}
566
568 void *arg,
569 stk_word_t *stack,
570 uint32_t stack_size)
571{
572 STK_ASSERT(entry != nullptr);
573 STK_ASSERT(stack != nullptr);
574 STK_ASSERT(stack_size != 0);
575
576 return AllocateTask(entry, arg, stack, stack_size, ACCESS_USER);
577}
578
580{
581 STK_ASSERT(tsk != nullptr);
582
583 tsk->handle.SetWeight(weight);
584}
585
586void stk_task_set_priority(stk_task_t *tsk, uint8_t priority)
587{
588 STK_ASSERT(priority <= 31U);
589
590 const stk_weight_t weight = static_cast<stk_weight_t>(priority);
591
592 stk_task_set_weight(tsk, weight);
593}
594
595void stk_task_set_name(stk_task_t *tsk, const char *tname)
596{
597 STK_ASSERT(tsk != nullptr);
598
599 tsk->handle.SetName(tname);
600}
601
602const char *stk_task_get_name(const stk_task_t *tsk)
603{
604 STK_ASSERT(tsk != nullptr);
605
606 return tsk->handle.GetTraceName();
607}
608
610{
611 STK_ASSERT(tsk != nullptr);
612
613 return stk::GetTidFromUserTask(&tsk->handle);
614}
615
617{
618 STK_ASSERT(tsk != nullptr);
619
620 return &tsk->handle;
621}
622
624{
625 STK_ASSERT(tsk != nullptr);
626
627 FreeTask(tsk);
628}
629
630// -----------------------------------------------------------------------------
631// Kernel services (available inside tasks)
632// -----------------------------------------------------------------------------
633stk_tid_t stk_tid(void) { return stk::GetTid(); }
635uint32_t stk_tick_resolution(void) { return stk::GetTickResolution(); }
644void stk_delay(stk_timeout_t ticks) { stk::Delay(ticks); }
645void stk_sleep(stk_timeout_t ticks) { stk::Sleep(ticks); }
650void stk_yield(void) { stk::Yield(); }
651
652// -----------------------------------------------------------------------------
653// Thread-Local Storage (TLS) API
654// -----------------------------------------------------------------------------
655#if STK_TLS
656void *stk_tls_get(void)
657{
658 return hw::GetTlsPtr<void *>();
659}
660
661void stk_tls_set(void *ptr)
662{
663 hw::SetTlsPtr(ptr);
664}
665#endif
666
667// -----------------------------------------------------------------------------
668// Critical Section
669// -----------------------------------------------------------------------------
670
675
680
687
692
693// =============================================================================
694} // extern "C"
695// =============================================================================
Collection of memory-related primitives (stk::memory namespace).
Top-level STK include. Provides the Kernel class template and all built-in task-switching strategies.
#define STK_UNUSED(X)
Explicitly marks a variable as unused to suppress compiler warnings.
Definition stk_defs.h:715
#define __stk_forceinline
Forces compiler to always inline the decorated function, regardless of optimisation level.
Definition stk_defs.h:277
#define STK_NONCOPYABLE_CLASS(TYPE)
Disables copy construction and assignment for a class.
Definition stk_defs.h:708
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:516
#define STK_STATIC_ASSERT(X)
Compile-time assertion. Produces a compilation error if X is false.
Definition stk_defs.h:553
#define STK_VIRT_DTOR
Makes destructors virtual and compliant to strict rules if STK_STRICT_COMPLIANCY=0.
Definition stk_defs.h:261
Collection of synchronization primitives (stk::sync namespace).
Collection of time-related primitives (stk::time namespace).
C language binding/interface for SuperTinyKernel RTOS.
C language binding for stk::time::TimerHost and stk::time::TimerHost::Timer.
static stk_kernel_t * CastCppKernelInterfaceToC(IKernel *const k)
Definition stk_c.cpp:55
static stk_task_t * AllocateTask(stk_task_entry_t entry, void *arg, stk_word_t *stack, uint32_t stack_size, EAccessMode amode)
Definition stk_c.cpp:262
#define STK_KERNEL_CASE(X)
Definition stk_c.cpp:318
static void UnregisterKernel(const IKernel *k)
Definition stk_c.cpp:225
static void RegisterKernel(IKernel *k, uint8_t core_nr)
Definition stk_c.cpp:218
static const IKernel * CastCToKernelInterfaceConst(const stk_kernel_t *const k)
Definition stk_c.cpp:49
static void FreeTask(const stk_task_t *tsk)
Definition stk_c.cpp:288
static stk_task_t * CastCppTaskInterfaceToC(ITask *const t)
Definition stk_c.cpp:140
static void SetEventOverrider(IKernel *k, stk_event_overrider_t *overrider)
Definition stk_c.cpp:238
static struct TaskSlot s_Tasks[((4))]
#define STK_C_TASKS_MAX
Definition stk_c.cpp:37
static IKernel * CastCToKernelInterface(stk_kernel_t *const k)
Definition stk_c.cpp:43
static KernelRegistryEntry s_KernelMap[(1)]
Definition stk_c.cpp:216
void stk_kernel_process_tick(stk_kernel_t *k)
Manually deliver one scheduler tick to the kernel.
Definition stk_c.cpp:515
stk_task_t * stk_task_create_user(stk_task_entry_t entry, void *arg, stk_word_t *stack, uint32_t stack_size)
Create user-mode task.
Definition stk_c.cpp:567
void stk_task_set_name(stk_task_t *tsk, const char *tname)
Assign human-readable task name (for tracing/debugging).
Definition stk_c.cpp:595
stk_cycle_t stk_hires_cycles(void)
Get raw CPU cycle counter.
Definition stk_c.cpp:641
stk_tid_t stk_tid(void)
Returns current task/thread ID (the value set by stk_task_set_id).
Definition stk_c.cpp:633
stk_tick_t stk_ticks_from_ms(stk_time_t msec)
Get ticks from milliseconds using current kernel tick resolution.
Definition stk_c.cpp:637
void stk_kernel_remove_task(stk_kernel_t *k, stk_task_t *tsk)
Remove finished task from dynamic kernel.
Definition stk_c.cpp:436
void * stk_tls_get(void)
Get thread-local pointer (platform-specific slot).
uint8_t stk_cs_session_t
Session of Critical Section.
Definition stk_c.h:897
const char * stk_task_get_name(const stk_task_t *tsk)
Get human-readable task name previously set with stk_task_set_name().
Definition stk_c.cpp:602
void stk_kernel_destroy(stk_kernel_t *k)
Destroy dynamic kernel instance (only when not running).
Definition stk_c.cpp:385
void stk_kernel_suspend_task(stk_kernel_t *k, stk_task_t *tsk, bool *suspended)
Suspend a task (prevent it from being scheduled).
Definition stk_c.cpp:460
stk::IKernel * stk_kernel_get_instance(uint8_t core_nr)
Get the underlying C++ stk::IKernel object for a given core.
Definition stk_c.cpp:372
struct stk_kernel_t stk_kernel_t
Opaque handle to a kernel instance.
Definition stk_c.h:131
void stk_kernel_resume(stk_kernel_t *k, stk_timeout_t elapsed_ticks)
Resume scheduling after a prior stk_kernel_suspend() call.
Definition stk_c.cpp:508
stk_timeout_t stk_kernel_suspend(stk_kernel_t *k)
Suspend scheduling (tickless idle entry point).
Definition stk_c.cpp:501
void stk_delay_ms(stk_timeout_t ms)
Busy-wait delay (other tasks continue to run).
Definition stk_c.cpp:646
void stk_yield(void)
Voluntarily give up CPU to another ready task (cooperative yield).
Definition stk_c.cpp:650
uint32_t stk_hires_frequency(void)
Get CPU clock frequency in Hz.
Definition stk_c.cpp:642
#define STK_C_CPU_COUNT
Number of kernel instances / CPU cores supported (default: 1).
Definition stk_c.h:65
void stk_kernel_resume_task(stk_kernel_t *k, stk_task_t *tsk)
Resume a previously suspended task.
Definition stk_c.cpp:469
void stk_kernel_start(stk_kernel_t *k)
Start the scheduler - never returns.
Definition stk_c.cpp:406
void stk_sleep(stk_timeout_t ticks)
Put current task to sleep (non-HRT kernels only).
Definition stk_c.cpp:645
uint64_t stk_cycle_t
CPU cycles value.
Definition stk_c.h:123
void stk_task_set_weight(stk_task_t *tsk, stk_weight_t weight)
Set task weight (used only by Smooth Weighted Round Robin).
Definition stk_c.cpp:579
void stk_kernel_set_event_overrider(stk_kernel_t *k, stk_event_overrider_t *overrider)
Install a platform event overrider on the kernel.
Definition stk_c.cpp:529
stk_cs_session_t stk_critical_section_enter_ex(stk_cs_session_t ses)
Enter global critical section - disable context switches on current core.
Definition stk_c.cpp:671
stk_timeout_t stk_ticks_from_ms_clamped_to_timeout(stk_timeout_t ms)
Get ticks from milliseconds using current kernel tick resolution, clamped to the maximum value repres...
Definition stk_c.cpp:638
stk_cycle_t stk_sys_timer_count(void)
Get raw system timer counter value.
Definition stk_c.cpp:639
static stk_tick_t stk_ticks_from_ms_r(stk_time_t msec, uint32_t resolution)
Get ticks from milliseconds using an explicit tick resolution.
Definition stk_c.h:690
stk_tid_t stk_task_get_id(const stk_task_t *tsk)
Get the unique identifier of a task.
Definition stk_c.cpp:609
uint32_t stk_tick_resolution(void)
Returns how many microseconds correspond to one kernel tick.
Definition stk_c.cpp:635
uint32_t stk_sys_timer_frequency(void)
Get system timer frequency in Hz.
Definition stk_c.cpp:640
void stk_kernel_schedule_task_removal(stk_kernel_t *k, stk_task_t *tsk)
Schedule removal of a running task from the kernel on the next tick.
Definition stk_c.cpp:452
void stk_sleep_ms(stk_timeout_t ms)
Put current task to sleep (non-HRT kernels only).
Definition stk_c.cpp:647
size_t stk_kernel_enumerate_tasks(stk_kernel_t *k, stk_task_t **tasks, size_t max_count)
Enumerate all currently active tasks.
Definition stk_c.cpp:477
void stk_kernel_add_task(stk_kernel_t *k, stk_task_t *tsk)
Add task to non-HRT kernel (static or dynamic).
Definition stk_c.cpp:428
void stk_kernel_init(stk_kernel_t *k, uint32_t tick_period_us)
Initialize kernel with given tick period.
Definition stk_c.cpp:399
void stk_critical_section_exit_ex(stk_cs_session_t ses)
Leave global critical section - re-enable context switches.
Definition stk_c.cpp:676
stk_tick_t stk_hires_time_us(void)
Get elapsed time in microseconds from the high-resolution clock.
Definition stk_c.cpp:643
void(* stk_task_entry_t)(void *arg)
Task entry point function type.
Definition stk_c.h:148
stk_kernel_state_t
Kernel state.
Definition stk_c.h:394
void stk_tls_set(void *ptr)
Set thread-local pointer.
stk_task_t * stk_task_create_privileged(stk_task_entry_t entry, void *arg, stk_word_t *stack, uint32_t stack_size)
Create privileged-mode (kernel-mode) task.
Definition stk_c.cpp:555
stk_tick_t stk_ticks(void)
Returns number of ticks elapsed since kernel start.
Definition stk_c.cpp:634
void stk_task_set_priority(stk_task_t *tsk, uint8_t priority)
Set task priority (used only by Fixed Priority scheduler).
Definition stk_c.cpp:586
void stk_critical_section_enter()
Enter global critical section - disable context switches on current core.
Definition stk_c.cpp:681
stk_word_t stk_tid_t
Task id.
Definition stk_c.h:103
stk::ITask * stk_task_get_instance(stk_task_t *tsk)
Get the underlying C++ stk::ITask object wrapped by a stk_task_t handle.
Definition stk_c.cpp:616
int64_t stk_tick_t
Ticks value.
Definition stk_c.h:108
stk_kernel_t * stk_kernel_create(uint8_t core_nr)
Create kernel.
Definition stk_c.cpp:331
uintptr_t stk_word_t
CPU register type.
Definition stk_c.h:99
bool stk_kernel_is_started(const stk_kernel_t *k)
Check whether the scheduler is currently running (first task switch has occurred).
Definition stk_c.cpp:444
void stk_sleep_cancel(stk_tid_t tid)
Cancel the sleep of a task, waking it immediately.
Definition stk_c.cpp:649
int64_t stk_time_t
Time value.
Definition stk_c.h:113
stk_time_t stk_time_now_ms(void)
Returns current time in milliseconds since kernel start.
Definition stk_c.cpp:636
int32_t stk_weight_t
Task weight value.
Definition stk_c.h:127
void stk_kernel_add_task_hrt(stk_kernel_t *k, stk_task_t *tsk, int32_t periodicity_ticks, int32_t deadline_ticks, int32_t start_delay_ticks)
Add task with HRT timing parameters (HRT kernels only).
Definition stk_c.cpp:536
stk_kernel_state_t stk_kernel_get_state(const stk_kernel_t *k)
Get state of the scheduler.
Definition stk_c.cpp:413
void stk_task_destroy(stk_task_t *tsk)
Destroy dynamically created task object.
Definition stk_c.cpp:623
bool stk_sleep_until(stk_tick_t ts)
Put current task to sleep (non-HRT kernels only).
Definition stk_c.cpp:648
void stk_kernel_process_hard_fault(stk_kernel_t *k)
Trigger a kernel hard fault (safe-state handler).
Definition stk_c.cpp:522
int32_t stk_timeout_t
Timeout value.
Definition stk_c.h:118
void stk_critical_section_exit()
Leave global critical section - re-enable context switches.
Definition stk_c.cpp:688
void stk_delay(stk_timeout_t ticks)
Busy-wait delay (other tasks continue to run).
Definition stk_c.cpp:644
bool stk_kernel_is_schedulable(const stk_kernel_t *k)
Test whether currently configured task set is schedulable.
Definition stk_c.cpp:420
Namespace of STK package.
uintptr_t Word
Native processor word type.
Definition stk_common.h:146
static void Yield()
Notify scheduler to switch to the next runnable task.
Definition stk_helper.h:546
static void Sleep(Timeout tick_count)
Put calling process into a sleep state.
Definition stk_helper.h:483
static void SleepCancel(TId task_id)
Cancel sleep of the task.
Definition stk_helper.h:524
static void SleepMs(Timeout ms)
Put calling process into a sleep state.
Definition stk_helper.h:496
EAccessMode
Hardware access modes by the task.
Definition stk_common.h:36
@ ACCESS_USER
Unprivileged access mode (access to some hardware is restricted, see CPU manual for details)....
Definition stk_common.h:37
@ ACCESS_PRIVILEGED
Privileged access mode (access to hardware is fully unrestricted).
Definition stk_common.h:38
static Time GetTimeNowMs()
Get current time in milliseconds since kernel start.
Definition stk_helper.h:449
static void DelayMs(Timeout ms)
Delay calling process by busy-waiting until the deadline expires.
Definition stk_helper.h:619
int32_t Timeout
Timeout time (ticks).
Definition stk_common.h:156
static bool SleepUntil(Ticks timestamp)
Put calling process into a sleep state until the specified timestamp.
Definition stk_helper.h:508
static constexpr Weight DEFAULT_WEIGHT
Weight value: default weight of value (1) (see SwitchStrategySmoothWeightedRoundRobin).
Definition stk_common.h:230
static uint32_t GetTickResolution()
Get number of microseconds in one tick.
Definition stk_helper.h:372
static uint32_t GetSysTimerFrequency()
Get system timer frequency.
Definition stk_helper.h:472
static void Delay(Timeout tick_count)
Delay calling process by busy-waiting until the deadline expires.
Definition stk_helper.h:608
static Ticks GetTicks()
Get number of ticks elapsed since kernel start.
Definition stk_helper.h:438
static TId GetTid()
Get task/thread Id of the calling task.
Definition stk_helper.h:362
static Timeout GetTicksFromMsClampedToTimeout(Timeout ms)
Convert milliseconds to ticks and clamp the result to a Timeout type.
Definition stk_helper.h:423
static constexpr TId GetTidFromUserTask(const ITask *task) noexcept
Get task identifier from ITask instance.
Definition stk_arch.h:716
static Cycles GetSysTimerCount()
Get system timer count value.
Definition stk_helper.h:463
int32_t Weight
Weight value (aka priority).
Definition stk_common.h:176
bool IsPrivilegedContext()
Check if caller context is Privileged.
void InitializeTimerHost(stk_kernel_t *kernel, stk::time::TimerHost *th, EAccessMode amode)
Definition stk_c.cpp:64
static constexpr Session DEFAULT_SESSION
Default session value passed to Enter()/Exit() when the caller does not need to force a specific hand...
Definition stk_arch.h:478
static Session Enter(const Session ses=DEFAULT_SESSION)
Enter a critical section.
static void Exit(const Session ses=DEFAULT_SESSION)
Exit a critical section.
static uint32_t GetFrequency()
Get clock frequency.
static Ticks GetTimeUs()
Get elapsed time in microseconds.
Definition stk_arch.h:692
static Cycles GetCycles()
Get number of clock cycles elapsed.
Lightweight, non-owning view over a contiguous sequence of elements.
Definition stk_common.h:263
Interface for a user task.
Definition stk_common.h:780
virtual void ProcessTick()=0
Process one tick.
virtual Timeout Suspend()=0
Suspend scheduling.
virtual void Resume(Timeout elapsed_ticks)=0
Resume scheduling after a prior Suspend() call.
virtual void SetEventOverrider(IEventOverrider *overrider, bool non_secure=false)=0
Set platform event overrider.
virtual void ProcessHardFault()=0
Cause a hard fault of the system.
Interface for a platform event overrider.
Interface for the implementation of the kernel of the scheduler. It supports Soft and Hard Real-Time ...
EKernelState
Kernel state.
@ KSTATE_RUNNING
Initialized and running, IKernel::Start() was called successfully.
@ KSTATE_SUSPENDED
Scheduling is suspended with IKernelService::Suspend().
virtual void ResumeTask(ITask *user_task)=0
Resume task.
virtual void SuspendTask(ITask *user_task, bool &suspended)=0
Suspend task.
virtual IPlatform * GetPlatform()=0
Get platform driver instance.
virtual size_t EnumerateTasks(ArrayView< ITask * > user_tasks)=0
Enumerate user tasks.
virtual EKernelState GetState() const =0
Get a snapshot of the kernel state.
virtual void RemoveTask(ITask *user_task)=0
Remove a previously added task from the kernel when it is not started.
virtual void AddTask(ITask *user_task)=0
Add user task.
virtual void ScheduleTaskRemoval(ITask *user_task)=0
Schedule task removal from scheduling (exit).
virtual void Initialize(uint32_t resolution_us=PERIODICITY_DEFAULT)=0
Initialize kernel.
virtual void Start()=0
Start kernel scheduling.
static SchedulabilityCheckResult< TTaskCount > IsSchedulableWCRT(const ITaskSwitchStrategy *strategy)
Perform WCRT schedulability analysis on the task set registered with strategy.
RAII-style low-level synchronization primitive for atomic code execution. Used as building brick for ...
Definition stk_sync_cs.h:54
Software timer multiplexer that manages multiple Timer instances on top of a small fixed set of kerne...
void Initialize(IKernel *kernel, EAccessMode mode)
Initialize timer host instance.
C-level callback table that mirrors stk::IPlatform::IEventOverrider.
Definition stk_c.h:520
stk_word_t * m_stack
Definition stk_c.cpp:117
void SetName(const char *tname)
Definition stk_c.cpp:107
const char * m_tname
Definition stk_c.cpp:121
size_t GetStackSize() const override
Get number of elements of the stack memory array.
Definition stk_c.cpp:93
stk_task_entry_t m_func
Definition stk_c.cpp:115
EAccessMode m_mode
Definition stk_c.cpp:119
Weight m_weight
Definition stk_c.cpp:120
size_t m_stack_size
Definition stk_c.cpp:118
void * m_user_data
Definition stk_c.cpp:116
const char * GetTraceName() const override
Get task trace name set by application.
Definition stk_c.cpp:89
TaskWrapper()
Definition stk_c.cpp:77
void OnExit() override
Called by the kernel before removal from the scheduling (see stk::KERNEL_DYNAMIC).
Definition stk_c.cpp:145
~TaskWrapper()=default
Destructor.
int32_t GetWeight() const override
Get static base weight of the task.
Definition stk_c.cpp:88
const Word * GetStack() const override
Get pointer to the stack memory.
Definition stk_c.cpp:92
void SetWeight(Weight weight)
Definition stk_c.cpp:106
EAccessMode GetAccessMode() const override
Get pointer to the stack memory.
Definition stk_c.cpp:87
void Run() override
Entry point of the user task.
Definition stk_c.cpp:112
void Initialize(stk_task_entry_t const func, void *user_data, stk_word_t *stack, size_t stack_size, EAccessMode mode)
Definition stk_c.cpp:95
TaskWrapper handle
Definition stk_c.cpp:126
stk_task_t task
Definition stk_c.cpp:135
TaskSlot()
Definition stk_c.cpp:131
bool busy
Definition stk_c.cpp:134
bool OnSleep(Timeout sleep_ticks) override
Called by the Kernel when it is entering a sleep mode.
Definition stk_c.cpp:181
void SetCallback(stk_event_overrider_t *c)
Bind or unbind a C-level overrider struct.
Definition stk_c.cpp:174
bool OnHardFault() override
Called by Kernel when hard fault happens.
Definition stk_c.cpp:192
bool IsActive() const
Returns true when a C-level struct is currently bound.
Definition stk_c.cpp:178
~EventOverrider()=default
Destructor.
stk_event_overrider_t * m_cb
Definition stk_c.cpp:205
IKernel * kernel
Definition stk_c.cpp:213
EventOverrider event_cb
Definition stk_c.cpp:214