yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
MSPM0 Smart Robot Car📖
1.Quick Start Guide
  • 1. Assembly Videos
  • 2. Quick Start Videos
  • 3. Battery charging
  • 4. Notes
2.Introduction to the MSPM0 Car
  • 1.About MSPM0
  • 2.Development board interface description
3.Development environment setup and usage
  • 1.CCS Theia development
  • 2.MDK Arm development
  • 3.Uniflash burning
  • 4.External crystal oscillator configuration
  • 5.Project Migration
4.MSPM0 basic course
  • 1. LED light control (GPIO)
  • 2. Buzzer Control (GPIO)
  • 3. Button Control (EXTI)
  • 4. Serial Port (UART)
  • 5. Voltage Detection (ADC)
  • 6. Temperature Detection (ADC)
  • 7. Independent Watchdog (WWDG)
  • 8. Window Watchdog (WWDG)
  • 9. Timer (TIM)
  • 10. Breathing LED (PWM)
  • 11. I2C Communication (I2C)
  • 12. External Flash (SPI)
  • 13. Internal Flash (Flash)
  • 14. DMA
  • 15. FreeRTOS
5.Sensor basic course
  • 1.Servo control
  • 2.Ultrasonic servo PTZ basic use
  • 3.Motor PID control
  • 4.OLED display photosensitive value
  • 5.Infrared avoid sensor
  • 6.1 Infrared line tracking sensor-8 channel infrared tracking sensor module
  • 6.2 Infrared line tracking sensor-4 channel infrared tracking sensor module
  • 7.Infrared remote control
  • 8.Ultrasonic ranging
  • 9.RGB light drive
  • 10.MPU6050 raw data acquisition
  • 11.MPU6050 data fusion
  • 12.K210 vision recognition module
  • 13.K230 vision recognition module
6.Smart car course
  • 1.1 Car line tracking-8 channel infrared tracking sensor module
  • 1.2 Car line tracking-4 channel infrared tracking sensor module
  • 2.1 Drawing a circle-8 channel infrared tracking sensor module
  • 2.2 Drawing a circle-4 channel infrared tracking sensor module
  • 3.Ultrasonic following
  • 4.Ultrasonic avoid
  • 5.Ultrasonic avoid(Servo PTZ)
  • 6.Infrared sensor avoid
  • 7.Light following
  • 8.Gyroscope calibration straight-line walk
  • 9.Infrared remote control
  • 10.Autonomous driving car
7.Vision application course
  • 1.K210 autonomous driving
  • 2.K210 color tracking
  • 3.K210 handwritten digit action
  • 4.K210 color response
  • 5.K210 road sign indication action
  • 6.K210 following machine code
  • 7.K210 QR code command
  • 8.K230 vision line tracking
  • 9.K230 color tracking
  • 10.K230 machine code tracking
  • 11.K230 QR code command
  • 12.K230 autonomous avoid
  • 13.K230 license plate tracking
  • 14.K230 face tracking
  • 15.K230 gaze direction tracking
  • 16.K230 palm tracking
  • 17.K230 target tracking
  • 18.K230 human body tracking
  • 19.K230 OCR character recognition
8.Extended application course (Sold separately)
  • 1.Voice interaction module communication
  • 2.Voice interaction control
  • 3.K230 road sign indication action(Voice)
  • 4.K230 color response(Voice)
  • 5.K230 gesture control(Voice)
  • 6.K230 rock-paper-scissors(Voice)
  • 7.8-channel grayscale color line tracking
  • 8.Bluetooth remote control
  • 9.K210 Scenario-based autonomous driving
  • 10.K230 Scenario-based autonomous driving
Download
  • Code
  • SCH
  • 3D Model File
  • MSPM0 Data Sheet
  • Voice firmware
  • Hardware interface manual
Download ZIP

Welcome to MSPM0 Smart Robot Car repository

15. FreeRTOS

FreeRTOS

FreeRTOSI. Learning ObjectivesII. FreeRTOS IntroductionIII. Hardware SetupIV. Experiment StepsV. Code AnalysisVI. Experiment Phenomenon

 

I. Learning Objectives

  1. Understand basic FreeRTOS knowledge.
  2. Use FreeRTOS to schedule RGB, serial port, LED, buzzer, and OLED peripherals.

II. FreeRTOS Introduction

FreeRTOS is a real-time operating system (RTOS) widely used in embedded systems, characterized by open source, lightweight, and scalable features, particularly suitable for resource-constrained microcontrollers (MCUs) and embedded devices. Its design core is to achieve efficient multi-task management and real-time response on resource-constrained hardware. It provides core functions such as task scheduling, memory management, synchronization and communication, helping developers build responsive and highly reliable real-time applications, widely used in smart home, industrial control, IoT devices and other fields.

Project address: https://github.com/FreeRTOS/FreeRTOS

Official website: https://www.freertos.org

I. FreeRTOS Principles

  1. Task Management and Scheduling: Core Mechanism of Multi-tasking

The core of FreeRTOS is the task scheduler, which manages multiple independent tasks and decides when to run which task. A task is the smallest execution unit in the operating system, with independent stack space and execution logic, can be viewed as a "micro-program".

  • Essence of Tasks: Each task is an infinite loop (while(1)), containing independent local variables and stack (for saving context, such as register status). Task creation requires specifying priority (0~configMAX_PRIORITIES-1, higher value means higher priority).

  • Task Control Block (TCB): Each task corresponds to a TCB_t structure (task control block), used to store key information of the task, including: stack pointer (save task context), priority, status, delay time, belonging queue, etc. All task TCBs form a linked list for scheduler management.

  • Task States and Transitions: Tasks have 4 core states, scheduler achieves task switching through state transitions:

    • Ready: Task is ready to run, waiting for CPU resources (only limited by priority).
    • Running: Task is currently occupying CPU execution.
    • Blocked: Task temporarily cannot run due to waiting for events (such as delay, semaphore, queue data), does not participate in scheduling.
    • Suspended: Task is forcibly paused, needs explicit recovery through vTaskResume(), does not participate in scheduling.
  • Scheduler Working Mechanism:

    FreeRTOS uses preemptive scheduling as core (default mode), meaning when high-priority tasks are ready, they immediately preempt CPU resources of low-priority tasks, ensuring real-time response of high-priority tasks. Specific rules:

    • Only ready-state tasks participate in scheduling, scheduler always selects highest-priority ready task to run.
    • Same-priority tasks can enable time-slice round-robin (configured through configUSE_TIME_SLICING), each task takes turns occupying CPU (time slice determined by system tick period).
    • Cooperative scheduling (optional): Actively yield CPU through taskYIELD(), suitable for scenarios with low real-time requirements.
  1. Inter-task Communication and Synchronization: Solving Multi-task Collaboration Problems

When multiple tasks run in parallel, specific mechanisms are needed to achieve data interaction and resource competition control. FreeRTOS provides rich synchronization and communication tools:

  • Queue:

    Used for asynchronous data transfer between tasks (such as sensor data, commands), based on FIFO (First In First Out) principle, supports multi-task read/write. Queues can store fixed-size elements (such as integers, pointers), block when queue is full during write, block when queue is empty during read (blocking time configurable).

  • Semaphore:

    Used for resource synchronization or counting, divided into two types:

    • Binary semaphore: Only two states (0/1), similar to "switch", often used for mutual exclusion (such as controlling single thread access to hardware resources) or synchronization (such as task A notifying task B after completion).
    • Counting semaphore: Supports counting (0~n), used to manage limited number of resources (such as 3 UART ports, count initial is 3, decrease by 1 when occupied, increase by 1 when released).
  • Mutex:

    Special binary semaphore, used to solve priority inversion problem (when low-priority task occupies resources, high-priority task is blocked due to waiting for resources, causing medium-priority tasks to "jump the queue"). Mutex temporarily boosts low-priority task's priority through priority inheritance protocol, making it release resources faster.

  • Event Group:

    Used for multiple tasks waiting for multiple events (such as "task waits for both sensor A and sensor B to be ready"). Each event is represented by a bit, tasks can wait for "any event satisfied" or "all events satisfied", suitable for complex condition trigger scenarios.

  • Task Notification:

    More efficient mechanism than queues (no additional memory allocation), achieves communication by directly writing notification value to task's TCB. A task can be notified by multiple tasks, supports operations like overwrite, increment, set bit, suitable for lightweight interaction.

  1. Memory Management: Adapting to Embedded Resource-constrained Scenarios

Embedded systems have limited memory, FreeRTOS provides 5 memory allocation schemes (selected through heap_x.c), balancing efficiency, determinism and flexibility:

  • heap_1: Only supports memory allocation (pvPortMalloc()), does not support free (vPortFree()), suitable for scenarios without dynamic memory release (such as tasks not deleted after creation), advantages are simple, no fragmentation.
  • heap_2: Supports allocation and free, but does not merge adjacent free blocks, prone to memory fragmentation after long-term use, suitable for scenarios with fixed memory block sizes.
  • heap_3: Wraps standard library malloc() and free(), depends on compiler implementation, advantage is universal, disadvantage is poor real-time performance (allocation time uncertain).
  • heap_4: Supports allocation, free and free block merging (reduces fragmentation), manages memory through linked list, suitable for scenarios needing dynamic release and sensitive to fragmentation.
  • heap_5: Based on heap_4, supports non-contiguous memory regions (such as external RAM + internal RAM), defines memory blocks through vPortDefineHeapRegions(), suitable for hardware with scattered memory distribution.
  1. Time Management: Tick-based Timing Mechanism

FreeRTOS relies on system tick to achieve timing and scheduling, ticks are generated by hardware timer (such as SysTick), period (configTICK_RATE_HZ) usually 100~1000Hz (i.e., 1~10ms once).

  • Scheduler's task switching, delay functions (such as vTaskDelay()) are all based on tick counting.
  • vTaskDelay(x): Task blocks for x ticks then enters ready state (relative delay, calculated from call moment).
  • vTaskDelayUntil(): Absolute delay, ensures task executes at fixed period (such as running every 10ms, not affected by task execution time).

II. FreeRTOS Features

  1. Open Source and Free, Friendly License

Uses MIT license, allows free commercial use, source code completely open, no patent or commercial authorization restrictions, suitable for enterprise and personal projects.

  1. Lightweight, Extremely Low Resource Usage

Core code only a few thousand lines, compiled size can be as low as 6KB (depending on feature trimming), RAM usage mainly depends on task stack size (each task stack can be as small as dozens of bytes), suitable for 8-bit/16-bit MCUs (such as STM8, PIC) and resource-constrained 32-bit MCUs (such as ARM Cortex-M0).

  1. Highly Scalable, Configure on Demand

Through FreeRTOSConfig.h header file, functions can be enabled/disabled (such as queues, mutexes, time-slice round-robin), adjust priority count, stack size and other parameters, only keep necessary components, maximize resource savings.

  1. Strong Real-time Performance, Deterministic Scheduling

Preemptive scheduling ensures high-priority tasks can respond at microsecond level (delay determined by task switching time, usually <10us), scheduling behavior is predictable (task switching time fixed under same conditions), meeting real-time scenario requirements such as industrial control, automotive electronics.

  1. Broad Hardware and Architecture Support

Supports almost all mainstream embedded architectures, including ARM (Cortex-M/R/A), AVR, PIC, RISC-V, MIPS, etc., adapts to thousands of MCUs (such as STM32, ESP32, MSP430), official provides numerous porting examples.

  1. Flexible Task Scheduling Strategies

Supports preemptive, cooperative scheduling, same-priority tasks can time-slice round-robin, priority range configurable (up to 256 levels), meeting task priority design needs of different scenarios.

  1. Complete Synchronization and Communication Mechanisms

Provides queues, semaphores, mutexes, event groups, task notifications and other tools, covering single/multi-task data transfer, resource competition, condition triggering and other needs, with simple and easy-to-use interfaces.

  1. Priority Inversion Protection

Mutex's priority inheritance protocol solves common priority inversion problems in real-time systems, avoiding high-priority tasks being blocked for long time due to waiting for resources held by low-priority tasks.

  1. Strong Portability

Kernel is hardware-independent, adapts to different architectures through "port layer" (only need to implement hardware-related code such as context switching, interrupt handling), porting workload is small (usually a few hundred lines of code).

III. Hardware Setup

image-20251027222433867

IV. Experiment Steps

This project is built based on the previously configured 80MHz crystal example. We click Manage RunTime Environment, check and add all components under RTOS. Here we select FreeRTOS as the RTOS version, and select Heap_4 as the memory management algorithm.

image-20251027221523657

Add components as follows

image-20251027222559861

Then we add peripheral configuration through sysconfig tool

RGB light configuration

image-20251027222102687

Buzzer configuration

image-20251027222138186

MCU indicator light configuration

image-20251027222151264

Serial port configuration

image-20251027222210641

Serial port configuration

image-20251027222217459

OLED configuration

image-20251027222307571

image-20251027222316554

We focus on introducing some FreeRTOS configurations

CPU frequency setting

#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 )

Systick interrupt frequency setting

#define configTICK_RATE_HZ 1000

//Software timer is turned off and not used. If enabled, need to implement vApplicationGetTimerTaskMemory vApplicationGetIdleTaskMemory #define configUSE_TIMERS 0

System call stack size

#define configSYSTEM_CALL_STACK_SIZE 128

Enable static memory allocation

#define configSUPPORT_STATIC_ALLOCATION 1

Enable dynamic memory allocation

#define configSUPPORT_DYNAMIC_ALLOCATION 1

Kernel automatically allocates memory, we allocate manually here

#define configKERNEL_PROVIDED_STATIC_MEMORY 0

Boot MPU M0 core does not support, turn off here

#define configENABLE_MPU 0

FreeRTOS heap size in bytes

#define configTOTAL_HEAP_SIZE 4096

V. Code Analysis

xTaskCreate

Function PrototypeBaseType_t xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const configSTACK_DEPTH_TYPE uxStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask )
Function DescriptionCreate a new task in FreeRTOS. After successful creation, the task enters ready state, waiting for scheduler to allocate CPU resources to run
Input ParameterspxTaskCode: Pointer to task function, task function must be in void vTaskFunction(void *pvParameters) format pcName: Task name, used for debugging identification, length not exceeding configMAX_TASK_NAME_LEN uxStackDepth: Task stack depth, unit is "stack items" (not bytes), stack size = uxStackDepth × stack item bytes pvParameters: Parameter pointer passed to task function uxPriority: Task priority, higher value means higher priority, range is 0~configMAX_PRIORITIES-1 pxCreatedTask: Used to save handle of newly created task, can be set to NULL (means not saved)
Return ValueBaseType_t type, return pdPASS means task creation successful; return errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY means insufficient memory, task creation failed

vTaskDelayUntil

Function Prototypevoid vTaskDelayUntil( TickType_t *pxPreviousWakeTime, TickType_t xTimeIncrement )
Function DescriptionImplement periodic task scheduling, ensure task executes at fixed time intervals, suitable for scenarios requiring strict periods
Input ParameterspxPreviousWakeTime: Pointer to TickType_t type variable, used to store the timestamp of last task wake-up, needs to be initialized before first call (such as using xTaskGetTickCount() to get current time) xTimeIncrement: Time interval of task execution, unit is system tick, i.e., time interval between two task execution starts
Return ValueNone

xQueueSend

Function PrototypeBaseType_t xQueueSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait )
Function DescriptionSend data to the tail of queue (macro definition, essentially calls xQueueGenericSend and specifies queueSEND_TO_BACK), wait specified time if queue is full
Input ParametersxQueue: Handle of target queue pvItemToQueue: Pointer to data to send, data will be copied to queue xTicksToWait: Maximum time to wait for queue to have space (unit: system tick), 0 means no wait, portMAX_DELAY means infinite wait
Return ValueBaseType_t type, pdPASS means send successful; errQUEUE_FULL means wait timeout and queue still full

xQueueReceive

Function PrototypeBaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )
Function DescriptionReceive data from queue head and remove it from queue, wait specified time if queue is empty
Input ParametersxQueue: Handle of target queue pvBuffer: Pointer to receive data buffer, data in queue will be copied to this buffer xTicksToWait: Maximum time to wait for queue to have data (unit: system tick), 0 means no wait, portMAX_DELAY means infinite wait
Return ValueBaseType_t type, pdPASS means receive successful; errQUEUE_EMPTY means wait timeout and queue still empty

prvQueueSendTask

Function Prototypestatic void prvQueueSendTask(void *pvParameters)
Function DescriptionQueue send task: Periodically send fixed value (100UL) to queue, send frequency defined by mainQUEUE_SEND_FREQUENCY_MS, uses vTaskDelayUntil to ensure strict period
Input ParameterspvParameters: Task parameter, must equal mainQUEUE_SEND_PARAMETER (validated through configASSERT)
Return ValueNone

prvQueueReceiveTask

Function Prototypestatic void prvQueueReceiveTask(void *pvParameters)
Function DescriptionQueue receive task: Wait indefinitely for queue data, after receiving verify if value is 100UL, if matches then control LED to blink (restore state after short delay)
Input ParameterspvParameters: Task parameter, must equal mainQUEUE_RECEIVE_PARAMETER (validated through configASSERT)
Return ValueNone

prvBuzzerTask

Function Prototypestatic void prvBuzzerTask(void *pvParameters)
Function DescriptionBuzzer control task: With 2-second period, control buzzer to turn on for 200ms then turn off, uses vTaskDelayUntil to ensure period stability
Input ParameterspvParameters: Task parameter, must equal mainBUZZER_TASK_PARAMETER (validated through configASSERT)
Return ValueNone

prvUartTask

Function Prototypestatic void prvUartTask(void *pvParameters)
Function DescriptionSerial port send task: With 1-second period, cyclically send counter information through serial port (format: "FreeRTOS running, counter: %u\r\n"), counter increments, uses vTaskDelayUntil to ensure period
Input ParameterspvParameters: Task parameter, must equal mainUART_TASK_PARAMETER (validated through configASSERT)
Return ValueNone

prvRgbTask

Function Prototypestatic void prvRgbTask(void *pvParameters)
Function DescriptionRGB light control task: With 2-second period, update all RGB light colors (cycle through preset color array rgbColors), and print current color name through serial port, uses vTaskDelayUntil to ensure period
Input ParameterspvParameters: Task parameter, must equal mainRGB_TASK_PARAMETER (validated through configASSERT)
Return ValueNone

prvOledTask

Function Prototypestatic void prvOledTask(void *pvParameters)
Function DescriptionOLED display task: After initializing OLED, update screen display with 2-second period, first line fixed displays "Current Color:", second line displays current RGB light color name (taken from colorNames array), uses vTaskDelayUntil to ensure period
Input ParameterspvParameters: Task parameter, must equal mainOLED_TASK_PARAMETER (validated through configASSERT)
Return ValueNone

rgb_SetColor

Function Prototypevoid rgb_SetColor(unsigned char LedId, unsigned long color)
Function DescriptionSet color of specified LED, decompose color value into three primary color components and store in LED data array
Input ParametersLedId: LED number to control (must be less than ledsCount, otherwise no operation performed) color: 32-bit color value, format is red (high 8 bits), green (middle 8 bits), blue (low 8 bits)
Return ValueNone

rgb_SetRGB

Function Prototypevoid rgb_SetRGB(unsigned char LedId, unsigned long red, unsigned long green, unsigned long blue)
Function DescriptionSet color of specified LED through three primary color components, combine red, green, blue components into 32-bit color value, then call rgb_SetColor to implement setting
Input ParametersLedId: LED number to control red: Red component (0~255) green: Green component (0~255) blue: Blue component (0~255)
Return ValueNone

VI. Experiment Phenomenon

After the program is flashed, connect Type-C to the car, open serial port assistant and configure as follows. LED executes one toggle every 1s, serial port counting task prints once every 1s, RGB, buzzer, OLED execute once every 2s.

image--20251028142743168

DMA
Servo control

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/中文