yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
ESP32 Core Board📖
1. ESP32 Introduction
  • 1. ESP32S3 Overview
  • 2. Environment Setup Introduction
  • 3. Dev Board Introduction
2. ESP-IDF Development Tutorial
1. Before Development
  • 1. Environment Setup (Windows)
  • 2. Environment Setup (Linux)
  • 3. Build and Flash
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. ESP_TIMER
  • 5. GPTIMER
  • 6. Watchdog Timer
  • 7. DMA
  • 8. ADC
  • 9. PWM Breathing LED
  • 10. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication Experiment
  • 2. I2C_OLED Display Experiment
  • 3. SPI Bus Communication Experiment
  • 4. PSRAM External Memory Experiment
  • 5. Flash Read and Write Experiment
  • 6. USB Emulated Mass Storage Experiment
4. FreeRTOS operating system
  • 1.FreeRTOS Core Concepts Theory
  • 2.Task Creation and Management
  • 3.Queue
  • 4.Binary Semaphore
  • 5.Mutex
  • 6.Event Groups
  • 7.Software Timer
  • 8.Task Scheduler
  • 9.Low Power Mode
  • 10.Deadlock
  • 11.Priority Inversion
5. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Client Experiment
  • 5. UDP Server Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. Socket Programming Basics
  • 9. HTTP Client Experiment
  • 10. HTTP Server Experiment
  • 11. MQTT IoT Communication Protocol
  • 12. WIFI OTA Upgrade
  • 13. Bluetooth Fundamentals
  • 14. Bluetooth Slave Mode
  • 15. Bluetooth Master Mode
6. Audio Applications
  • 1.I2S Microphone Recording and U-Disk Playback
  • 2.I2S Audio Playback Experiment
  • 3.Repeater Experiment
7. Xiaozhi AI Voice
  • 1. Burn Xiaozhi Firmware
  • 2. Network and Configuration
  • 3. AI Agent Settings
  • 4. Program Analysis
  • 5. Free Chat
3. Arduino Development Course
1. Before Development
  • 1. Environment Setup
  • 2. Build and Flash
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. ESP_TIMER
  • 5. GPTIMER
  • 6. Watchdog Timer
  • 7. ADC
  • 8. PWM Breathing LED
  • 9. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication
  • 2. I2C OLED Display
  • 3. SPI Bus Communication
  • 4. Flash Read and Write
  • 5. USB Emulated Mass Storage
4. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Server Experiment
  • 5. UDP Client Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. HTTP Client Experiment
  • 9. HTTP Server Experiment
  • 10. MQTT IoT Communication Protocol
  • 11. WIFI OTA Upgrade
  • 12. Bluetooth Fundamentals
  • 13. Bluetooth Slave Mode
  • 14. Bluetooth Master Mode
5. Audio Applications
  • 1.I2S Microphone Recording and U-Disk Playback
  • 2.I2S Audio Playback Experiment
  • 3.Repeater Experiment
4. MicroPython Development Course
1. Before Development
  • 1. Environment Setup
  • 2. Build and Flash
  • 3. Thonny IDE
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. TIMER_IT
  • 5. Watchdog Timer
  • 6. ADC
  • 7. PWM Breathing LED
  • 8. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication Experiment
  • 2. I2C_OLED Display Experiment
  • 3. SPI Bus Communication Experiment
  • 4. Flash Read and Write Experiment
  • 5. Print Storage
4. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Client Experiment
  • 5. UDP Server Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. HTTP Client Experiment
  • 9. HTTP Server Experiment
  • 10. MQTT
  • 11. Bluetooth Fundamentals
  • 12. Bluetooth Slave Mode
  • 13. Bluetooth Master Mode
5. Audio Applications
  • 1. I2S Audio Playback Experiment
  • 2. Repeater Experiment
Download
  • Code
  • Hardware_Info
  • 3D_Model_File
  • Software_Tools
  • VMware
  • VM_File
Download ZIP

Welcome to ESP32 Core Board repository

1.FreeRTOS Core Concepts Theory

FreeRTOS Core Concepts Theory

FreeRTOS Core Concepts (Theory)


FreeRTOS Core Concepts (Theory)1. What is RTOS1.1 Bare Metal vs RTOS1.2 Why Use RTOS2. Task2.1 What is a Task2.2 Task State Machine2.3 Task Creation2.4 Task Lifecycle Control2.5 Task Diagnostics3. Scheduler3.1 Scheduling Policy3.2 Priority3.3 Preemption Diagram3.4 Round-Robin Time Slice Diagram3.5 When Tasks Yield CPU4. Inter-Task Communication4.1 Five Mechanisms Overview4.2 Queue — FIFO Data Pipeline4.3 Binary Semaphore — ISR → Task Notification4.4 Mutex — Mutual Exclusion Lock4.5 Event Group — 24-bit Bitmap4.6 How to Choose: A Diagram5. Software Timer6. ESP32-S3 FreeRTOS Features7. Common Concurrency Problems7.1 Deadlock7.2 Priority Inversion7.3 Data Race8. FreeRTOS Configuration in ESP-IDF9. Learning Path Recommendations


1. What is RTOS

RTOS (Real-Time Operating System) is an operating system kernel designed specifically for embedded devices. Its core function is to schedule multiple tasks according to priority and time constraints, ensuring that critical tasks respond within specified time limits.

1.1 Bare Metal vs RTOS

FeatureBare Metal (Super Loop)RTOS
Program StructureOne big loop while(1), executes sequentiallyMultiple independent tasks, scheduler allocates CPU
Response LatencyDepends on other code execution time in loopHigher priority task preempts immediately when ready
CPU UtilizationOne blocking (e.g., delay) → entire program stopsOne task blocks → CPU automatically switches to other tasks
ComplexitySimple, suitable for single functionRequires understanding tasks, synchronization, priority
Code MaintainabilityMore features → "spaghetti code"Each task is independent module, clear responsibilities

1.2 Why Use RTOS

Imagine a smartwatch — the following pseudocode comparison shows execution differences between bare metal and RTOS in the same scenario:

​x
Bare Metal (Bare Metal) — all operations run sequentially in one loop:
  while(1) {
      readHeartRateSensor();    // takes 50ms
      refreshScreen();          // takes 80ms
      WiFiUploadData();         // takes 200ms, blocks touch during upload
      detectTouchButton();       // takes 5ms
  }

RTOS — each function is a separate task, scheduler assigns CPU by priority:
  Task HeartRate (Prio 4):   read sensor every 100ms
  Task Touch (Prio 3):       woken by touch, refreshes UI immediately
  Task WiFi (Prio 2):        uploads data in idle time
  Task Screen (Prio 1):      lowest priority, refreshes when CPU is free
  → touch always responsive, WiFi never blocks heart-rate reading

In bare metal programs, all code executes serially on a single timeline. RTOS splits the program into multiple independent tasks — blocking operations no longer waste CPU, urgent events no longer wait in queue.


2. Task

2.1 What is a Task

A task is the basic execution unit in FreeRTOS. Each task is a C function that never returns (infinite loop) with its own stack space.

Below is a minimal task skeleton: infinite loop + delay to yield CPU is the fixed pattern for FreeRTOS tasks.

xxxxxxxxxx
// Task function, never returns
void vMyTask(void *pvParameters)
{
    // Every task must be an infinite loop
    while (1) {
        // do work
        // block for 1 second, yield CPU
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

2.2 Task State Machine

FreeRTOS tasks transition between five states. The following state diagram shows all possible transition paths:

xxxxxxxxxx
   Created ──► Ready ──► Running ──► Blocked (waiting for event/delay)
               ▲                     │
                │        ┌────────────┘
                │        ▼
                ├── Suspended
                │
                └── Deleted
StateMeaningHow to Enter
ReadyReady, waiting for scheduler to allocate CPUAfter task creation / waiting event arrived
RunningCurrently executingOnly one per core at any time
BlockedBlockedvTaskDelay / waiting semaphore / waiting queue
SuspendedSuspended, not participating in schedulingvTaskSuspend() call
DeletedDeleted, memory reclaimedvTaskDelete() call

2.3 Task Creation

xTaskCreate is the core API for creating tasks. Below is the complete function signature and parameter descriptions:

xxxxxxxxxx
BaseType_t xTaskCreate(
    TaskFunction_t pvTaskCode,     // task function pointer
    // task name (for debugging, max 16 chars)
    const char * const pcName,
    // stack size in WORDS, not bytes
    uint32_t usStackDepth,
    // parameter passed to task
    void *pvParameters,
    // priority (higher = higher priority)
    UBaseType_t uxPriority,
    // task handle (pass NULL if not needed)
    TaskHandle_t *pxCreatedTask
);

// Pinned-to-core version
BaseType_t xTaskCreatePinnedToCore(..., BaseType_t xCoreID);
// Core 1 = APP_CPU (user application)

Stack size unit is WORDS, not bytes. On ESP32-S3, one word = 4 bytes. usStackDepth = 2048 means 2048 × 4 = 8192 bytes = 8KB.

2.4 Task Lifecycle Control

APIFunctionNotes
vTaskSuspend(handle)SuspendTask removed from Ready, no longer scheduled
vTaskResume(handle)ResumeMust be called on suspended task
vTaskDelete(handle)DeleteNULL = self-delete; cannot delete suspended tasks
vTaskDelay(ticks)Relative delayCalculated from call moment

2.5 Task Diagnostics

The following three diagnostic APIs are the most commonly used debugging tools during development — check priority, stack remaining, running core:

xxxxxxxxxx
// Query current task priority
UBaseType_t prio = uxTaskPriorityGet(NULL);

// Query remaining stack space (Stack High Water Mark)
// Stack high water mark (words), smaller = riskier
UBaseType_t remaining = uxTaskGetStackHighWaterMark(NULL);

// Query which core the current task is running on
int core = xPortGetCoreID();

3. Scheduler

3.1 Scheduling Policy

FreeRTOS uses fixed priority preemptive + same priority round-robin time slicing scheduling. The following three rules summarize the core logic of the entire scheduling policy:

xxxxxxxxxx
Rule 1 (Preemption):
  Higher priority task ready → immediately preempts lower priority task

Rule 2 (Time Slice):
  Same priority tasks ready → round-robin switch every tick

Rule 3 (Idle Fallback):
  No task ready → IDLE task runs (priority 0)

3.2 Priority

  • Value range: 0 ~ (configMAX_PRIORITIES - 1), default 0 ~ 24

  • Larger number = higher priority

  • IDLE task has fixed priority 0

  • ESP-IDF main task (running app_main) has default priority 1

3.3 Preemption Diagram

The following timeline shows how high priority tasks immediately preempt low priority tasks:

xxxxxxxxxx
  Prio 3 (High):   ............████████████............
  Prio 2 (Mid):    ....████████............████████....
  Prio 1 (Low):    ████................................
                   ↑             ↑              ↑
                Low runs    High preempts  High ends
                                         Low resumes

3.4 Round-Robin Time Slice Diagram

Multiple tasks of the same priority alternate execution by time slice, switching every tick:

xxxxxxxxxx
  Mid1 (Prio 2):   ████............████............
  Mid2 (Prio 2):   ....████............████............
                   ├─ 1 tick ─┤  kernel switches every tick

3.5 When Tasks Yield CPU

OperationDescription
vTaskDelay()Active delay, task enters Blocked
xSemaphoreTake() / xQueueReceive()Waiting for resource, task enters Blocked
Preempted by higher priority taskPassive yield, enters Ready
Same priority time slice expiredPassive yield, enters Ready

A high priority task that doesn't yield CPU will starve all lower priority tasks. High priority tasks must call vTaskDelay or blocking APIs at appropriate locations, otherwise the system essentially degrades to bare metal.


4. Inter-Task Communication

4.1 Five Mechanisms Overview

MechanismPurposeData CarriedTypical Scenario
QueuePass data between tasksAny size dataSensor data buffer, button events
Binary SemaphoreISR → task event notificationNoneGPIO interrupt notifies task to process
MutexMutual exclusion for shared resourcesNoneProtect global variables, peripheral registers
Event GroupMulti-event synchronization24-bit flagsWait for multiple conditions simultaneously
Task NotificationLightweight task wakeup32-bit valueSingle-to-single fast notification

4.2 Queue — FIFO Data Pipeline

FIFO data pipeline, standard way to pass data between tasks. The following code creates a queue with capacity 10 for unsigned 32-bit integers, and demonstrates basic send/receive usage:

xxxxxxxxxx
// 10 slots, 4 bytes each
QueueHandle_t xQueue = xQueueCreate(10, sizeof(uint32_t));

// send, 100ms timeout
xQueueSend(xQueue, &data, pdMS_TO_TICKS(100));
// receive, block indefinitely
xQueueReceive(xQueue, &data, portMAX_DELAY);

Blocking vs Non-blocking:

xTicksToWaitBehavior when queue full/emptyApplicable Scenario
0Return error immediatelyPaths that cannot wait
portMAX_DELAYBlock forever until space/data availableData must not be lost / event-driven receive

4.3 Binary Semaphore — ISR → Task Notification

Most commonly used for ISR → task notification. ISR is hardware interrupt service routine, cannot block, must complete quickly. Semaphore lets ISR only do "notification" and delegates actual processing to task.

xxxxxxxxxx
// Initial value = 0
SemaphoreHandle_t xSem = xSemaphoreCreateBinary();
xSemaphoreGiveFromISR(xSem, &xHigherPriorityTaskWoken);

// inside task:
// block until ISR notification
xSemaphoreTake(xSem, portMAX_DELAY);

Must use FromISR version in ISR: xSemaphoreGiveFromISR / xQueueSendFromISR etc. Calling normal API in ISR will trigger assert.

4.4 Mutex — Mutual Exclusion Lock

Protect shared resources, ensuring only one task enters critical section at a time. Key differences from binary semaphore:

FeatureMutexBinary Semaphore
PurposeMutual exclusion — protect dataSynchronization — event notification
Priority Inheritance✓✗
Who can give lockOnly the task that took itAny task can give
Use in ISR✗✓ (GiveFromISR)
Initial value1 (available)0 (blocking, waiting for event)

The following code uses mutex to protect increment operation of a global variable:

xxxxxxxxxx
// Create mutex
SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();

// Take lock — block if held
xSemaphoreTake(xMutex, portMAX_DELAY);
g_shared_var++;                           // ← critical section
xSemaphoreGive(xMutex);                   // Give lock back

4.5 Event Group — 24-bit Bitmap

24-bit bitmap, can wait for multiple events all ready or any ready. The following code creates an event group and waits for all event bits to be ready:

USB Emulated Mass Storage Experiment
Task Creation and Management

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文