OS Abstraction Layer (OSAL)ΒΆ
OverviewΒΆ
OSAL provides a portable interface for RTOS primitives. Applications can switch between different RTOS backends (FreeRTOS, RT-Thread, Zephyr) or run bare-metal without code changes.
Key features:
Unified API across multiple RTOS backends
Bare-metal support for resource-constrained systems
Task, mutex, semaphore, queue, and timer primitives
Critical section and interrupt management
Memory allocation abstraction
Supported BackendsΒΆ
Backend |
Status |
Notes |
|---|---|---|
Bare-metal |
β Ready |
Cooperative |
FreeRTOS |
β Ready |
Full support |
RT-Thread |
π§ Planned |
|
Zephyr |
π§ Planned |
Getting StartedΒΆ
Include the header:
#include "osal/osal.h"
Initialize OSAL:
osal_init();
Task ManagementΒΆ
Create a task:
void my_task(void* arg)
{
while (1) {
/* Task code */
osal_task_delay(100);
}
}
osal_task_config_t cfg = {
.name = "my_task",
.func = my_task,
.arg = NULL,
.stack_size = 1024,
.priority = OSAL_PRIORITY_NORMAL,
};
osal_task_handle_t handle;
osal_status_t status = osal_task_create(&cfg, &handle);
Task control:
/* Delay current task */
osal_task_delay(100); /* 100 ms */
/* Suspend task */
osal_task_suspend(handle);
/* Resume task */
osal_task_resume(handle);
/* Delete task */
osal_task_delete(handle);
/* Get current task handle */
osal_task_handle_t current = osal_task_get_current();
MutexΒΆ
Create and use mutex:
osal_mutex_handle_t mutex;
osal_mutex_create(&mutex);
/* Lock with timeout */
if (osal_mutex_lock(mutex, 1000) == OSAL_OK) {
/* Critical section */
/* ... */
/* Unlock */
osal_mutex_unlock(mutex);
}
/* Lock forever */
osal_mutex_lock(mutex, OSAL_WAIT_FOREVER);
/* Try lock (non-blocking) */
if (osal_mutex_lock(mutex, 0) == OSAL_OK) {
/* Got the lock */
}
/* Delete when done */
osal_mutex_delete(mutex);
SemaphoreΒΆ
Binary semaphore:
osal_sem_handle_t sem;
osal_sem_create_binary(0, &sem); /* Initial count = 0 */
/* Wait (take) */
osal_sem_take(sem, OSAL_WAIT_FOREVER);
/* Signal (give) */
osal_sem_give(sem);
/* Delete */
osal_sem_delete(sem);
Counting semaphore:
osal_sem_handle_t sem;
osal_sem_create_counting(10, 0, &sem); /* max=10, initial=0 */
/* Take multiple */
osal_sem_take(sem, 1000);
/* Give multiple */
osal_sem_give(sem);
/* Get current count */
uint32_t count = osal_sem_get_count(sem);
Message QueueΒΆ
Create and use queue:
typedef struct {
uint32_t id;
uint32_t data;
} message_t;
osal_queue_handle_t queue;
osal_queue_create(sizeof(message_t), 10, &queue);
/* Send message */
message_t msg = { .id = 1, .data = 42 };
osal_queue_send(queue, &msg, OSAL_WAIT_FOREVER);
/* Send to front (high priority) */
osal_queue_send_front(queue, &msg, 1000);
/* Receive message */
message_t received;
osal_queue_receive(queue, &received, OSAL_WAIT_FOREVER);
/* Check available messages */
uint32_t count = osal_queue_get_count(queue);
/* Delete */
osal_queue_delete(queue);
Software TimerΒΆ
Create and use timer:
void timer_callback(void* arg)
{
/* Timer expired */
}
osal_timer_handle_t timer;
osal_timer_create("my_timer", timer_callback, NULL,
1000, /* Period: 1000 ms */
true, /* Auto-reload */
&timer);
/* Start timer */
osal_timer_start(timer);
/* Stop timer */
osal_timer_stop(timer);
/* Change period */
osal_timer_set_period(timer, 500);
/* Delete */
osal_timer_delete(timer);
Critical SectionsΒΆ
Disable/enable interrupts:
osal_enter_critical();
/* Interrupts disabled - keep this section short! */
/* ... */
osal_exit_critical();
Nested critical sections:
uint32_t state = osal_interrupt_disable();
/* Interrupts disabled */
/* ... */
osal_interrupt_restore(state);
Memory ManagementΒΆ
Dynamic allocation:
void* ptr = osal_malloc(1024);
if (ptr) {
/* Use memory */
osal_free(ptr);
}
/* Aligned allocation */
void* aligned = osal_malloc_aligned(1024, 32);
osal_free_aligned(aligned);
Time FunctionsΒΆ
Get system time:
/* Get tick count */
uint32_t ticks = osal_get_tick_count();
/* Get milliseconds */
uint32_t ms = osal_get_time_ms();
/* Delay */
osal_delay_ms(100);
Error HandlingΒΆ
All OSAL functions return osal_status_t:
osal_status_t status = osal_mutex_create(&mutex);
if (status != OSAL_OK) {
/* Handle error */
}
Common status codes:
OSAL_OK- SuccessOSAL_ERR_PARAM- Invalid parameterOSAL_ERR_TIMEOUT- Operation timeoutOSAL_ERR_NO_MEM- Out of memoryOSAL_ERR_ISR- Called from ISR context
Bare-metal ConsiderationsΒΆ
When using the bare-metal backend:
Tasks run cooperatively (no preemption)
osal_task_delay()uses busy-waitMutexes use simple flags (no priority inheritance)
Queues use ring buffers
Call
osal_scheduler_run()in main loop
int main(void)
{
osal_init();
/* Create tasks */
osal_task_create(&task1_cfg, &task1);
osal_task_create(&task2_cfg, &task2);
/* Run scheduler (bare-metal) */
osal_scheduler_run();
return 0;
}
API ReferenceΒΆ
See OSAL API Reference for complete API documentation.