All Projects → mryndzionek → esm

mryndzionek / esm

Licence: MPL-2.0 License
Lightweight communicating state machine framework for embedded systems

Programming Languages

c
50402 projects - #5 most used programming language
C++
36643 projects - #6 most used programming language
assembly
5116 projects
Makefile
30231 projects
HTML
75241 projects
CMake
9771 projects
python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to esm

STM32F10x Servo Library
Servo library with stm developed by the Liek Software Team. We are working on new versions.
Stars: ✭ 14 (-33.33%)
Mutual labels:  embedded, stm32, embedded-systems, stm32f103
STM32Keyboard
No description or website provided.
Stars: ✭ 15 (-28.57%)
Mutual labels:  embedded, stm32, stm32f103
platformio-libopencm3-freertos
Sample blinky project for PlatformIO using libopencm3 and FreeRTOS
Stars: ✭ 14 (-33.33%)
Mutual labels:  stm32, bluepill, stm32f103
BlueVGA
VGA library for STM32F103C (BluePill) that can manipulate a screen with 28x30 tiles with 8x8 pixels each, in a total resolution of 224x240 pixels with 8 colors using a very low footprint
Stars: ✭ 39 (+85.71%)
Mutual labels:  stm32, bluepill, stm32f103
Hfsm2
High-Performance Hierarchical Finite State Machine Framework
Stars: ✭ 134 (+538.1%)
Mutual labels:  embedded, state-machine, embedded-systems
stm32 tiny monitor
A tiny external monitor for PC using STM32 and ST7789. Connects to PC over USB and displays the captured screen on ST7789 (240x240) display.
Stars: ✭ 61 (+190.48%)
Mutual labels:  stm32, bluepill, stm32f103
MPU60X0
Fast, Lightweight STM32 I2C HAL Driver for the MPU6000/MPU6050 IMU
Stars: ✭ 15 (-28.57%)
Mutual labels:  stm32, embedded-systems
kocherga
Robust platform-agnostic Cyphal/DroneCAN bootloader for deeply embedded systems
Stars: ✭ 21 (+0%)
Mutual labels:  embedded, embedded-systems
async-stm32f1xx
Abstractions for asynchronous programming on the STM32F1xx family of microcontrollers.
Stars: ✭ 24 (+14.29%)
Mutual labels:  embedded, stm32
stm32f10x makefile freertos
stm32f10x gcc makefile freertos
Stars: ✭ 28 (+33.33%)
Mutual labels:  stm32, stm32f103
pydevmem
Python interface to /dev/mem
Stars: ✭ 41 (+95.24%)
Mutual labels:  embedded, embedded-systems
statemachine-go
🚦 Declarative Finite-State Machines in Go
Stars: ✭ 47 (+123.81%)
Mutual labels:  state-machine, statecharts
STM32-Bare-Metal
STM32F103C8 bare metal template
Stars: ✭ 26 (+23.81%)
Mutual labels:  stm32, stm32f103
BIPES
BIPES: Block based Integrated Platform for Embedded Systems allows text and block based programming for several types of embedded systems and Internet of Things modules using MicroPython, CircuitPython, Python or Snek. You can connect, program, debug and monitor several types of boards using network, USB or Bluetooth. No software install needed!
Stars: ✭ 72 (+242.86%)
Mutual labels:  embedded, embedded-systems
STM32F103 MSD BOOTLOADER
STM32F103 Mass Storage Device Bootloader
Stars: ✭ 23 (+9.52%)
Mutual labels:  stm32, stm32f103
statechart
A rust implementation of statecharts: hierarchical, reactive state machines
Stars: ✭ 41 (+95.24%)
Mutual labels:  reactive, state-machine
lwprintf
Lightweight printf library optimized for embedded systems
Stars: ✭ 98 (+366.67%)
Mutual labels:  embedded, embedded-systems
vt100 stm32
VT100 Terminal Emulator for Arduino STM32
Stars: ✭ 27 (+28.57%)
Mutual labels:  stm32, bluepill
MPU6050
STM32 HAL library for GY-521 (MPU6050) with Kalman filter
Stars: ✭ 114 (+442.86%)
Mutual labels:  stm32, bluepill
i2c-sniffer
Debugging tool for I2C networks, built for STM32 microcontrollers
Stars: ✭ 22 (+4.76%)
Mutual labels:  stm32, stm32f103

Efficient State Machine framework

status

Introduction

Good system design is often about knowing what to avoid. Unrestricted use of traditional techniques for writing concurrent software, like preemptive threading, almost always results in systems that are unpredictable and unreliable. Degradation of those two aspects is specially problematic in embedded systems where predictability and reliability are even more important than performance and/or expressiveness.

Active Object Model brings the same improvements to behavioral design as Object Orientation to architectural design. Active objects are objects that encapsulate own flow of control and are designed as message pumps with Run-to-completion (RTC) semantics and explicit state machine structure.

Adapting Active Object Model allows for construction of comprehensible concurrent programs. Resulting conceptual integrity has also added benefit of making it possible to spend effort on design instead of implementation. Implementation step in this method is, for the most part, mechanical process and as such, can be automated.

This repository gathers all the ideas and implementation tricks around lightweight, efficient statecharts and AOM implementation in C. Inspired by QP framework. It's basically a simple cooperative priority-based scheduler and a (hierarchical) state machine framework. Some implementation techniques and design patterns (like 'Embedded Anchor' and linker-section-based 'plugin' system) are borrowed from Linux kernel.

Another interesting feature is the possibility of running the system without delays, so as fast as possible. Having the inputs defined explicitly makes mocking them out easy and then linking with the test platform produces a binary that can generate an execution log containing days worth of system operation in seconds. Then it's easy to analyze the log (e.g. in an Excel spreadsheet) for safety/liveness properties. Sort of poor man's model checker 😃.

Provided are following examples/demos:

There are also two more complex apps:

Simplest Example

In the form of hierarchical state machine (statechart) the logic of a single 'blinker' is:

blink

The code implementing this is a set of pointers to structures (black arrows) encoding the hierarchy and pointer assignments in switch/case handlers (transitions - red arrows):

blink_dot

// Blink state machine configuration structure
// It's kept in read-only memory and holds the delay
// the machine will stay in state before transitioning to another

typedef struct {
	const uint32_t delay;
	const uint8_t led_num;
} blink_cfg_t;

// Structure representing the machine object (active object)
// Timer is used to schedule timeout signal on which machine changes state

typedef struct {
	hesm_t esm;
	esm_timer_t timer;
	blink_cfg_t const *const cfg;
} blink_esm_t;

// Define two top-level states (state structures) 'active' and 'paused'

ESM_COMPLEX_STATE(active, top, 1);
ESM_LEAF_STATE(paused, top, 1);

// Define two nested states 'on' and 'off'

ESM_LEAF_STATE(on, active, 2);
ESM_LEAF_STATE(off, active, 2);

static void esm_active_init(esm_t *const esm)
{
	(void)esm;
	ESM_TRANSITION(on);
}

static void esm_active_entry(esm_t *const esm)
{
	(void)esm;
}

static void esm_active_exit(esm_t *const esm)
{
	blink_esm_t *self = ESM_CONTAINER_OF(esm, blink_esm_t, esm);
	esm_timer_rm(&self->timer);
}

static void esm_active_handle(esm_t *const esm, const esm_signal_t * const sig)
{
	(void)esm;

	switch(sig->type)
	{
	case esm_sig_button:
		ESM_TRANSITION(paused);
		break;
	default:
		ESM_TRANSITION(unhandled);
		break;
	}
}

static void esm_on_entry(esm_t *const esm)
{
	blink_esm_t *self = ESM_CONTAINER_OF(esm, blink_esm_t, esm);
	esm_signal_t sig = {
			.type = esm_sig_tmout,
			.sender = esm,
			.receiver = esm
	};
	esm_timer_add(&self->timer,
			self->cfg->delay>>3, &sig);

	BOARD_LED_ON(self->cfg->led_num);
}

static void esm_on_exit(esm_t *const esm)
{
	(void)esm;
}

static void esm_on_handle(esm_t *const esm, const esm_signal_t * const sig)
{
	switch(sig->type)
	{
	case esm_sig_tmout:
		ESM_TRANSITION(off);
		break;
	default:
		ESM_TRANSITION(unhandled);
		break;
	}
}

static void esm_off_entry(esm_t *const esm)
{
	blink_esm_t *self = ESM_CONTAINER_OF(esm, blink_esm_t, esm);
	esm_signal_t sig = {
			.type = esm_sig_tmout,
			.sender = esm,
			.receiver = esm
	};
	esm_timer_add(&self->timer,
			self->cfg->delay, &sig);
	BOARD_LED_OFF(self->cfg->led_num);
}

static void esm_off_exit(esm_t *const esm)
{
	(void)esm;
}

static void esm_off_handle(esm_t *const esm, const esm_signal_t * const sig)
{
	switch(sig->type)
	{
	case esm_sig_tmout:
		ESM_TRANSITION(on);
		break;
	default:
		ESM_TRANSITION(unhandled);
		break;
	}
}

static void esm_paused_entry(esm_t *const esm)
{
	blink_esm_t *self = ESM_CONTAINER_OF(esm, blink_esm_t, esm);
	BOARD_LED_OFF(self->cfg->led_num);
}

static void esm_paused_exit(esm_t *const esm)
{
	(void)esm;
}

static void esm_paused_handle(esm_t *const esm, const esm_signal_t * const sig)
{
	switch(sig->type)
	{
	case esm_sig_button:
		ESM_TRANSITION(active);
		break;
	default:
		ESM_TRANSITION(unhandled);
		break;
	}
}

static void esm_blink_init(esm_t *const esm)
{
	ESM_TRANSITION(active);
}

// Configuration structure of machine instance 'blink_1'
static const blink_cfg_t blink1_cfg = {
		.delay = 300UL,
		.led_num = 0
};

// Register instance 'blink_1' of the blink machine with the framework
ESM_COMPLEX_REGISTER(blink, blink1, esm_gr_blinkers, 2, 3, 0);

Recommended reading

Books:

Articles:

Build instructions

Standard CMake routine with some configuration options. Currently most extensively tested with:

cmake version 3.16.3
arm-none-eabi-gcc (15:9-2019-q4-0ubuntu1) 9.2.1 20191025
libnewlib-arm-none-eabi 3.3.0-0ubuntu1

Project setup for native Linux:

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..

Project setup for test mode on Linux:

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DESM_PLATFORM=test -DESM_BOARD=native ..

For STM32 target (bluepill board):

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DESM_PLATFORM=stm32 -DESM_BOARD=bluepill \
      -DCMAKE_TOOLCHAIN_FILE=../platform/stm32/Toolchain.cmake ..

Build step:

make

TODO

  • adding hierarchical state machine support
  • add proper platform (BSP) separation
  • change to more flexible build system (CMake)
  • evaluate usefulness of publish-subscribe (efficient implementation limits signal types to 31)
  • switch from array to list in main scheduler loop
  • research and implement efficient priority support
  • add more examples
  • handle timer rollover
  • add automatic tests

License

  • MPLv2

Contact

If you have questions, contact Mariusz Ryndzionek at:

[email protected]

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].