A lightweight and efficient Finite State Machine (FSM) library with built-in non-blocking task manager, written in C for STM32 (HAL-based).
Unlike blocking implementations, this library uses time-based state transitions and a task queue system to keep your main loop responsive.
It can be used in any CubeMX STM32 project, making it fully flexible and easy to integrate.
It is designed for:
- Projects where CPU blocking (
HAL_Delay
) must be avoided - Applications that need clean state handling
- Event-driven systems that use interrupts (EXTI, UART, Timers)
- Easy portability across STM32 families (F0/F1/F3/F4/F7/G0/G4/H7, etc.)
- 🔹 Non-blocking state transitions with millisecond resolution
- 🔹 Built-in task queue system for background jobs
- 🔹 Works with interrupt callbacks (e.g. EXTI, UART, Timer)
- 🔹 Fully HAL-compatible (
HAL_GetTick()
) - 🔹 Small memory footprint, portable C code
- 🔹 Simple, clean API
You can install in two ways:
Add these files to your STM32 project:
fsm.h
fsm.c
fsm_config.h
Available in the official pack repo:
👉 STM32-PACK (Not Ready)
Defines library limits and task queue size. Example:
#define FSM_MAX_TASKS 16 // Max number of queued tasks
#include "fsm.h"
fsm_t hFsm;
fsm_init(&hFsm, state_idle);
while (1)
{
fsm_loop(&hFsm); // must be called frequently
}
/* ===== States ===== */
void state_idle(void)
{
// do ...
if ( .... )
{
// change state to state_calc1
fsm_next(&hFsm, state_calc1, 0);
}
}
/* ===== States ===== */
void state_calc1(void)
{
// do ...
// set next state after 200 ms
fsm_next(&hFsm, state_calc2, 200);
}
/* ===== States ===== */
void state_calc2(void)
{
// do ...
// go back to idle state
fsm_next(&hFsm, state_idle, 0);
}
/* ===== Task Function ===== */
void button_task(void)
{
// do ...
}
/* ===== Interrupt Callback ===== */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == B1_Pin) // User button
{
// Schedule FSM task safely from interrupt
fsm_task_add(&hFsm, button_task);
}
}
✅ ISR stays short → only fsm_task_add()
is called
✅ FSM executes logic in main loop → no blocking in ISR
Function | Description |
---|---|
fsm_init() |
Initialize FSM handle with first state |
fsm_loop() |
Main loop handler; runs tasks and state changes |
fsm_next() |
Schedule next state after delay (ms) |
fsm_time() |
Get elapsed time in current state |
fsm_task_add() |
Add a function task to be executed by FSM |
If you find this project useful, please ⭐ star the repo and consider supporting!
Licensed under the terms in the LICENSE.