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

5.Mutex

Mutex

Mutex


Mutex1. Mutex Overview1.1 What is a Mutex1.2 Importance and Application Scenarios1.3 This Project Demonstrates2. Core Concepts2.1 How Mutex Works2.2 Mutex API2.3 Mutex vs Binary Semaphore2.4 Shared Resource Protection Principles3. Project Architecture and Flow4. Hardware Dependencies5. Source Code Analysis5.1 Header Files and Macro Configuration5.2 key_init() — Button GPIO Initialization5.3 rgb_init() — WS2812 LED Initialization5.4 rgb_set() / rgb_rainbow_loop() / rgb_red_loop() — LED Display Functions5.5 check_winner() — Win Condition Check5.6 vProducer() — Producer Task5.7 vConsumer1_Human() — Human Consumer5.8 vConsumer2_AI() — AI Consumer5.9 app_main() — Main Entry6. Operation Flow6.1 Compilation and Flashing Flow6.2 Normal Operation6.3 Edge Cases7. FAQ


1. Mutex Overview

1.1 What is a Mutex

Mutex is FreeRTOS's core mechanism for protecting shared resources. When multiple tasks need to access the same global variable, peripheral, or data structure, mutex ensures that only one task can enter the critical section at any given time, preventing data races.

1.2 Importance and Application Scenarios

Mutex is one of the most commonly used, most fundamental synchronization mechanisms in RTOS multi-tasking programming, and almost any scenario involving multi-task shared resources relies on it:

Application ScenarioDescription
Shared memory protectionWhen multiple tasks simultaneously read/write global variables/structs/arrays, must lock to ensure data consistency
Peripheral exclusive accessWhen multiple tasks operate on the same SPI/I2C/UART bus, prevent bus conflicts and data corruption
Queue/linked list operationsInsert/delete operations on FreeRTOS queues or custom linked lists require atomic protection
Sensor data acquisitionAcquisition task writes, display task reads, must be mutually exclusive to prevent reading "half-new half-old" data
File system writingMultiple tasks writing to the same file causes data corruption, mutex ensures serialized writes
Display screen refreshWhen multiple tasks update different areas of the same screen, lock is needed to protect frame buffer

Core Value: Mutex is not only a tool for protecting data, but also the cornerstone of ensuring system stability and predictability. Unlocked shared resource access is one of the hardest to reproduce, hardest to debug bugs in embedded systems.

1.3 This Project Demonstrates

This project demonstrates mutex through a "Grab Goods Game" (Human vs AI): Producer produces goods every second, human holds BOOT button to grab lock→releases to grab goods, AI automatically grabs lock→grabs goods→cools down for 1s. First to grab 10 goods wins. Human wins → rainbow LED cycling, AI wins → solid red LED.

Through this game, you will intuitively understand: lock exclusivity (human keeps holding → AI can never get lock), critical section protection (all stock/score operations are inside the lock), and deadlock prevention (each task strictly follows Take → Operation → Give order).


2. Core Concepts

2.1 How Mutex Works

  Task A                Task B
    │                     │
    │ xSemaphoreTake()    │ xSemaphoreTake()
    ▼ (got lock)          ▼ (blocked, waiting)
  ┌────────────┐         ╔══════════════╗
  │  Critical  │         ║ Waiting for   ║
  │  Section   │         ║ lock release...║
  │  Access    │         ╚══════════════╝
  │  shared    │
  │  variables │
  └────────────┘              │
    │                         │
    │ xSemaphoreGive()        ▼ (got lock)
    ▼ (release lock)      ┌────────────┐
                           │  Critical  │
                           │  Section   │
                           └────────────┘

2.2 Mutex API

​x
// Create mutex
SemaphoreHandle_t xSemaphoreCreateMutex(void);

// Take lock (enter critical section)
xSemaphoreTake(xMutex, portMAX_DELAY);

// Give lock (exit critical section)
xSemaphoreGive(xMutex);

2.3 Mutex vs Binary Semaphore

FeatureMutexBinary Semaphore
PurposeMutual exclusion — protect shared resourcesSynchronization — event notification
Priority inheritance✓ (auto elevate holder priority)✗
Recursive acquisitionConfigurable recursive mutex availableNot available
ReleaserMust be acquirer (same task Take → Give)Any task can Give
Use in ISR✗ (cannot Take/Give in ISR)✓ (GiveFromISR)
Initial value1 (available, not held by any task)Usually 0

Mutex priority inheritance mechanism is key to solving priority inversion. When a high-priority task waits for a lock, the low-priority task holding the lock is temporarily elevated to high priority to ensure quick lock release.

2.4 Shared Resource Protection Principles

xxxxxxxxxx
All code accessing g_goods must:
  1. xSemaphoreTake(xMutex, ...)  ← Take lock
  2. Read/modify g_goods          ← Critical section
  3. xSemaphoreGive(xMutex)       ← Give lock

Missing any step = data race = bug

3. Project Architecture and Flow

xxxxxxxxxx
app_main()
  ├─ rgb_init() + key_init()          ← WS2812 (GPIO48) + Button (GPIO0)
  ├─ xSemaphoreCreateMutex()          ← Create mutex (protects: g_goods, g_human_score, g_ai_score)
  ├─ xTaskCreate(vProducer)           ← Producer (Prio 2)
  ├─ xTaskCreate(vConsumer1_Human)    ← Human (Prio 3)
  └─ xTaskCreate(vConsumer2_AI)       ← AI (Prio 2)

  Producer ──(take→produce n→give)──► g_goods    ← Shared resource
  Human    ──(hold→take...release→grab→give)──► g_human_score
  AI       ──(take→grab→give→cool 1s)──► g_ai_score

  Human holds button continuously → Lock always held by Human → AI blocks permanently at xSemaphoreTake
                                        → Demonstrates mutex exclusivity

Game Rules:

ParameterValue
Win conditionFirst to grab 10 goods
ProducerProduces 2~5 randomly per second
AI cooldownWaits 1 second after successful grab
Human operationHold BOOT = hold lock, release = grab + give lock
Human wins → Rainbow cyclingAI wins → Solid red

4. Hardware Dependencies

PinFunctionDescription
GPIO 0BOOT buttonHuman uses button to grab lock and goods
GPIO 48WS2812 RGB LEDHuman wins rainbow / AI wins red

Required Components: freertos/FreeRTOS, freertos/task, freertos/semphr, driver/gpio, led_strip, esp_log, esp_random

This project uses a third-party library again: For details, review (Third-party library installation process: 2.Basic Peripherals → 10.RGB LED Effects)

Note: led_strip is a third-party component provided by ESP-IDF Component Registry, not built into IDF. Before use, declare dependency in main/idf_component.yml:

xxxxxxxxxx
## IDF Component Manager Manifest File
dependencies:
idf:
 version: '>=4.1.0'
espressif/led_strip: ^3.0.3

After declaration, execute idf.py build, and component manager will automatically download component to managed_components/ directory.


5. Source Code Analysis

Full source code: Source Code → ESP-IDF → 4.FreeRTOS → 2. RTOS_Inter-task_communication → RTOS-MUTEX

5.1 Header Files and Macro Configuration

This section defines GPIO pins, game parameters, and all shared resource variables protected by mutex.

xxxxxxxxxx
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_random.h"
#include "driver/gpio.h"
#include "led_strip.h"

static const char *TAG = "MUTEX_GAME";

// ---- GPIO Pin Definitions ----
#define KEY_GPIO        0
#define BLINK_GPIO      48
#define LED_NUM         1
#define DEBOUNCE_MS     50

// ---- Game Parameters ----
#define WIN_COUNT       10
#define PRODUCE_MIN     2
#define PRODUCE_MAX     5
#define AI_COOLDOWN_MS  1000

// ---- Rainbow Colors (WS2812 GRB Order) ----
typedef struct {
    uint8_t green;
    uint8_t red;
    uint8_t blue;
} led_color_t;

static const led_color_t rainbow_colors[] = {
    {0,   150, 0  },   // Red
    {60,  150, 0  },   // Orange
    {150, 150, 0  },   // Yellow
    {150, 0,   0  },   // Green
    {150, 0,   150},   // Cyan
    {0,   0,   150},   // Blue
    {0,   120, 150},   // Purple
};
#define COLOR_COUNT  7

// ---- Shared Resources (all protected by mutex) ----
static SemaphoreHandle_t xMutex = NULL;
static int  g_goods       = 0;
static int  g_human_score = 0;
static int  g_ai_score    = 0;
static bool g_game_over   = false;
static int  g_winner      = 0;

static led_strip_handle_t led_strip;

5.2 key_init() — Button GPIO Initialization

Configure BOOT button (GPIO0) as internal pull-up input mode, low level when pressed.

xxxxxxxxxx
static void key_init(void)
{
    gpio_config_t cfg = {
        .pin_bit_mask = 1ULL << KEY_GPIO,
        .mode         = GPIO_MODE_INPUT,
        .pull_up_en   = GPIO_PULLUP_ENABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type    = GPIO_INTR_DISABLE,
    };
    gpio_config(&cfg);
}

5.3 rgb_init() — WS2812 LED Initialization

Initialize WS2812 strip on GPIO48 via RMT peripheral.

xxxxxxxxxx
static void rgb_init(void)
{
    led_strip_config_t strip_cfg = {
        .strip_gpio_num          = BLINK_GPIO,
        .max_leds                = LED_NUM,
        .led_model               = LED_MODEL_WS2812,
        .color_component_format  = LED_STRIP_COLOR_COMPONENT_FMT_GRB,
        .flags.invert_out        = false,
    };
    led_strip_rmt_config_t rmt_cfg = {
        .resolution_hz = 10 * 1000 * 1000,
        .flags.with_dma = false,
    };
    ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_cfg, &rmt_cfg, &led_strip));
    led_strip_clear(led_strip);
}

5.4 rgb_set() / rgb_rainbow_loop() / rgb_red_loop() — LED Display Functions

Three LED control functions: set solid color, rainbow cycle, solid red.

xxxxxxxxxx
static void rgb_set(uint8_t r, uint8_t g, uint8_t b)
{
    led_strip_set_pixel(led_strip, 0, r, g, b);
    led_strip_refresh(led_strip);
}

static void rgb_rainbow_loop(void)
{
Binary Semaphore
Event Groups

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
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文