Skip to content
/ stk Public

Minimalistic C++ thread scheduling kernel for Embedded systems. Supports ARM Cortex-M and RISC-V MCUs with debugging possibility on conventional x86. Compiles with GCC. Comes with examples for Eclipse. Can be used on any embedded system with limited RAM and FLASH resources.

License

Notifications You must be signed in to change notification settings

dmitrykos/stk

Repository files navigation

SuperTinyKernel (STK)

Minimalistic thread scheduling kernel for the Embedded systems.

About

STK tends to me as minimal as possible to be able to provide a multi-threading capability for your Embedded system without any attempt to abstract operations with peripherals. It does not pretent to be a Real-Time OS (RTOS) but instead it gives possibility to add multi-threading into a bare-metal project with a very little effort.

STK is developed in C++ and follows an Object-Oriented Design principles while at the same time does not pollute namespace with exceeding declarations, nor using fancy new C++ features. It just tries to be very friendly to C developers ;)

Features

STK supports soft real-time (default) and hard-real time (HRT) modes of operation. It supports infinite looping (KERNEL_STATIC), finite (KERNEL_DYNAMIC) and periodic (HRT mode - KERNEL_HRT) tasks.

STK intercepts main process program flow if it is in KERNEL_STATIC mode but it can also return into the main process when all tasks exited in case of KERNEL_DYNAMIC mode.

HRT mode allows to run periodic tasks which can be finite or infinite depending on whether KERNEL_STATIC or KERNEL_DYNAMIC mode is used in addition to the KERNEL_HRT. HRT tasks are checked for a deadline miss by STK automatically therefore it guarantees a fully deterministic behavior of the application.

STK's run-time performance is comparable to other well known C-based thread scedulers but its code base is much slimmer and therefore easier to test, maintain and advance.

Hardware support

MCU

  • Arm Cortex-M0
  • Arm Cortex-M3
  • Arm Cortex-M4
  • Arm Cortex-M7

Floating point

  • Soft, Hard

Requires

  • CMSIS
  • Vendor BSP (NXP, STM, ...)

Example

Here is an example to toggle Red, Green, Blue LEDs of the NXP FRM-K66F or STM STM32F4DISCOVERY development boards hosting Arm Cortex-M4F CPU where thread is handling its own LED, e.g. there are 3 threads in total which are switching LEDs with 1 second periodicity.

#include <stk_config.h>
#include <stk.h>
#include "example.h"

static volatile uint8_t g_TaskSwitch = 0;

template <stk::EAccessMode _AccessMode>
class MyTask : public stk::Task<256, _AccessMode>
{
    uint8_t m_taskId;

public:
    MyTask(uint8_t taskId) : m_taskId(taskId) {}
    stk::RunFuncType GetFunc() { return &Run; }
    void *GetFuncUserData() { return this; }

private:
    static void Run(void *user_data)
    {
        ((MyTask *)user_data)->RunInner();
    }

    void RunInner()
    {
        uint8_t task_id = m_taskId;

        float count = 0;
        uint64_t count_skip = 0;

        while (true)
        {
            if (g_TaskSwitch != task_id)
            {
                ++count_skip;
                continue;
            }

            ++count;

            switch (task_id)
            {
            case 0:
                LED_SET_STATE(LED_RED, true);
                LED_SET_STATE(LED_GREEN, false);
                LED_SET_STATE(LED_BLUE, false);
                break;
            case 1:
                LED_SET_STATE(LED_RED, false);
                LED_SET_STATE(LED_GREEN, true);
                LED_SET_STATE(LED_BLUE, false);
                break;
            case 2:
                LED_SET_STATE(LED_RED, false);
                LED_SET_STATE(LED_GREEN, false);
                LED_SET_STATE(LED_BLUE, true);
                break;
            }

            g_KernelService->Sleep(delay_ms);

            g_TaskSwitch = (task_id + 1) % 3;
        }
    }
};

static void InitLeds()
{
    LED_INIT(LED_RED, false);
    LED_INIT(LED_GREEN, false);
    LED_INIT(LED_BLUE, false);
}

void RunExample()
{
    using namespace stk;

    InitLeds();

    static Kernel<KERNEL_STATIC, 3, SwitchStrategyRoundRobin, PlatformDefault> kernel;
    static MyTask<ACCESS_PRIVILEGED> task1(0), task2(1), task3(2);

    kernel.Initialize();

    kernel.AddTask(&task1);
    kernel.AddTask(&task2);
    kernel.AddTask(&task3);

    kernel.Start(PERIODICITY_DEFAULT);

    assert(false);
    while (true);
}

Test boards

Build

It is fairly easy to build and run examples without even having embedded hardware on your hands. You will need these tools to run examples on your PC:

Arm platform:

In case of NXP MCU you will only need MCUXpresso IDE which is comes with bundled GCC compler.

RISC-V platform:

If you are working with only Arm platform then you only need Arm-related tools.

Generic eclipse examples are located in the build/example/project/eclipse folder and sorted by platform:

  • stm - Arm platform, examples based on STM32 microcontrollers and can be executed on QEMU virtual machine or directly on hardware if you have corresponding board.
  • risc-v - RISC-V platform, examples based on QEMU virtual machine.
  • x86 - x86 platform, examples are executed on x86 CPU.

Additionally, examples for NXP MCUXpresso IDE are provided in build/example/project/nxp-mcuxpresso folder. These examples are compatible with NXP Kinetis® K66, Kinetis® K26 and NXP i.MX RT1050 MCUs and can be executed directly on corresponding evaluation boards.

Porting

You are welcome to port STK to a new platform and offer a patch. The platform dependent files are located in: stk/src/arch and stk/include/arch folders.

Origin

STK proved to be a very competitive C++ thread scheduler implementation for the embedded platform compared to the well-known thread scheduler implemented purely in C.

Here you can learn more details about how it was designed, developed, tested and benchmarked. You will also get a useful insight about C++ usage in Embedded software development - what impacts are on a source code development, binary size and run-time performance.

If you found useful pieces of information for your own work, please cite it as follows:

Dmitrijs Kostjučenko, "Using C++ versus legacy C in the Embedded software 
development", MSc Dissertation, Software Engineering, Kellogg College,
University of Oxford, 2023

About

Minimalistic C++ thread scheduling kernel for Embedded systems. Supports ARM Cortex-M and RISC-V MCUs with debugging possibility on conventional x86. Compiles with GCC. Comes with examples for Eclipse. Can be used on any embedded system with limited RAM and FLASH resources.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages