Static Allocation

Introduction

This document describes the static allocation component of EasyEmbeddedFramework. It explains the structure, behavior, and data types used in the static memory allocator implementation. The static allocation component provides a malloc/free-like API for managing memory from a user-provided static buffer, suitable for embedded systems without dynamic memory allocation.

The static allocation component allows users to:

  • Initialize a memory manager with a static buffer

  • Allocate and free memory blocks from the buffer

  • Track allocated and free memory blocks

  • Query the number of allocated and free blocks

  • Print memory usage for debugging

Limitations:

  • Not thread-safe by default

  • Buffer size is fixed at initialization

  • No memory compaction or defragmentation beyond adjacent block merging

Use cases:

  • Memory management in bare-metal or RTOS-based embedded systems

  • Replacement for malloc/free in environments without heap

  • Buffer management for communication stacks or data structures

Component’s structure

The static allocation component is composed of the following elements: - MemList (or ezmMemList): Main structure managing the static buffer, free list, and allocated list - MemBlock: Header for each memory block, used for both free and allocated blocks - Node: Linked list node for managing block lists - User-provided static memory buffer (uint8_t array)

Mermaid diagram:

        classDiagram
  class MemList {
    Node free_list_head
    Node alloc_list_head
    uint8_t* buff
    uint16_t buff_size
  }
  class MemBlock {
    Node node
    void* buff
    uint16_t buff_size
  }
  MemList o-- "*" MemBlock : manages
  MemBlock o-- Node : node
  MemList o-- "1" uint8_t : buff
    

Component’s behavior

External behavior:

  • Users can initialize the memory manager, allocate memory blocks, free blocks, and query memory usage.

  • Memory is allocated from the static buffer; freed blocks are returned to the free list and may be merged with adjacent free blocks.

  • Debugging functions allow printing the state of the memory manager.

Internal behavior:

  • The memory manager maintains two linked lists: one for free blocks and one for allocated blocks.

  • When allocating, the manager searches for a free block large enough for the request, splits it if necessary, and moves it to the allocated list.

  • When freeing, the block is removed from the allocated list, added to the free list, and adjacent free blocks are merged.

  • The buffer and all block headers are statically allocated; no dynamic memory is used.

Component’s data type

The static allocation component uses the following data types:

  • MemList / ezmMemList: Structure managing the memory buffer and block lists

  • MemBlock: Structure representing each memory block

  • Node: Linked list node for block management

  • uint8_t*: Pointer to the static memory buffer

  • uint16_t: For buffer size and block sizes

  • bool: For status returns

All memory managed by this component is accessed as void pointers, allowing flexible use for different data types.