Skip to content

nimaltd/fsm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🌀 Finite State Machine + Task Manager Library for STM32

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.)

✨ Features

  • 🔹 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

⚙️ Installation

You can install in two ways:

1. Copy files directly

Add these files to your STM32 project:

  • fsm.h
  • fsm.c
  • fsm_config.h

2. STM32Cube Pack Installer (Recommended)

Available in the official pack repo:
👉 STM32-PACK (Not Ready)


🔧 Configuration (fsm_config.h)

Defines library limits and task queue size. Example:

#define FSM_MAX_TASKS     16    // Max number of queued tasks

🚀 Quick Start

Include header

#include "fsm.h"

Define handle

fsm_t hFsm;

Initialize in main.c

fsm_init(&hFsm, state_idle);

while (1)
{
    fsm_loop(&hFsm);   // must be called frequently
}

Example: Using FSM with EXTI Button Interrupt

/* ===== 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


🧰 API Overview

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

💖 Support

If you find this project useful, please ⭐ star the repo and consider supporting!

  • GitHub
  • YouTube
  • Instagram
  • LinkedIn
  • Email
  • Ko-fi

📜 License

Licensed under the terms in the LICENSE.

Releases

No releases published

Sponsor this project

  •  

Packages

No packages published

Languages