INTRODUCTION
FreeRTOS is a lightweight, open-source Real-Time Operating System kernel designed for microcontrollers and small embedded systems. It provides essential RTOS features such as task scheduling, inter-task communication, synchronization mechanisms, and low-power management, while maintaining a minimal memory footprint.
In this project, FreeRTOS is used to manage multiple concurrent tasks on an STM32 microcontroller, enabling deterministic execution, modular software design, and safe access to shared hardware resources. The RTOS scheduler handles task switching, while tasks explicitly yield CPU control through delay functions, implementing a cooperative multitasking approach suitable for resource-constrained systems.
PROJECT OBJECTIVE
The objective of this project is to design and implement an RTOS-based multitasking embedded system that concurrently:
- Acquires temperature data from an I2C sensor
- Controls RGB LED brightness using analog input
- Updates graphical information on an LCD
- Executes a periodic LED blink task
All tasks operate independently while sharing system resources safely using RTOS synchronization primitives.
Step 1: Hardware and Peripheral Initialization
- Configure system clock, GPIOs, ADC, I2C, FSMC, and PWM peripherals using STM32CubeMX
- Initialize the LCD (ST7789 v3) via FSMC using an 8080 parallel interface
- Initialize the AHT20 temperature and humidity sensor over I2C
- Verify proper operation of LEDs and potentiometer input
Pin Mapping and Wiring Connection:
STM32 Dev Board -> Potentiometer
GND -> Left Leg
PA1 -> Middle Leg
3.3V -> Right Leg
STM32 Dev Board -> RGB
GND -> Long Leg
PA6 -> Red Leg
PE13 -> Blue Leg
PE11 -> Green Leg
Step 2: Driver integration and implementation- Adapted/implemented the ST7789 driver (src/drv_lcd.c + inc/drv_lcd.h and font routines in drv_lcd_font.c) to initialize the display, set windows, and draw text/pixels over FSMC.
- Implemented the AHT2x driver (src/drv_aht21.c + inc/drv_aht21.h) to perform I²C transactions and convert responses into temperature/humidity values.
- Added simple ADC read helpers and PWM setter functions for LED control.
Step 4 — RTOS task design
Implemented four focused FreeRTOS tasks (created in src/main.c):
- TempDisplayTask — read AHT2x, format temperature string, update LCD (periodic).
- BrightnessTask — sample ADC, smooth value, map to PWM duty cycle for RGB LED.
- CounterTask — increment and display a counter on the LCD.
- BlinkTask — toggle a GPIO LED at a steady rate.
- Each task runs an infinite loop and uses vTaskDelay() after its update so tasks voluntarily yield (cooperative-style behavior).
Step 5 — Synchronization: protecting the LCD
- Created a FreeRTOS mutex for the LCD (xSemaphoreCreateMutex()).
- Every multi-step LCD operation takes the mutex before writing (set window → push pixels → draw text) and gives it back immediately afterward.
- Used short timeouts on xSemaphoreTake so tasks can skip updates or retry rather than deadlock.
Step 6 — ADC smoothing and PWM mapping
- Applied a small smoothing filter (simple EMA) to raw ADC samples to avoid visible LED flicker.
- Mapped filtered ADC values to timer PWM duty cycles and updated three channels (R/G/B).
Step 7 — Power considerations
- Enabled FreeRTOS idle handling (tickless-idle or vApplicationIdleHook) so the MCU can enter sleep when no tasks are ready.
- Ensured sleep entry does not interfere with required interrupts (I²C, TIM, ADC).
Step 8 — Build, flash and verification
- Built the project in STM32CubeIDE and flashed it using ST‑Link.
Verified behavior on the physical board:
- LCD initializes and clears.
- Temperature is displayed and updates periodically.
- Counter increments in its own LCD area.
- Potentiometer smoothly changes RGB brightness.
- Blink LED toggles at expected rate.
- No LCD corruption (mutex protects access).
Step 9 — Observations, fine-tuning and decisions
- Kept LCD critical sections short: prepare strings/buffers in RAM, then take mutex briefly to write.
- Increased mutex timeout slightly to reduce skipped updates during heavy activity.
- Added ADC smoothing to remove visible flicker.
- If planning larger refreshes later, considered DMA or double buffering to reduce display-blocking time.
Files to inspect in the repo (where the work lives):
- src/main.c — task creation, mutex creation, scheduler start, high-level flow.
- src/drv_lcd.c, inc/drv_lcd.h — ST7789 initialization and drawing functions.
- src/drv_lcd_font.c, inc/drv_lcd_font.h — font rendering and text helper routines.
- src/drv_aht21.c, inc/drv_aht21.h — AHT2x sensor driver (I²C read/convert).
inc/FreeRTOSConfig.h — RTOS configuration used for this project. Full repo for the source code at the end.
Result Sample
Demo Video Link:
https://drive.google.com/file/d/1wLsBM2x6mtNRGryWBkrKpHFMUVXQBMnH/view?usp=sharing






Comments