Dynamic memory management is one of the core challenges in embedded development. Many bare-metal platforms and lightweight RTOS do not provide standard <span>malloc()</span> and <span>free()</span> interfaces, leading to poor code portability and difficult resource management. Today, we introduce libmemory, an open-source tool designed to solve this pain point. This article will explore all aspects of this library.
Why You Need to Pay Attention to Libmemory?
In embedded development, dynamic memory management has always been a “taboo topic”. The traditional view holds that:
- Real-time systems must avoid dynamic memory allocation
- The standard library’s
<span>malloc()</span>implementation is too bulky - Memory APIs of different RTOS are incompatible
Libmemory breaks these shackles through three revolutionary designs:
- Minimal Implementation: Basic memory management requires only a 4MB initial memory block
- RTOS Adaptation Layer: Unifies memory APIs for FreeRTOS/ThreadX and others
- Standardized Interface: Directly uses ANSI C’s
<span>malloc/free</span>specifications
// Example: Allocate 4MB heap space at address 0xDEADBEEF
malloc_addblock(0xDEADBEEF, 4 * 1024 * 1024);
Core Technology Analysis
The core competitiveness of libmemory lies in its architecture design and algorithm optimization:
1. Free List Algorithm
- Uses the classic free-list strategy to manage memory blocks
- Supports memory merging to prevent fragmentation
- Provides
<span>aligned_malloc()</span>for aligned allocation
2. Cross-Platform Support
- Supports x86/x64/ARM/ARM64 architectures
- Compilation system adapts to GCC/Clang/ARM-GCC
- Provides FreeRTOS/ThreadX/EVM framework adaptation layer
3. Safety Verification
- Unit tests cover basic allocation/deallocation functions
- Boundary checks prevent out-of-bounds access
- Memory block tracking mechanism (in development)
Quick Start in Five Minutes
Hardware Requirements
- Any MCU that supports C language
- At least 4KB of available RAM (recommended)
Development Environment Setup
# Install required toolchain
sudo apt install git-lfs meson ninja-build
pip3 install meson
# Clone the repository (note to use --recursive)
git clone --recursive [email protected]:embeddedartistry/libmemory.git
# Compile for ARM Cortex-M4 version
meson buildresults --cross-file build/cross/gcc_arm_cortex-m4.txt
ninja -C buildresults
Key API Quick Reference
// Initialize heap memory
void malloc_addblock(void* addr, size_t size);
// Standard memory allocation
void* malloc(size_t size);
void free(void* ptr);
// Aligned memory allocation
void* aligned_malloc(size_t align, size_t size);
void aligned_free(void* ptr);
Deep Customization of Build System
Libmemory uses the Meson build system, supporting high customization:
Typical Compilation Scenarios
# Native compilation (development testing)
meson buildresults -Denable-pedantic-error=true
# Cross-compilation for ARMv7
meson buildresults --cross-file build/cross/gcc_arm_cortex-m7.txt
# Enable RTOS adaptation layer
meson configure -Duse-libc-subproject=true
Configuration Options Explained
| Option Name | Description |
|---|---|
| enable-pedantic | Enable strict compilation warnings |
| libc-subproject | Specify C library subproject dependencies |
| use-libc-subproject | Enable custom C library configuration |
Practical Integration Guide
Solution 1: Traditional Embedded Project
- Copy
<span>include/</span>directory to the project source tree - Link
<span>buildresults/src/libmemory_freelist.a</span> - Initialize heap memory in the startup code
Solution 2: Meson Project Integration
libmemory = subproject('libmemory')
executable('my_firmware',
sources: ['main.c'],
dependencies: libmemory.get_variable('libmemory_freertos_dep'))
Debugging Tips
- Use
<span>MALLOC_DEBUG=1</span>to enable allocation logging - Periodically call
<span>malloc_stats()</span>to check memory status - Mock memory interfaces for unit testing using wrap files
Performance Optimization Secrets
Memory Block Partitioning Strategy
- It is recommended to partition multiple memory pools by function
- Critical tasks should use separate memory blocks
- Adjust block sizes dynamically to reduce fragmentation
// Create a memory pool dedicated to cache
malloc_addblock(0x20000000, 64*1024); // 64KB cache
RTOS Adaptation Optimization
- Use
<span>pvPortMalloc</span>wrapper in FreeRTOS - Configure
<span>tx_byte_allocate</span>callback for ThreadX - Implement thread safety through
<span>malloc_lock()</span>
Conclusion
Libmemory brings three core values to embedded developers:
- Standardization: Unifies memory management interfaces across platforms
- Lightweight: Minimal implementation requires only hundreds of bytes of RAM
- Portability: Supports everything from 8-bit MCUs to 64-bit processors
Whether for bare-metal development, RTOS porting, or hybrid memory architecture design, libmemory demonstrates strong adaptability. The active community support and clear architectural roadmap make it a benchmark solution in the field of embedded memory management.
Project link: https://github.com/embeddedartistry/libmemory