Real-Time Operating Systems (Part 8)
RTOS Coding Examples in FreeRTOS
FreeRTOS is a lightweight RTOS widely used in embedded systems. Below are practical coding examples to demonstrate its core features:
1. Task Creation
#include "FreeRTOS.h"
#include "task.h"
void vTask1(void *pvParameters) {
for (;;) {
// Task 1 code here
}
}
void vTask2(void *pvParameters) {
for (;;) {
// Task 2 code here
}
}
int main(void) {
xTaskCreate(vTask1, "Task 1", 100, NULL, 1, NULL);
xTaskCreate(vTask2, "Task 2", 100, NULL, 2, NULL);
vTaskStartScheduler();
return 0;
}
This example demonstrates creating two tasks with different priorities.
2. Inter-Task Communication (Queues)
#include "FreeRTOS.h"
#include "queue.h"
QueueHandle_t xQueue;
void vSenderTask(void *pvParameters) {
int valueToSend = 100;
for (;;) {
xQueueSend(xQueue, &valueToSend, portMAX_DELAY);
}
}
void vReceiverTask(void *pvParameters) {
int receivedValue;
for (;;) {
xQueueReceive(xQueue, &receivedValue, portMAX_DELAY);
}
}
int main(void) {
xQueue = xQueueCreate(5, sizeof(int));
xTaskCreate(vSenderTask, "Sender", 100, NULL, 1, NULL);
xTaskCreate(vReceiverTask, "Receiver", 100, NULL, 2, NULL);
vTaskStartScheduler();
return 0;
}
Queues enable efficient communication between tasks, as shown above.
3. Synchronization with Semaphores
#include "FreeRTOS.h"
#include "semphr.h"
SemaphoreHandle_t xSemaphore;
void vTask(void *pvParameters) {
for (;;) {
if (xSemaphoreTake(xSemaphore, portMAX_DELAY) == pdTRUE) {
// Critical section code
xSemaphoreGive(xSemaphore);
}
}
}
int main(void) {
xSemaphore = xSemaphoreCreateBinary();
xSemaphoreGive(xSemaphore);
xTaskCreate(vTask, "Task", 100, NULL, 1, NULL);
vTaskStartScheduler();
return 0;
}
Semaphores ensure safe access to shared resources in a multitasking environment.
These examples illustrate FreeRTOS’s versatility in managing tasks, communication, and synchronization in embedded systems.
RTOS Coding Examples in Zephyr
Zephyr RTOS is an open-source platform designed for IoT and embedded applications. Here are practical examples showcasing its functionality:
1. Thread Creation
#include
void thread1(void) {
while (1) {
// Thread 1 code here
k_msleep(1000);
}
}
void thread2(void) {
while (1) {
// Thread 2 code here
k_msleep(500);
}
}
K_THREAD_DEFINE(t1, 512, thread1, NULL, NULL, NULL, 1, 0, 0);
K_THREAD_DEFINE(t2, 512, thread2, NULL, NULL, NULL, 2, 0, 0);
This code demonstrates creating two threads with different priorities using Zephyr’s thread management APIs.
2. Message Queue
#include
#include
K_MSGQ_DEFINE(my_msgq, sizeof(int), 10, 4);
void sender_thread(void) {
int data = 42;
while (1) {
k_msgq_put(&my_msgq, &data, K_FOREVER);
k_msleep(1000);
}
}
void receiver_thread(void) {
int received_data;
while (1) {
k_msgq_get(&my_msgq, &received_data, K_FOREVER);
printk("Received: %d\n", received_data);
}
}
K_THREAD_DEFINE(sender, 512, sender_thread, NULL, NULL, NULL, 1, 0, 0);
K_THREAD_DEFINE(receiver, 512, receiver_thread, NULL, NULL, NULL, 2, 0, 0);
Message queues in Zephyr facilitate structured communication between threads, as illustrated here.
3. Synchronization Using Semaphores
#include
#include
struct k_sem my_semaphore;
void thread_with_semaphore(void) {
while (1) {
k_sem_take(&my_semaphore, K_FOREVER);
// Critical section code
printk("Semaphore Acquired\n");
k_sem_give(&my_semaphore);
k_msleep(1000);
}
}
K_THREAD_DEFINE(thread_sem, 512, thread_with_semaphore, NULL, NULL, NULL, 1, 0, 0);
void main(void) {
k_sem_init(&my_semaphore, 1, 1);
}
This example highlights the use of semaphores for synchronization in Zephyr RTOS.
Zephyr’s APIs offer robust features for managing multitasking, synchronization, and inter-thread communication in embedded systems.
CPU Requirements and Hardware Compatibility
Real-Time Operating Systems (RTOS) are designed to run on a wide range of hardware platforms, from simple microcontrollers to high-end processors. Understanding the CPU requirements is essential for selecting suitable hardware.
1. Minimum CPU Specifications
Most RTOS can run on minimal hardware. For example:
- FreeRTOS: Requires 2 KB RAM and 8 KB flash, compatible with ARM Cortex-M0+ and AVR processors.
- Zephyr: Needs around 8 KB RAM and 32 KB flash, supporting ARM, RISC-V, and x86 architectures.
2. Hardware Compatibility
RTOS compatibility varies with processor families. Examples include:
- VxWorks: Optimized for x86, PowerPC, and ARM architectures, suitable for high-performance applications.
- QNX: Supports ARM Cortex-A, x86, and MIPS, widely used in automotive systems.
3. Common Misconceptions
Despite popular myths, RTOS does not require high-end hardware. For instance:
- Low-cost microcontrollers like ESP32 and STM32 can run FreeRTOS efficiently.
- Zephyr runs seamlessly on Nordic Semiconductor SoCs for IoT applications.
4. Real-Time Performance Metrics
Consider metrics such as interrupt latency, context switch time, and power consumption when evaluating hardware for RTOS. High-end processors may offer better performance but are unnecessary for many use cases.
By matching RTOS requirements with hardware capabilities, developers can optimize performance and cost for their specific applications.