Bear bones realtime operating system for embedded systems. Focus lies on KISS (Keep-It-Super-Simple).
Read the ⇥ Getting Started when you want to use the OS in your project.
Supported Microcontrollers: The device name is also the name of the global
#define
which enables the particular MCU.
- STM®
Device | Core | FPU | Header |
---|---|---|---|
STM32F405xx | ARM Cortex M4® | :x: | arm_cm4_nofpu.h |
STM32F429xx | ARM Cortex M4® | :x: | arm_cm4_nofpu.h |
STM32L053xx | ARM Cortex M0+® | :x: | arm_cm0plus_nofpu.h |
STM32L071xx | ARM Cortex M0+® | :x: | arm_cm0plus_nofpu.h |
STM32L072xx | ARM Cortex M0+® | :x: | arm_cm0plus_nofpu.h |
STM32L073xx | ARM Cortex M0+® | :x: | arm_cm0plus_nofpu.h |
Device | Core | FPU | Header |
---|---|---|---|
- |
Name | Status | Description |
---|---|---|
main | active |
Main branch for working on releases |
dev | active |
Main branch for developing |
You want to use the OTOS operating system in your project? Awesome! :sunglasses:
Here are the main steps to get up and running:
The kernel is automatically initialized when the kernel object is created:
// Create the kernel object
OTOS::Kernel OS;
Each thread handles one task. You can bundle multiple actions in one task, or use separate tasks for each action. The tasks are scheduled using their function name:
// Schedule task with the function name MyTask and a stack size of 128 bytes
OS.schedule_thread<128>(&MyTask, OTOS:Priority::Normal);
When you do not give an execution rate, the task will run whenever it is possible to run it. That means:
To define a execution frequency the task is allowed to execute use this task constructor:
// Schedule task with the function name MyTask and run it with 10 Hz
OS.schedule_thread<128>(&MyTask, OTOS:Priority::Normal, 10);
The OS does not implement a preemptive scheduling (yet). So your scheduled task has to periodically yield its execution and tell the OS that another task can be executed.
// Tell the OS that it can give the control to another task
OTOS::Thread::yield();
You can use Timed_Task
for timing within tasks.
The function will use the yield()
function for waiting and timing.
Currently, only the SysTick timer is used as a time base, but you can give the task any function handle which returns a time as an integer type.
To create a task using the SysTick timer use this:
// Create a timed task using SysTick as the timebase
OTOS::TimedTask MyTask(OTOS::get_time_ms);
The function get_time_ms()
is a static class method of the OTOS kernel and can be called from anywhere to get the current time in [ms] since the system was started.
:warning: The SysTick Interrupt has to be enabled!
Within the SysTick interrupt execute the following kernel timing functions:
/**
* @brief Provide a Interrupt handler for the systick timer,
* which gets called every 1 ms.
*/
extern "C" void SysTick_Handler(void)
{
OS.count_time_ms();
OS.update_schedule();
};
In the main function configure the interrupt using the following function:
// Configure SysTick timer for interrupts every 1 ms
timer::SysTick_Configure();
The function takes the configured CPU clock into account and configures the SysTick interrupt for an interrupt every 1ms.
Once all threads are scheduled, you can start the kernel execution with:
// Start the kernel and execute the threads
OS.start();