1. 单片机双链表实现解析:从原理到实战
在嵌入式开发中,数据结构的选择直接影响系统性能和资源利用率。双链表因其高效的插入/删除特性,成为处理动态数据的理想选择。今天分享一个在STM32等单片机环境实现的双向链表模块,支持头尾插入、任意位置删除等操作,并内置线程安全保护机制。
这个实现有三大特点:
- 采用环形链表结构,头节点同时作为哨兵节点
- 通过临界区保护实现线程安全
- 内存管理可适配不同平台(malloc/free可替换)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心数据结构设计
2.1 节点结构定义
c复制typedef struct sListData {
uint16_t len; // 数据长度
uint8_t *pstr; // 数据指针
uint8_t buff[]; // 柔性数组
} ListData_t;
typedef struct sListNode {
struct sListNode *next; // 后继指针
struct sListNode *prev; // 前驱指针
ListData_t val; // 数据域
} ListNode_t;
设计要点:
- 使用柔性数组实现变长数据存储,避免二次内存分配
- 前后指针采用经典的双链表结构
- 数据长度字段支持二进制安全操作
- 默认采用环形链表设计(头节点的prev指向尾节点)
2.2 线程安全实现
c复制#define LIST_LOCK_STATE // 声明临界区状态
#define LIST_LOCK __disable_irq() // 进入临界区
#define LIST_UNLOCK __enable_irq() // 退出临界区
安全策略:
- 所有链表操作都包裹在临界区内
- 通过关中断实现最简单的互斥保护
- 可替换为RTOS的互斥锁(如FreeRTOS的xSemaphore)
注意:在RTOS环境下建议替换为更精细的锁机制,长时间关中断会影响系统实时性
3. 关键操作实现解析
3.1 链表初始化
c复制ListNode_t* ListCreate(void) {
ListData_t list;
LIST_LOCK;
list.len = 1;
list.pstr = NULL;
ListNode_t *head = ListAppliNode(&list);
if(head == NULL) {
LIST_UNLOCK;
return NULL;
}
