1. Overview of FreeRTOS
FreeRTOS is a lightweight, open-source real-time operating system suitable for embedded systems. It provides features such as task scheduling, synchronization, and communication, characterized by its portability, configurability, and efficiency, making it widely used in resource-constrained embedded devices.
2. FreeRTOS File Structure
(1) Source Folder
This contains the core source code of FreeRTOS, which is the core implementation part of FreeRTOS. Different folders and files serve different functions:
-
include folder: Header files that must be included for portability.
-
portable folder: Hardware-related portability code. Different compilers and MCUs have different implementations, such as Keil, RVDS, etc.
-
portable/MemMang: Memory management schemes, with heap_4.c being commonly used.
-
Other files: Task scheduling, time management, list operations, queue management, etc.
(2) Portable Folder
This serves as a bridge connecting FreeRTOS with hardware, allowing FreeRTOS to run on different hardware platforms.
(3) MemMang Folder
This is the memory management module, providing five schemes. heap_4.c is flexible and efficient, often chosen.
(4) FreeRTOSConfig.h
This is a critical configuration file that defines macros to configure system functions and behaviors. Modifications are required based on project needs during portability, such as clock frequency, number of priorities, feature toggles, etc.
3. FreeRTOS Coding Style
(1) Variable Naming Conventions
-
portBASE_TYPE → x prefix: For example,
<span>xTask</span>indicates task-related variables. -
char type variables → c prefix: For example,
<span>cTaskName</span>indicates a character variable for task names. -
char type pointers → pc prefix: For example,
<span>pcTaskName</span>indicates a character pointer for task names.
(2) Function Naming Conventions
-
Private functions → prv prefix: For example,
<span>prvTaskFunction</span>indicates a private function for tasks. -
Specific module functions: For example, functions returning void in queue.c → vQueue prefix: For example,
<span>vQueueAddToQueue</span>indicates a function that adds data to a queue.
(3) Macro Definition Naming Conventions
-
Macros in the port module → port prefix: For example,
<span>portTICK_PERIOD_MS</span>indicates the tick period macro.
(4) Code Formatting Standards
-
Set TAB to 4 spaces: This facilitates code readability and formatting, maintaining code consistency.
4. The Essence of FreeRTOS and Task Management
(1) Essence of RTOS
RTOS is a thread manager, where threads are functions that can be executed repeatedly, exhibiting concurrent execution characteristics (actually time-sliced execution). Its core functions are to manage task scheduling, synchronization, and communication, ensuring multiple tasks can run efficiently.
(2) Task Switching Mechanism
Task switching requires saving the TCB (Task Control Block) of the interrupted task, which records the task’s state and context. The <span>SysTick</span> interrupt is the key mechanism for task switching, providing timing signals that trigger task switching scheduling.
(3) Task State Management
-
Running State: The task is currently using the CPU for execution.
-
Ready State: The task is ready to run, waiting to acquire CPU resources.
-
Blocked State: The task cannot execute due to waiting for events or delays, such as calling
<span>vTaskDelay</span>or waiting for queues, semaphores, etc. -
Suspended State: The task is suspended and does not participate in scheduling; it must be called to resume to become ready again.
(4) Task Priority
The range of task priorities is from 0 to <span>configMAX_PRIORITIES-1</span>. By setting <span>configUSE_TIME_SLICING</span> to 1, time-slice round-robin scheduling can be achieved for all tasks at the same priority level.
5. Creating and Managing FreeRTOS Tasks
(1) Creating Dynamic Tasks
xTaskCreate( TaskFunction_t pxTaskCode, // Task function const char * const pcName, // Task name const uint32_t usStackDepth, // Task stack size (in words) void * const pvParameters, // Parameters passed to the task function UBaseType_t uxPriority, // Task priority TaskHandle_t * const pxCreatedTask // Task handle);
Return value:<span>pdPASS</span> (task created successfully), <span>errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY</span> (task creation failed due to insufficient heap memory).
(2) Creating Static Tasks
xTaskCreateStatic( TaskFunction_t pxTaskCode, // Task function const char * const pcName, // Task name const uint32_t ulStackDepth, // Task stack size (in words) void * const pvParameters, // Parameters passed to the task function UBaseType_t uxPriority, // Task priority StackType_t * const puxStackBuffer, // Static stack buffer StaticTask_t * const pxTaskBuffer // Static task control block);
Return value: Task handle (task created successfully), <span>NULL</span> (task creation failed, stack or control block buffer is <span>NULL</span>).
(3) Deleting Tasks
vTaskDelete(TaskHandle_t xTaskToDelete);
This deletes the task with the specified handle and releases resources.
(4) Suspending and Resuming Tasks
vTaskSuspend(TaskHandle_t xTaskToSuspend); // Suspend taskvTaskResume(TaskHandle_t xTaskToResume); // Resume task
Suspending a task puts it into the blocked state, while resuming a task brings it back to the ready state.
6. Task Stack Management
The task stack is used to store local variables, register values, and other information during task execution. When dynamically creating tasks, the stack memory is allocated by FreeRTOS; for statically created tasks, the user must provide more flexible stack management, suitable for embedded systems with strict memory requirements.
7. Conclusion
FreeRTOS is a powerful, highly portable, and configurable real-time operating system suitable for embedded system development. It provides a rich API for task management, synchronization, communication, and more, with good community support and a wide range of hardware platform porting cases. With proper configuration and optimization, FreeRTOS can meet the needs of most embedded systems, helping developers efficiently create real-time applications with high requirements.