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

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

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

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循环) 复杂(指针管理)
调试难度 容易(索引清晰) 较难(指针追踪)
扩展性 固定大小,编译时确定 运行时动态添加
适用场景 协议解析、过滤器、校验链 动态审批流、插件系统
相关推荐
风逸尘_lz3 小时前
05-LPB3568针对不同网段实现UDP通信
网络·网络协议·udp
学编程就要猛3 小时前
JavaEE初阶:网络编程
运维·服务器·网络
北京聚信万通科技有限公司3 小时前
北京聚信万通科技有限公司获Odette CA官方授权,成为中国区“Odette ID及数字证书”官方注册审批管理机构
网络·科技·汽车·edi·电子数据交换·国产软件
2501_948114243 小时前
Claude Sonnet 4.6 深度评测:性能逼近 Opus、成本打骨折,附接入方案与选型指南
大数据·网络·人工智能·安全·架构
TOWE technology3 小时前
智能PDU——电力分配与数据信息的价值
网络·科技·pdu·智能pdu
humors2214 小时前
一些安全类网站(不定期更新)
linux·网络·windows·安全·黑客·白帽
M ? A4 小时前
VuReact 编译器核心重构:统一管理组件元数据收集
前端·javascript·vue.js·react.js·重构·开源
ou.cs4 小时前
c# SemaphoreSlim保姆级教程
开发语言·网络·c#
V搜xhliang02464 小时前
多期CT影像组学融合临床危险因素模型预测甲状腺乳头状癌中央区淋巴结转移的价值
人工智能·重构·机器人