Welcome to my STM32 IoT framework series! I’m building a complete IoT system from scratch without using STM32 HAL libraries. Let’s start by understanding the project structure.
Project Overview
This is a baremetal implementation featuring:
- Priority-based task scheduler
- Power management with multiple sleep modes
- UART communication with command interface
- Modular design for easy expansion
GitHub Repository: github.com/umanggulati/iotmodule
Project Name in IDE: embeddedc_gpio1234
Complete File Structure
stm32f429-iot-module [embeddedc_gpio1234 develop]
βββ π Binaries/
β βββ stm32f429-iot-module.elf # Compiled executable
β
βββ π Debug/
β βββ π Src/ # Compiled object and dependency files
β β βββ main.o, main.d
β β βββ power_management.o, power_management.d
β β βββ syscalls.o, syscalls.d
β β βββ sysmem.o, sysmem.d
β β βββ system_config.o, system_config.d
β β βββ systick.o, systick.d
β β βββ task_scheduler.o, task_scheduler.d
β β βββ uart.o, uart.d
β βββ π Startup/
β β βββ startup_stm32f429zitx.o
β β βββ startup_stm32f429zitx.d
β βββ makefile
β βββ objects.list
β βββ objects.mk
β βββ sources.mk
β βββ stm32f429-iot-module.list # Assembly listing
β βββ stm32f429-iot-module.map # Memory map
β
βββ π Inc/ # Header files
β βββ cmsis_armcc.h # CMSIS compiler abstraction (ARM Compiler)
β βββ cmsis_armclang.h # CMSIS compiler abstraction (ARM Clang)
β βββ cmsis_compiler.h # CMSIS compiler abstraction layer
β βββ cmsis_gcc.h # CMSIS compiler abstraction (GCC)
β βββ cmsis_iccarm.h # CMSIS compiler abstraction (IAR)
β βββ cmsis_version.h # CMSIS version information
β βββ core_cm4.h # Cortex-M4 core definitions
β βββ mpu_armv7.h # Memory Protection Unit definitions
β βββ mpu_armv8.h # MPU ARMv8 definitions
β βββ power_management.h # Power modes and wake-up control
β βββ stm32f429xx.h # MCU-specific register definitions
β βββ stm32f4xx.h # STM32F4 family definitions
β βββ system_config.h # System clock configuration
β βββ system_stm32f4xx.h # System initialization declarations
β βββ systick.h # 1ms timer service interface
β βββ task_scheduler.h # Task management interface
β βββ tz_context.h # TrustZone context (not used)
β βββ uart.h # Serial communication interface
β
βββ π Src/ # Source files
β βββ main.c # Application entry point and demo tasks
β βββ power_management.c # Power mode implementation
β βββ syscalls.c # System calls for newlib
β βββ sysmem.c # Memory management for newlib
β βββ system_config.c # Clock configuration implementation
β βββ systick.c # Timer implementation
β βββ task_scheduler.c # Task scheduling engine
β βββ uart.c # UART driver implementation
β
βββ π Startup/
β βββ startup_stm32f429zitx.s # Assembly startup code
β
βββ π embeddedc_gpio1234 Debug.launch # Debug configuration
βββ π README.md # Project documentation
βββ π stm32f429-iot-module.launch # Launch configuration
βββ π STM32F429ZITX_FLASH.ld # Linker script for Flash
βββ π STM32F429ZITX_RAM.ld # Linker script for RAM
Directory Explanations
Inc/ – Header Files
Contains all the public interfaces and CMSIS (Cortex Microcontroller Software Interface Standard) files:
CMSIS Files (ARM Standard Headers):
- core_cm4.h – Cortex-M4 processor and core peripherals
- cmsis_gcc.h – GCC compiler specific definitions
- cmsis_compiler.h – Compiler abstraction layer
- cmsis_armcc.h, cmsis_armclang.h, cmsis_iccarm.h – Other compiler support
- mpu_armv7.h – Memory Protection Unit functions
STM32 Specific:
- stm32f4xx.h – STM32F4 family register definitions
- stm32f429xx.h – STM32F429 specific registers and memory map
- system_stm32f4xx.h – System initialization functions
Our Framework Headers:
- power_management.h – Power mode definitions (Run, Sleep, Stop, Standby)
- system_config.h – Clock speed configuration (16MHz HSI)
- systick.h – Millisecond timer interface
- task_scheduler.h – Task registration and management API
- uart.h – Serial communication functions
Src/ – Implementation Files
Where the actual work happens:
- main.c – Entry point, initializes all systems, contains demo tasks (LED blink, status reporting)
- power_management.c – Implements sleep modes, wake-up sources, voltage scaling
- syscalls.c – Low-level system calls for C library (enables printf, malloc)
- sysmem.c – Memory allocation functions for newlib C library
- system_config.c – Returns system clock frequency (16MHz)
- systick.c – Provides 1ms timing heartbeat using SysTick timer
- task_scheduler.c – Priority-based task execution engine
- uart.c – UART3 driver for serial communication at 115200 baud
Debug/ – Build Output
Generated during compilation:
- Src/ and Startup/ folders contain:
- .o files – Compiled object code
- .d files – Dependency information for incremental builds
- stm32f429-iot-module.list – Assembly listing for debugging
- stm32f429-iot-module.map – Memory map showing where functions and variables are located
- makefile, objects.mk, sources.mk – Auto-generated build scripts
Startup/
- startup_stm32f429zitx.s – Assembly code that:
- Sets up stack pointer
- Copies initialized data from Flash to RAM
- Clears uninitialized data (BSS section)
- Calls SystemInit() and then main()
- Contains interrupt vector table
Configuration Files
Linker Scripts (.ld files)
Define memory layout:
- STM32F429ZITX_FLASH.ld – Normal operation (code runs from Flash at 0x08000000)
- STM32F429ZITX_RAM.ld – Debug mode (code runs from RAM at 0x20000000)
Launch Configurations
- embeddedc_gpio1234 Debug.launch – Debug session configuration
- stm32f429-iot-module.launch – Alternative launch configuration
Build Output
- Binaries/ folder contains the final .elf file ready for debugging
Key Features of This Structure
- Clear Separation – Headers (interface) separate from implementation
- Modular Design – Each file has a specific purpose
- No HAL Dependencies – Direct register manipulation only
- CMSIS Compliance – Uses ARM standard headers for portability
- Professional Organization – Similar to industry projects
- Easy to Navigate – Logical grouping of related files
Note: Some configuration files like .gitignore, .project, .cproject are hidden in the IDE view but exist in the repository.
How It All Works Together
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β Startup ββββββΆβ main.c ββββββΆβ SysTick β
β (.s file) β β (init all) β β (1ms timer) β
βββββββββββββββ ββββββββββββββββ βββββββββββββββ
β β
βΌ βΌ
ββββββββββββββββ βββββββββββββββ
β UART β β Task β
β (115200) β β Scheduler β
ββββββββββββββββ βββββββββββββββ
β β
βΌ βΌ
ββββββββββββββββ βββββββββββββββ
β Power β β Tasks: β
β Management β β -LED Blink β
ββββββββββββββββ β -Sensors β
β -Reports β
βββββββββββββββ
- Power On β startup_stm32f429zitx.s runs first
- System Init β Clocks configured via system_config.c
- main() Entry β main.c takes control
- Initialize Subsystems β SysTick, UART, Power Management, Task Scheduler
- Register Tasks β LED blinking, sensor reading, status reporting
- Run Forever β Task scheduler executes tasks based on timing and priority
Getting Started
# Clone the repository
git clone https://github.com/umanggulati/iotmodule.git
# Open in STM32CubeIDE
# File β Import β Existing Projects into Workspace
# Select the project folder
# Build (Ctrl+B) and Flash to your STM32F429ZI board
What’s Next?
In Part 2, we’ll dive deep into the boot process. We’ll trace exactly what happens from the moment you power on the STM32 to when your main() function starts executing. You’ll learn about the reset vector, how RAM gets initialized, and why we verify the interrupt vector table.
Next: Part 2 – STM32 Boot Secrets: From Power-On to Your Code β
This is Part 1 of the STM32 IoT Framework series. Follow along as we build a professional embedded system from scratch!
GitHub: github.com/umanggulati/iotmodule
Status: Active development – more features being added regularly
Pingback: STM32 SysTick: Build a Reliable 1ms Heartbeat (Code Walkthrough) - Learn By Building