当前位置: 首页 > news >正文

嵌入式通信协议框架的四层架构设计与实现

文章目录

  • 一、硬件抽象层:数据收发的基石
    • 1.1 设计要点
    • 1.2 代码示例
  • 二、协议管理层:智能路由中枢
    • 2.1 设计要点
    • 2.2 代码示例
  • 三、协议处理层:协议具体实现
    • 3.1 设计要求
    • 3.2代码示例
      • 3.2.1 协议公共定义
      • 3.2.2 协议一设计
      • 3.2.3 协议二设计
  • 四、应用层:业务逻辑实现
    • 4.1 设计要点
    • 4.2 代码示例
      • 4.2.1 协议一处理
      • 4.2.2 协议二处理
  • 五、四层协作流程
    • 5.1 收发流程
    • 5.2 代码示例
  • 总结


在嵌入式系统开发中,高效可靠的通信协议栈设计对系统稳定性至关重要。本文将深入剖析一种四层通信协议架构设计,从硬件抽象到应用处理逐层分解,帮助开发者构建灵活、可扩展的嵌入式通信系统。

下面我将完整展示每个层次的示例代码实现,并附上详细说明。这个架构已被多个工业级项目验证,能够处理复杂的通信需求。

一、硬件抽象层:数据收发的基石

硬件抽象层是与具体硬件打交道的底层,需要处理最原始的数据收发和缓冲管理。

1.1 设计要点

  1. 双缓冲设计:独立的发送和接收缓冲区避免数据竞争

  2. 环形队列:高效利用缓冲区空间,避免频繁内存分配

  3. 硬件封装:drv_custom_can_开头的函数是硬件驱动接口

  4. 状态管理:通过can_t结构体维护通信状态

  5. 错误隔离:硬件错误不会直接影响上层逻辑

1.2 代码示例

/* 缓冲区大小配置 */
#define CUSTOM_CAN_TX_BUFFER_SIZE 1024
#define CUSTOM_CAN_RX_BUFFER_SIZE 512/* 静态缓冲区分配 */
static uint8_t custom_can_tx_buf[CUSTOM_CAN_TX_BUFFER_SIZE];
static uint8_t custom_can_rx_buf[CUSTOM_CAN_RX_BUFFER_SIZE];/* CAN硬件信息结构体 */
typedef struct {uint8_t* tx_buf;        // 发送缓冲区指针uint8_t* rx_buf;        // 接收缓冲区指针uint16_t tx_buf_size;   // 发送缓冲区大小uint16_t rx_buf_size;   // 接收缓冲区大小bool tx_running;        // 发送状态标志bool can_error;         // 错误状态标志RingQueue rx_queue;     // 接收环形队列RingQueue tx_queue;     // 发送环形队列
} can_t;/* CAN硬件信息实例 */
static can_t custom_can_info = {.tx_buf = custom_can_tx_buf,.rx_buf = custom_can_rx_buf,.tx_buf_size = CUSTOM_CAN_TX_BUFFER_SIZE,.rx_buf_size = CUSTOM_CAN_RX_BUFFER_SIZE,.tx_running = false,.can_error = false,
};/* 获取CAN信息结构体指针 */
can_t* get_custom_can_info(void)
{return &custom_can_info;
}/* 硬件初始化函数 */
void custom_can_init(void)
{can_t* can_info = get_custom_can_info();/* 初始化收发环形队列 */init_queue(&can_info->rx_queue, can_info->rx_buf, can_info->rx_buf_size);init_queue(&can_info->tx_queue, can_info->tx_buf, can_info->tx_buf_size);/* 硬件特定初始化 */drv_custom_can_hw_init();/* 上层协议初始化 */protocol_manager_init();
}/* 清空接收队列 */
void custom_can_rx_queue_clear(void)
{can_t* can_info = get_custom_can_info();clear_queue(&can_info->rx_queue);
}/* 获取接收队列数据长度 */
uint16_t custom_can_rx_queue_len(void)
{can_t* can_info = get_custom_can_info();return queue_length(&can_info->rx_queue);
}/* 从接收队列读取数据 */
uint16_t custom_can_read(uint8_t* buf, uint16_t read_len)
{can_t* can_info = get_custom_can_info();return read_block_queue(buf, &can_info->rx_queue, read_len);
}/* 发送数据接口 */
uint16_t custom_can_puts(const uint8_t *src, uint16_t len)
{/* 调用硬件驱动发送 */return drv_custom_can_puts(src, len);
}

二、协议管理层:智能路由中枢

协议管理层是框架的核心枢纽,负责协议的识别和路由。

2.1 设计要点

  1. 插件架构:通过描述符动态注册协议

  2. 自动识别:基于特征值快速识别协议类型

  3. 统一接口:为上层提供一致的解析和构建接口

  4. 类型安全:使用强类型避免错误

  5. 可扩展性:易于添加新协议支持

2.2 代码示例

/* 最大支持的协议数量 */
#define MAX_PROTOCOLS 5/* 自动解析协议数据 */
ProtocolStatus parse_protocol_auto(const uint8_t* data, uint16_t length, ProtocolType* type, void* frame, size_t frame_size
);/* 协议1发送接口 */
ProtocolStatus send_protocol1(uint16_t src_id,uint16_t dest_id,uint8_t cmd_set,uint8_t cmd_id,const uint8_t* data,uint16_t data_len
);/* 协议2发送接口 */ 
ProtocolStatus send_protocol2(uint8_t src_id,uint8_t dest_id,uint8_t cmd_id,const uint8_t* data,uint16_t data_len
);/* 已注册协议数组 */
static const ProtocolDescriptor* registered_protocols[MAX_PROTOCOLS];
static int protocol_count = 0;/* 协议管理器初始化 */
void protocol_manager_init(void) 
{if (protocol_count == 0) {/* 注册协议1 */registered_protocols[protocol_count++] = &protocol1_descriptor;/* 注册协议2 */registered_protocols[protocol_count++] = &protocol2_descriptor;/* 可扩展注册更多协议... */}
}/* 协议自动识别 */
static ProtocolType detect_protocol(const uint8_t* data, uint16_t length) 
{if (length < 1) return PROTOCOL_UNKNOWN;/* 检查协议1特征 */if (data[0] == PROTOCOL1_HEADER) {return PROTOCOL_TYPE_1;} /* 检查协议2特征 */else if (length >= 2 && data[0] == PROTOCOL2_HEADER_1 && data[1] == PROTOCOL2_HEADER_2) {return PROTOCOL_TYPE_2;}return PROTOCOL_UNKNOWN;
}/* 获取协议描述符 */
static const ProtocolDescriptor* get_protocol(ProtocolType type) 
{for (int i = 0; i < protocol_count; i++) {if (registered_protocols[i]->type == type) {return registered_protocols[i];}}return NULL;
}/* 通用协议解析入口 */
ProtocolStatus parse_protocol_auto(const uint8_t* data, uint16_t length, ProtocolType* type, void* frame, size_t frame_size) 
{/* 1. 协议识别 */ProtocolType detected_type = detect_protocol(data, length);if (detected_type == PROTOCOL_UNKNOWN) {return PROTOCOL_ERR_TYPE;}/* 2. 获取协议描述符 */const ProtocolDescriptor* proto = get_protocol(detected_type);if (!proto || frame_size < proto->frame_size) {return PROTOCOL_ERR_TYPE;}/* 3. 调用具体协议解析 */*type = detected_type;return proto->parse(data, length, frame);
}/* 构建协议数据 */
static ProtocolStatus build_protocol(ProtocolType type, const void* frame, uint8_t* buffer, uint16_t buffer_size) 
{const ProtocolDescriptor* proto = get_protocol(type);if (!proto) return PROTOCOL_ERR_TYPE;return proto->build(frame, buffer, buffer_size);
}/* 协议解包处理 */
void custom_can_run_unpack(uint8_t *pdata, uint16_t pdata_len)
{ProtocolType type;union {Protocol1Frame frame1;Protocol2Frame frame2;} frame;/* 1. 自动解析协议 */ProtocolStatus status = parse_protocol_auto(pdata, pdata_len, &type, &frame, sizeof(frame));/* 2. 根据协议类型路由处理 */if (status == PROTOCOL_OK) {switch(type) {case PROTOCOL_TYPE_1:handle_protocol1_data(&frame.frame1);break;case PROTOCOL_TYPE_2:handle_protocol2_data(&frame.frame2);break;default:DEBUG_MSG("Unknown protocol type");break;}} else {DEBUG_MSG("Parse error: %d", status);}
}/* 协议1数据发送实现 */
ProtocolStatus send_protocol1(uint16_t src_id,uint16_t dest_id,uint8_t cmd_set,uint8_t cmd_id,const uint8_t* data,uint16_t data_len) 
{uint8_t send_buf[MAX_PROTOCOL_LEN];/* 构造协议1帧 */Protocol1Frame frame = {.src_id = src_id,.dest_id = dest_id,.cmd_set = cmd_set,.cmd_id = cmd_id,.data_len = data_len,.data = (uint8_t*)data};/* 构建协议1原始数据 */ProtocolStatus status = build_protocol(PROTOCOL_TYPE_1, &frame, send_buf, sizeof(send_buf));/* 通过硬件层发送 */if (status == PROTOCOL_OK) {uint16_t total_len = protocol1_descriptor.min_frame_len + data_len;custom_can_puts(send_buf, total_len);}return status;
}/* 协议2数据发送实现 */
ProtocolStatus send_protocol2(uint8_t src_id,uint8_t dest_id,uint8_t cmd_id,const uint8_t* data,uint16_t data_len) 
{uint8_t send_buf[MAX_PROTOCOL_LEN];/* 构造协议2帧 */Protocol2Frame frame = {.src_id = src_id,.dest_id = dest_id,.cmd_id = cmd_id,.data_len = data_len,.data = (uint8_t*)data};/* 构建协议2原始数据 */ProtocolStatus status = build_protocol(PROTOCOL_TYPE_2, &frame, send_buf, sizeof(send_buf));/* 通过硬件层发送 */if (status == PROTOCOL_OK) {uint16_t total_len = protocol2_descriptor.min_frame_len + data_len;custom_can_puts(send_buf, total_len);}return status;
}

三、协议处理层:协议具体实现

协议处理层包含各具体协议的实现细节(帧结构定义、解析函数、构建函数、校验机制)。

3.1 设计要求

  1. 协议独立性:每个协议完全独立实现
  2. 内存安全:严格检查缓冲区边界
  3. 校验机制:支持多种校验方式
  4. 零拷贝:直接引用原始数据减少拷贝
  5. 标准接口:统一通过描述符暴露功能

3.2代码示例

3.2.1 协议公共定义

/* 协议类型枚举 */
typedef enum {PROTOCOL_TYPE_1 = 1,   // 协议类型1PROTOCOL_TYPE_2 = 2,   // 协议类型2PROTOCOL_UNKNOWN = 0xFF
} ProtocolType;/* 协议处理状态 */
typedef enum {PROTOCOL_OK,            // 处理成功PROTOCOL_ERR_HEADER,    // 头部错误PROTOCOL_ERR_LENGTH,    // 长度错误PROTOCOL_ERR_CHECKSUM,  // 校验错误PROTOCOL_ERR_TYPE,      // 类型错误PROTOCOL_ERR_BUFFER     // 缓冲区不足
} ProtocolStatus;/* 协议解析函数指针 */
typedef ProtocolStatus (*ParseFunc)(const uint8_t*, uint16_t, void* frame);/* 协议构建函数指针 */
typedef ProtocolStatus (*BuildFunc)(const void* frame, uint8_t*, uint16_t);/* 协议描述符结构 */
typedef struct {ProtocolType type;       // 协议类型ParseFunc parse;         // 解析函数BuildFunc build;         // 构建函数uint16_t min_frame_len;  // 最小帧长度size_t frame_size;       // 帧结构体大小
} ProtocolDescriptor;#endif

3.2.2 协议一设计

/* 协议1定义 */
#define PROTOCOL1_HEADER 0x11
#define PROTOCOL1_MIN_LEN 11  // 最小帧长度/* 协议1帧结构 */
typedef struct {uint16_t src_id;       // 源地址uint16_t dest_id;      // 目的地址uint8_t cmd_set;       // 命令集uint8_t cmd_id;        // 命令IDuint16_t data_len;     // 数据长度uint8_t* data;         // 数据指针
} Protocol1Frame;/* 协议1描述符声明 */
extern const ProtocolDescriptor protocol1_descriptor;/* 计算校验和 */
static uint16_t calculate_checksum(const uint8_t* data, uint16_t len) {uint16_t sum = 0;for (uint16_t i = 0; i < len; i++) {sum += data[i];}return sum;
}/* 协议1解析实现 */
static ProtocolStatus parse_protocol1(const uint8_t* data, uint16_t length, void* frame) 
{Protocol1Frame* p1frame = (Protocol1Frame*)frame;/* 检查最小长度 */if (length < PROTOCOL1_MIN_LEN) {return PROTOCOL_ERR_LENGTH;}/* 检查帧头 */if (data[0] != PROTOCOL1_HEADER) {return PROTOCOL_ERR_HEADER;}/* 解析数据长度 */uint16_t data_len = (data[1] << 8) | data[2];/* 检查完整帧长度 */if (length < (PROTOCOL1_MIN_LEN + data_len)) {return PROTOCOL_ERR_LENGTH;}/* 填充帧结构 */p1frame->src_id = (data[3] << 8) | data[4];p1frame->dest_id = (data[5] << 8) | data[6];p1frame->cmd_set = data[7];p1frame->cmd_id = data[8];p1frame->data_len = data_len;p1frame->data = (uint8_t*)&data[9]; // 指向原始数据/* 校验和检查 */uint16_t checksum = (data[9+data_len] << 8) | data[10+data_len];if (checksum != calculate_checksum(&data[1], 8 + data_len)) {return PROTOCOL_ERR_CHECKSUM;}return PROTOCOL_OK;
}/* 协议1构建实现 */
static ProtocolStatus build_protocol1(const void* frame, uint8_t* buffer, uint16_t buffer_size) 
{const Protocol1Frame* p1frame = (const Protocol1Frame*)frame;uint16_t required_len = PROTOCOL1_MIN_LEN + p1frame->data_len;if (buffer_size < required_len) {return PROTOCOL_ERR_BUFFER;}/* 填充固定字段 */buffer[0] = PROTOCOL1_HEADER;buffer[1] = (p1frame->data_len >> 8) & 0xFF;buffer[2] = p1frame->data_len & 0xFF;buffer[3] = (p1frame->src_id >> 8) & 0xFF;buffer[4] = p1frame->src_id & 0xFF;buffer[5] = (p1frame->dest_id >> 8) & 0xFF;buffer[6] = p1frame->dest_id & 0xFF;buffer[7] = p1frame->cmd_set;buffer[8] = p1frame->cmd_id;/* 填充数据 */if (p1frame->data_len > 0) {memcpy(&buffer[9], p1frame->data, p1frame->data_len);}/* 计算校验和 */uint16_t checksum = calculate_checksum(&buffer[1], 8 + p1frame->data_len);buffer[9+p1frame->data_len] = (checksum >> 8) & 0xFF;buffer[10+p1frame->data_len] = checksum & 0xFF;return PROTOCOL_OK;
}/* 协议1描述符定义 */
const ProtocolDescriptor protocol1_descriptor = {PROTOCOL_TYPE_1,parse_protocol1,build_protocol1,PROTOCOL1_MIN_LEN,sizeof(Protocol1Frame)
};

3.2.3 协议二设计

/* 协议2定义 */
#define PROTOCOL2_HEADER_1 0x22
#define PROTOCOL2_HEADER_2 0x33
#define PROTOCOL2_MIN_LEN 9  // 最小帧长度/* 协议2帧结构 */
typedef struct {uint8_t src_id;        // 源地址uint8_t dest_id;       // 目的地址uint8_t cmd_id;        // 命令IDuint16_t data_len;     // 数据长度uint8_t* data;         // 数据指针
} Protocol2Frame;/* 协议2描述符声明 */
extern const ProtocolDescriptor protocol2_descriptor;
/* CRC16计算函数 */
static uint16_t calculate_crc16(const uint8_t* data, uint16_t len) {uint16_t crc = 0xFFFF;for (uint16_t i = 0; i < len; i++) {crc ^= data[i];for (uint8_t j = 0; j < 8; j++) {if (crc & 0x0001) {crc = (crc >> 1) ^ 0xA001;} else {crc >>= 1;}}}return crc;
}/* 协议2解析实现 */
static ProtocolStatus parse_protocol2(const uint8_t* data, uint16_t length, void* frame) 
{Protocol2Frame* p2frame = (Protocol2Frame*)frame;/* 检查最小长度 */if (length < PROTOCOL2_MIN_LEN) {return PROTOCOL_ERR_LENGTH;}/* 检查帧头 */if (data[0] != PROTOCOL2_HEADER_1 || data[1] != PROTOCOL2_HEADER_2) {return PROTOCOL_ERR_HEADER;}/* 解析数据长度 */uint16_t data_len = (data[2] << 8) | data[3];/* 检查完整帧长度 */if (length < (PROTOCOL2_MIN_LEN + data_len)) {return PROTOCOL_ERR_LENGTH;}/* 填充帧结构 */p2frame->src_id = data[4];p2frame->dest_id = data[5];p2frame->cmd_id = data[6];p2frame->data_len = data_len;p2frame->data = (uint8_t*)&data[7]; // 指向原始数据/* CRC校验检查 */uint16_t received_crc = (data[7+data_len] << 8) | data[8+data_len];uint16_t calculated_crc = calculate_crc16(&data[2], 5 + data_len);if (received_crc != calculated_crc) {return PROTOCOL_ERR_CHECKSUM;}return PROTOCOL_OK;
}/* 协议2构建实现 */
static ProtocolStatus build_protocol2(const void* frame, uint8_t* buffer, uint16_t buffer_size) 
{const Protocol2Frame* p2frame = (const Protocol2Frame*)frame;uint16_t required_len = PROTOCOL2_MIN_LEN + p2frame->data_len;if (buffer_size < required_len) {return PROTOCOL_ERR_BUFFER;}/* 填充固定字段 */buffer[0] = PROTOCOL2_HEADER_1;buffer[1] = PROTOCOL2_HEADER_2;buffer[2] = (p2frame->data_len >> 8) & 0xFF;buffer[3] = p2frame->data_len & 0xFF;buffer[4] = p2frame->src_id;buffer[5] = p2frame->dest_id;buffer[6] = p2frame->cmd_id;/* 填充数据 */if (p2frame->data_len > 0) {memcpy(&buffer[7], p2frame->data, p2frame->data_len);}/* 计算CRC */uint16_t crc = calculate_crc16(&buffer[2], 5 + p2frame->data_len);buffer[7+p2frame->data_len] = (crc >> 8) & 0xFF;buffer[8+p2frame->data_len] = crc & 0xFF;return PROTOCOL_OK;
}/* 协议2描述符定义 */
const ProtocolDescriptor protocol2_descriptor = {PROTOCOL_TYPE_2,parse_protocol2,build_protocol2,PROTOCOL2_MIN_LEN,sizeof(Protocol2Frame)
};

四、应用层:业务逻辑实现

应用层处理具体的业务逻辑,主要功能包括:命令处理、数据加工、业务决策、状态管理。

4.1 设计要点

  1. 表驱动编程:使用命令表简化路由逻辑
  2. 业务隔离:协议处理与业务逻辑分离
  3. 模块化设计:各命令处理函数独立
  4. 默认处理:提供未识别命令的默认处理
  5. 可测试性:独立于协议栈进行单元测试

4.2 代码示例

4.2.1 协议一处理

/* 命令处理函数类型 */
typedef void (*Protocol1CmdHandler)(const Protocol1Frame* frame);/* 命令集条目 */
typedef struct {uint8_t cmd_set;           // 命令集IDuint8_t cmd_id;            // 命令IDProtocol1CmdHandler handler; // 处理函数
} Protocol1CmdEntry;/**************** 命令处理表 ****************/
static const Protocol1CmdEntry protocol1_cmd_table[] = {// 系统命令集 (0x01){0x01, 0x01, handle_system_cmd_01},{0x01, 0x02, handle_system_cmd_02},// 数据采集命令集 (0x02){0x02, 0x10, handle_acq_cmd_10},{0x02, 0x20, handle_acq_cmd_20},
};/* 默认处理函数 */
static void default_protocol1_handler(const Protocol1Frame* frame) {DEBUG_MSG("Unhandled Protocol1 command: set=0x%02X, cmd=0x%02X", frame->cmd_set, frame->cmd_id);
}/* 协议1数据处理入口 */
void handle_protocol1_data(const Protocol1Frame* frame)
{const Protocol1CmdEntry* entry = NULL;size_t table_size = sizeof(protocol1_cmd_table) / sizeof(Protocol1CmdEntry);/* 查找匹配的命令处理函数 */for (size_t i = 0; i < table_size; i++) {if (protocol1_cmd_table[i].cmd_set == frame->cmd_set && protocol1_cmd_table[i].cmd_id == frame->cmd_id) {entry = &protocol1_cmd_table[i];break;}}/* 调用处理函数 */if (entry) {entry->handler(frame);} else {default_protocol1_handler(frame);}
}/**************** 具体命令处理实现 ****************/
static void handle_system_cmd_01(const Protocol1Frame* frame) {DEBUG_MSG("Processing System Command 01 from 0x%04X", frame->src_id);/* 实际业务处理... */
}static void handle_system_cmd_02(const Protocol1Frame* frame) {DEBUG_MSG("Processing System Command 02 with %d bytes data", frame->data_len);/* 实际业务处理... */
}static void handle_acq_cmd_10(const Protocol1Frame* frame) {DEBUG_MSG("Processing Acquisition Command 10");/* 实际业务处理... */
}static void handle_acq_cmd_20(const Protocol1Frame* frame) {DEBUG_MSG("Processing Acquisition Command 20");/* 实际业务处理... */
}

4.2.2 协议二处理

/* 命令处理函数类型 */
typedef void (*Protocol2CmdHandler)(const Protocol2Frame* frame);/* 命令集条目 */
typedef struct {uint8_t cmd_id;            // 命令IDProtocol2CmdHandler handler; // 处理函数
} Protocol2CmdEntry;/**************** 命令处理表 ****************/
static const Protocol2CmdEntry protocol2_cmd_table[] = {{0x10, handle_status_query},{0x20, handle_parameter_set},{0x30, handle_other_command},
};/* 默认处理函数 */
static void default_protocol2_handler(const Protocol2Frame* frame) {DEBUG_MSG("Unhandled Protocol2 command: 0x%02X", frame->cmd_id);
}/* 协议2数据处理入口 */
void handle_protocol2_data(const Protocol2Frame* frame)
{const Protocol2CmdEntry* entry = NULL;size_t table_size = sizeof(protocol2_cmd_table) / sizeof(Protocol2CmdEntry);/* 查找匹配的命令处理函数 */for (size_t i = 0; i < table_size; i++) {if (protocol2_cmd_table[i].cmd_id == frame->cmd_id) {entry = &protocol2_cmd_table[i];break;}}/* 调用处理函数 */if (entry) {entry->handler(frame);} else {default_protocol2_handler(frame);}
}/**************** 具体命令处理实现 ****************/
static void handle_status_query(const Protocol2Frame* frame) {DEBUG_MSG("Status query from device %d", frame->src_id);/* 构造响应数据并发送... */
}static void handle_parameter_set(const Protocol2Frame* frame) {DEBUG_MSG("Parameter set from device %d", frame->src_id);/* 参数处理逻辑... */
}static void handle_other_command(const Protocol2Frame* frame) {DEBUG_MSG("Processing command 0x%02X", frame->cmd_id);/* 其他命令处理... */
}

五、四层协作流程

5.1 收发流程

接收流程:

  • 硬件抽象层接收原始数据存入环形缓冲区

  • 协议管理层从缓冲区取出数据并识别协议类型

  • 协议处理层解析数据为结构化信息

  • 应用层处理具体业务逻辑

发送流程:

  • 应用层准备业务数据

  • 协议处理层打包为协议帧

  • 协议管理层选择适当发送接口

  • 硬件抽象层将数据发送至物理介质

在这里插入图片描述

5.2 代码示例

/* 系统初始化 */
void system_init(void)
{// 1. 硬件抽象层初始化custom_can_init();// 2. 应用层初始化app_init();
}/* 主任务循环 */
void main_task(void)
{uint8_t raw_data[256];while(1) {// 1. 从硬件层读取数据uint16_t len = custom_can_read(raw_data, sizeof(raw_data));if(len > 0) {// 2. 协议管理层处理custom_can_run_unpack(raw_data, len);}// 3. 应用层处理app_process();// 4. 休眠或等待事件delay_ms(10);}
}/* 应用层发送示例 */
void send_heartbeat(void)
{uint8_t hb_data[4] = {0x01, 0x02, 0x03, 0x04};// 使用协议1发送心跳ProtocolStatus status = send_protocol1(LOCAL_DEVICE_ID, MASTER_DEVICE_ID,CMD_SET_SYSTEM,CMD_HEARTBEAT,hb_data,sizeof(hb_data));if(status != PROTOCOL_OK) {handle_send_error(status);}
}

总结

这个四层通信协议架构具有以下优势:

  1. 清晰的层次划分:各层职责明确,便于维护

  2. 高度可扩展:轻松添加新协议和新命令

  3. 强类型安全:减少运行时错误

  4. 高效处理:优化数据流转路径

  5. 平台无关:硬件抽象层隔离硬件差异

实际项目中可根据需求调整各层实现,如增加加密层、优化缓冲区管理等。

http://www.lqws.cn/news/478297.html

相关文章:

  • 【云原生】Docker 部署 Elasticsearch 9 操作详解
  • 华为OD-2024年E卷-字符串化繁为简[200分] -- python
  • 「Linux文件及目录管理」vi、vim编辑器
  • Ragflow 源码:task_executor.py
  • Sqlserver 设置对特定数据库特定表只读访问权限
  • 1928: 日期差值 codeup
  • MySQL安装与配置【windowsMac】
  • Unity3D仿星露谷物语开发69之动作声音
  • Unity Addressable使用之服务器远程加载
  • leetcode:面试题 08.01. 三步问题
  • AWS认证系列:考点解析 - cloud trail,cloud watch,aws config
  • JavaEE-Mybatis初阶
  • ubuntu24.04+5090显卡驱动安装踩坑
  • C4.5算法深度解析:决策树进化的里程碑
  • 低空经济三大赛道深度解析:交通、安防、能源领域的革命性突破
  • 华为公布《鸿蒙编程语言白皮书》V1.0 版:解读适用场景
  • es中向量索引的增量更新
  • Linux:早期操作系统的系统调用
  • 【论文阅读笔记】TransparentGS:当高斯溅射学会“看穿”玻璃,如何攻克透明物体重建难题?
  • Day56打卡 @浙大疏锦行
  • 【threejs】一天一个小案例讲解:控制面板(GUI)
  • 扩散模型与强化学习(1):字节Seedance中的人类偏好优化实践
  • 华为云Flexus+DeepSeek征文|基于Dify构建解析网页写入Notion笔记工作流
  • sqlite3 数据库反弹shell
  • 开发语言本身只是提供了一种解决问题的工具
  • 【AI智能体】Spring AI MCP 服务常用开发模式实战详解
  • TDengine 3.3.5.0 新功能——服务端查询内存管控
  • PaddleOCR + Flask 构建 Web OCR 服务实战
  • Flink Sink函数深度解析:从原理到实践的全流程探索
  • 63-Oracle LogMiner(23ai)-实操