使用数组重构责任链实现通信协议解析

在嵌入式软件中,使用数组实现责任链模式是一种高效且易于维护的设计方法。相比链表,数组实现具有内存连续、访问速度快、代码简洁等优势,非常适合资源受限且对实时性要求高的嵌入式环境

为什么在嵌入式中用数组实现责任链?

1.内存连续,缓存友好:数组在内存中是连续存储的,遍历时CPU缓存命中率高,执行效率优于链表。

2.无需动态内存分配:可以预先定义固定大小的数组,避免使用 malloc/free,降低内存碎片风险。

3.代码简洁,易于调试:使用 for 循环遍历,逻辑清晰,调试时更容易追踪执行流程。

4.适合静态配置:嵌入式系统通常在编译时确定功能模块,数组非常适合这种"静态组装、动态执行"的模式。

以串口协议解析为例,实现一个基于数组的责任链
第一步:定义统一的处理器接口

c 复制代码
// protocol_handler.h
#ifndef PROTOCOL_HANDLER_H
#define PROTOCOL_HANDLER_H

#include <stdint.h>
#include <stdbool.h>

// 处理结果
typedef enum {
    HANDLER_OK,    // 成功处理,链条终止
    HANDLER_PASS,  // 无法处理,继续下一个
    HANDLER_ERROR  // 发生错误,终止链条
} HandlerResult;

// 处理器函数类型
typedef HandlerResult (*HandlerFunc)(uint8_t* data, int len);

// 责任链最大长度
#define MAX_HANDLERS 8

// 责任链结构体
typedef struct {
    HandlerFunc handlers[MAX_HANDLERS];  // 处理器函数数组
    int count;                           // 当前处理器数量
} ProtocolChain;

// 初始化责任链
void chain_init(ProtocolChain* chain);

// 添加处理器
bool chain_add_handler(ProtocolChain* chain, HandlerFunc handler);

// 执行责任链
HandlerResult chain_execute(ProtocolChain* chain, uint8_t* data, int len);

#endif

第二步:实现责任链核心逻辑

c 复制代码
// protocol_handler.c
#include "protocol_handler.h"
#include <string.h>

// 初始化
void chain_init(ProtocolChain* chain) {
    memset(chain->handlers, 0, sizeof(chain->handlers));
    chain->count = 0;
}

// 添加处理器
bool chain_add_handler(ProtocolChain* chain, HandlerFunc handler) {
    if (chain->count >= MAX_HANDLERS) {
        return false; // 数组已满
    }
    chain->handlers[chain->count++] = handler;
    return true;
}

// 执行责任链
HandlerResult chain_execute(ProtocolChain* chain, uint8_t* data, int len) {
    for (int i = 0; i < chain->count; i++) {
        HandlerResult result = chain->handlers[i](data, len);
        if (result != HANDLER_PASS) {
            return result; // OK 或 ERROR 都终止链条
        }
    }
    return HANDLER_PASS; // 所有处理器都未处理
}

第三步:实现具体协议处理器

c 复制代码
// modbus_handler.c
#include "protocol_handler.h"
#include <stdio.h>

// 简单的CRC校验函数(示例)
static bool check_crc(uint8_t* data, int len) {
    // 实际项目中应实现真实CRC算法
    return len >= 4; // 简化判断
}

// Modbus协议处理器
HandlerResult handle_modbus(uint8_t* data, int len) {
    if (len >= 4 && data == 0x01 && check_crc(data, len)) {
        printf("Modbus frame received: ");
        for (int i = 0; i < len; i++) {
            printf("%02X ", data[i]);
        }
        printf("\n");
        // 执行Modbus命令解析...
        return HANDLER_OK;
    }
    return HANDLER_PASS; // 不是Modbus帧,交给下一个
}
c 复制代码
// custom_handler.c
#include "protocol_handler.h"
#include <stdio.h>

// 自定义协议处理器
HandlerResult handle_custom(uint8_t* data, int len) {
    if (len >= 3 && data == 0xAA) {
        printf("Custom protocol: 0x%02X 0x%02X 0x%02X\n", 
               data, data, data);
        // 处理自定义协议...
        return HANDLER_OK;
    }
    return HANDLER_PASS;
}
```<websource>source_group_web_1</websource>

#### 第四步:组装和使用责任链

```c
// main.c
#include "protocol_handler.h"
#include <stdio.h>

// 外部声明处理器
extern HandlerResult handle_modbus(uint8_t*, int);
extern HandlerResult handle_custom(uint8_t*, int);

int main() {
    ProtocolChain chain;
    
    // 1. 初始化责任链
    chain_init(&chain);
    
    // 2. 静态组装责任链(编译时确定顺序)
    chain_add_handler(&chain, handle_custom);   // 先检查自定义协议
    chain_add_handler(&chain, handle_modbus);   // 再检查Modbus
    
    // 3. 模拟串口接收数据
    uint8_t frame1[] = {0xAA, 0x01, 0x02};           // 自定义协议
    uint8_t frame2[] = {0x01, 0x03, 0x00, 0x00};     // Modbus协议
    uint8_t frame3[] = {0xFF, 0xFF, 0xFF};           // 未知协议
    
    printf("--- Processing Frame 1 ---\n");
    chain_execute(&chain, frame1, sizeof(frame1));
    
    printf("\n--- Processing Frame 2 ---\n");
    chain_execute(&chain, frame2, sizeof(frame2));
    
    printf("\n--- Processing Frame 3 ---\n");
    chain_execute(&chain, frame3, sizeof(frame3));
    
    return 0;
}

数组实现 vs 链表实现

特性 数组实现 链表实现
内存使用 静态分配,无碎片 动态分配,可能碎片化
执行效率 高(缓存友好) 较低(指针跳转)
代码复杂度 简单(for循环) 复杂(指针管理)
调试难度 容易(索引清晰) 较难(指针追踪)
扩展性 固定大小,编译时确定 运行时动态添加
适用场景 协议解析、过滤器、校验链 动态审批流、插件系统
相关推荐
折哥的程序人生 · 物流技术专研4 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
专注VB编程开发20年4 小时前
c#Modbus上位机开发-一次读10个地址和100个地址速度一样
网络·网络协议·tcp/ip
2601_961963387 小时前
技术解剖:哈希值、区块链与CA认证如何守护电子合同安全?
网络·人工智能·安全·区块链·智能合约·政务
2601_961963387 小时前
从“电子化”到“自动化”:2026年智能合约与电子合同融合的技术逻辑与法律适配
网络·人工智能·区块链·智能合约·政务
不吃土豆的马铃薯8 小时前
C++ 高性能网络缓冲区 Buffer 源码解析
linux·服务器·开发语言·网络·c++
dog2509 小时前
网络可用性,扩展性,性能的统计本质
网络
嵌入式-老费10 小时前
esp32开发与应用(再谈wifi的使用)
网络·智能路由器
YJlio10 小时前
《Sysinternals实战指南》16.5 Ctrl2Cap 工具详解:把 Caps Lock 变成 Ctrl 的键盘改造与回退方法
linux·运维·服务器·网络·python·学习·计算机外设
wangxixi52210 小时前
OTN 以太网业务接入全流程详解
网络
带土110 小时前
5. 网络体系架构与WireShark简单使用
网络·测试工具·wireshark