BeeRTOS is a lightweight, efficient, and scalable real-time operating system (RTOS) specifically designed for embedded systems. With a focus on simplicity, low memory consumption, and speed of operation, BeeRTOS provides a robust solution for managing concurrent tasks in microcontroller-based applications. It provides multitasking, synchronization primitives, inter-task communication, and timing services, all configurable to fit specific application requirements.
- Simplicity: BeeRTOS offers an intuitive API and straightforward task management, making it accessible for developers of all experience levels.
- Low Memory Consumption: Optimized to require minimal memory resources, ensuring that even devices with limited RAM/ROM can run efficiently.
- Speed of Operation: Designed for fast context switching and efficient task scheduling.
- Preemptive Multitasking: Supports concurrent execution of multiple tasks, leveraging CPU resources effectively.
- Modular Design: Easily extendable and adaptable to various hardware platforms.
- Inter-Task Communication: Use message queues and signals for communication between tasks.
- Synchronization Primitives: Mutexes with priority ceiling protocol and semaphores for task synchronization.
- Timing Services: Utilize alarms for scheduling actions at specific times or intervals.
BeeRTOS's behavior and capabilities can be tailored through the BeeRTOS_cfg.h
configuration header. This file allows for the enabling or disabling of OS modules, the configuration of system tasks, and the setup of synchronization primitives and communication mechanisms, all without the need for dynamic memory allocation.
You can enable or disable specific OS modules to optimize the runtime environment according to your project's needs. This modular approach ensures that you only include the necessary components, contributing to a smaller memory footprint.
- Alarm Module: Allows for the scheduling of tasks or callbacks at specific intervals or points in time.
- Message Module: Enables inter-task communication through messages, facilitating data exchange between tasks.
- Queue Module: Similar to messages but more flexible, queues support FIFO communication patterns with variable data types.
- Mutex Module: Provides mutual exclusion capabilities to prevent simultaneous access to shared resources, with support for priority inheritance to avoid priority inversion problems.
- Semaphore Module: Offers a mechanism for synchronizing tasks, including binary and counting semaphores for various use cases.
#define OS_ALARM_MODULE_EN (true)
#define OS_MESSAGE_MODULE_EN (true)
#define OS_QUEUE_MODULE_EN (true)
#define OS_MUTEX_MODULE_EN (true)
#define OS_SEMAPHORE_MODULE_EN (true)
The OS_PRIORITY_LIST() macro is used to define tasks, mutexes, and alarms.
The priority of tasks is determined by their order in the OS_PRIORITY_LIST() macro. The first task listed has the highest priority, and the ones that follow have lower priorities. This order affects how the system schedules tasks, with higher priority tasks interrupting lower priority ones.
BeeRTOS automatically generates IDs for tasks, mutexes, and alarms as enum types based on their definitions in the OS_PRIORITY_LIST() macro. This makes it easier to refer to tasks and synchronization elements in the application code.
Each task is defined using the macro:
OS_TASK(task_id, function, stacksize, autostart, task_arg)
The structure of a task definition is as follows:
- task_id: A unique identifier for the task. This ID is used internally by BeeRTOS for task management and scheduling.
- function: The main function that the task will execute. This function must adhere to a specific signature defined by BeeRTOS.
- stacksize: The size of the stack allocated for the task. Stack size should be carefully chosen based on the task's needs to avoid stack overflows while minimizing memory usage.
- autostart: A boolean value indicating whether the task should start automatically upon system initialization (true) or if it should be started manually at a later time (false).
- task_arg: A pointer to any arguments that should be passed to the task function. This allows for flexible task configuration and initialization.
The priority ceiling mechanism in BeeRTOS requires the specification of mutex priorities. This prevents priority inversion, where a lower priority task holds a mutex needed by a higher priority task. The priority ceiling protocol raises the priority of the task holding the mutex to the highest level of any task that may use it, ensuring timely mutex release.
The OS_MUTEX() macro is used similarly for mutexes configuration.
OS_MUTEX(mutex_id, initial_count)
- mutex_id: A unique identifier for the mutex.
- initial_count: The initial count for the mutex. For binary mutexes, this is usually set to 0 or 1.
Alarm tasks are special tasks used for timing and scheduling purposes. They can trigger actions at set intervals or after a certain amount of time. Alarm tasks are configured using the OS_ALARM_TASK() macro:
OS_ALARM_TASK(task_id, stacksize)
- task_id: A unique identifier for the alarm task.
- stacksize: The size of the stack allocated for the alarm task.
In BeeRTOS_cfg.h, semaphores are defined using the OS_SEMAPHORE_LIST() macro. This macro allows for the creation of both binary and counting semaphores, specifying their initial count and type (binary or counting).
OS_SEMAPHORE(semaphore_id, initial_count, type)
- semaphore_id: Unique identifier for the semaphore.
- initial_count: Initial semaphore count. For binary semaphores, this is typically set to 0 (locked) or 1 (unlocked).
- type: Specifies the semaphore type, which can be either binary (SEMAPHORE_TYPE_BINARY) or counting (SEMAPHORE_TYPE_COUNTING). This parameter dictates how the semaphore behaves when incremented beyond 1.
Messages enable data passing between tasks, facilitating inter-task communication. Messages are more specific than queues and are used to transfer discrete data items. Messages provide a structured way to exchange data between tasks, encapsulating the data in defined formats.
OS_MESSAGE(message_id, messages_count, message_size)
- message_id: Unique identifier for the message queue.
- messages_count: The maximum number of messages that the queue can hold.
- message_size: The size of each message in bytes. This defines how large an individual message can be.
Queues in BeeRTOS allow FIFO (First In, First Out) communication between tasks. They can transfer byte streams, data structures, or pointers between tasks.
OS_QUEUE(queue_id, queue_size)
- queue_id: Unique identifier for the queue.
- queue_size: Specifies the maximum number of elements (or bytes, depending on the queue implementation) that the queue can store. This defines the capacity of the queue.
Alarm tasks are special tasks used for timing and scheduling purposes. They can trigger actions at set intervals or after a certain amount of time.
OS_ALARM(alarm_id, callback, autostart, default_period, periodic)
- alarm_id: Unique identifier for the alarm.
- callback: The function to be called when the alarm expires.
- autostart: Determines whether the alarm starts automatically upon system initialization. Set to true for automatic start.
- default_period: The default period of the alarm in system ticks. This is relevant only if autostart is true.
- periodic: Indicates whether the alarm is periodic (true) or one-shot (false). Periodic alarms reset after expiration, whereas one-shot alarms need to be manually restarted.