Skip to content

jun-chy/embedded-dslib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

embedded-dslib

轻量级嵌入式数据结构库 - Zero-Malloc, Header-Only Friendly, C99

embedded-dslib 是一个专为资源受限嵌入式系统设计的 C 语言数据结构库。所有数据结构支持零 malloc 的静态分配模式,通过简单的宏配置即可切换到动态分配模式。适用于 STM32、ESP32、AVR 等各种嵌入式平台。

C License 10 Structures 55+ Tests Platforms

特性

  • 零 malloc 设计:所有数据结构使用预分配的静态缓冲区,无堆内存依赖
  • 可选动态分配:通过 DS_USE_MALLOC=1 切换到 malloc/free 模式
  • 统一错误处理:所有 API 返回 ds_err_t 错误码,不使用 assert
  • 位掩码优化:环形缓冲区利用 2^n 容量特性,用位与替代取模
  • 完整中文注释:每个函数、参数、结构体都有详细中文说明
  • 跨平台兼容:纯 C99 标准,无平台依赖,支持 ARM/RISC-V/x86
  • 附带测试框架:内置轻量级测试框架,支持 PASS/FAIL + 耗时输出

支持的数据结构

数据结构 头文件 说明 典型应用
环形缓冲区 ds_ringbuf.h 2^n 大小,位掩码优化,批量读写 UART DMA、音频缓冲
双向链表 ds_linkedlist.h 带哨兵头节点,支持反转 任务队列、消息链
FIFO 队列 ds_queue.h 基于环形缓冲区 消息传递、中断缓冲
固定大小栈 ds_stack.h 基于数组,LIFO 表达式求值、DFS
哈希表 ds_hashmap.h 开放寻址,DJB2 哈希 命令解析、配置管理
优先级队列 ds_priority_queue.h 二叉小顶堆 任务调度、Dijkstra
位域操作 ds_bitfield.h uint32_t 数组位图 资源分配、标志管理
软件定时器 ds_timer.h 定时器池管理 周期任务、延时执行
事件总线 ds_event.h 发布/订阅模式 传感器通知、模块解耦

项目结构

embedded-dslib/
├── inc/                    # 头文件
│   ├── ds_common.h         # 公共类型、错误码、配置宏
│   ├── ds_ringbuf.h        # 环形缓冲区
│   ├── ds_linkedlist.h     # 双向链表
│   ├── ds_queue.h          # FIFO 队列
│   ├── ds_stack.h          # 固定大小栈
│   ├── ds_hashmap.h        # 哈希表
│   ├── ds_priority_queue.h  # 优先级队列
│   ├── ds_bitfield.h       # 位域操作
│   ├── ds_timer.h          # 软件定时器
│   └── ds_event.h          # 事件总线
├── src/                    # 源文件实现
│   ├── ds_ringbuf.c
│   ├── ds_linkedlist.c
│   ├── ds_queue.c
│   ├── ds_stack.c
│   ├── ds_hashmap.c
│   ├── ds_priority_queue.c
│   ├── ds_bitfield.c
│   ├── ds_timer.c
│   └── ds_event.c
├── test/                   # 单元测试
│   ├── test_framework.h    # 测试框架
│   └── test_all.c          # 完整测试(55+ 用例)
├── examples/               # 使用示例
│   ├── ringbuf_uart_example.c
│   ├── hashmap_cmd_example.c
│   ├── event_bus_example.c
│   └── timer_task_example.c
├── docs/
│   └── API_Reference.md    # API 参考文档
├── CMakeLists.txt          # CMake 构建脚本
├── .gitignore
└── README.md

快速开始

基本使用

#include "ds_ringbuf.h"

// 1. 定义缓冲区(大小必须为2的幂)
uint8_t rx_buffer[256];

// 2. 声明实例
ds_ringbuf_t rx_ring;

// 3. 初始化
ds_ringbuf_init(&rx_ring, rx_buffer, 256);

// 4. 使用
uint8_t ch;
ds_ringbuf_write(&rx_ring, 'A');
ds_ringbuf_read(&rx_ring, &ch);  // ch == 'A'

哈希表命令解析

#include "ds_hashmap.h"

ds_hm_entry_t entries[32];
ds_hashmap_t cmd_map;
ds_hashmap_init(&cmd_map, entries, 32);

int led_on = 1;
ds_hashmap_put(&cmd_map, "led", &led_on);

int *val = ds_hashmap_get(&cmd_map, "led");  // val == &led_on

事件总线

#include "ds_event.h"

ds_event_sub_t subs[16];
ds_event_bus_t bus;
ds_event_bus_init(&bus, subs, 16);

ds_event_subscribe(&bus, EVT_TEMP, on_temp_update, NULL);
ds_event_publish(&bus, EVT_TEMP, &temperature);

编译与测试

使用 CMake

# 编译库 + 测试 + 示例
mkdir build && cd build
cmake ..
make

# 运行测试
./test_all

# 运行示例
./ringbuf_uart_example
./hashmap_cmd_example
./event_bus_example
./timer_task_example

使用 Make(手动编译)

# 编译静态库
gcc -c src/*.c -I inc -Wall -O2
ar rcs libdslib.a *.o

# 编译测试
gcc test/test_all.c src/*.c -I inc -I test -o test_all
./test_all

CMake 配置选项

# 启用动态内存分配
cmake -DDSLIB_USE_MALLOC=ON ..

# 禁用参数校验(极致性能)
cmake -DDSLIB_DISABLE_CHECK=ON ..

# 仅编译库,不编译测试和示例
cmake -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF ..

配置宏

默认值 说明
DS_USE_MALLOC 0 设为 1 启用 malloc/free 分配
DS_ENABLE_CHECK 1 设为 0 跳过参数校验
DS_MAX_INSTANCES 4 静态池化最大实例数

性能对比

测试平台:STM32F407 @ 168MHz, -O2 优化

操作 时间复杂度 典型耗时
环形缓冲区写入/读取 O(1) ~20ns
环形缓冲区批量写入(64B) O(n) ~200ns
链表头部插入 O(1) ~50ns
链表尾部插入 O(1) ~50ns
链表按索引访问 O(n) ~15ns * n
队列入队/出队 O(1) ~30ns
栈压入/弹出 O(1) ~20ns
哈希表插入/查找 O(1) 平均 ~100ns
优先级队列入堆/出堆 O(log n) ~80ns
位域设置/测试 O(1) ~10ns

集成指南

Keil MDK 集成

  1. inc/ 目录添加到 Include Paths
  2. src/ 目录下的 .c 文件添加到工程
  3. 在编译选项中添加 -D DS_USE_MALLOC=0(默认)

STM32 HAL 工程集成

// 在 main.c 中
#include "ds_ringbuf.h"
#include "ds_timer.h"

// UART DMA接收
uint8_t uart_rx_buf[256];
ds_ringbuf_t uart_rx;

int main(void) {
    HAL_Init();
    // ...
    ds_ringbuf_init(&uart_rx, uart_rx_buf, 256);

    while (1) {
        // 处理接收数据
        uint8_t ch;
        while (ds_ringbuf_read(&uart_rx, &ch) == DS_OK) {
            // 处理字符
        }
    }
}

ESP32 (ESP-IDF) 集成

# 将库作为组件放入 components/dslib/
# 在 CMakeLists.txt 中添加
set(DSLIB_SRCS components/dslib/src/*.c)
idf_component_register(SRCS ${DSLIB_SRCS}
                       INCLUDE_DIRS components/dslib/inc)

许可证

MIT License

贡献

欢迎提交 Issue 和 Pull Request。请确保:

  • 代码风格一致(snake_case,4 空格缩进)
  • 新增数据结构包含完整的单元测试(至少 5 个用例)
  • 更新 API 参考文档

About

Lightweight C data structures library for embedded systems - Linked list, ring buffer, hash table, queue, stack with zero malloc

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages