# 协议收发库 **Repository Path**: SiaZhang/protocol-transceiver-driver ## Basic Information - **Project Name**: 协议收发库 - **Description**: 一个用于通信的库,自带协议 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-27 - **Last Updated**: 2026-05-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # protocol-transceiver-driver ## 1. 项目简介 这是一个面向嵌入式/设备通信场景的轻量协议收发库,核心目标是: - 固定帧格式,便于跨端互通 - 无动态内存分配,行为可预测 - 支持 ACK、超时与重传 - 通过轮询入口统一处理收发 库入口为 ProtocolProcess。应用层通常在主循环中周期调用该函数,以驱动接收解析、回调处理和发送状态机。 --- ## 2. 协议帧模型 帧结构采用 1 字节对齐,主要字段如下: - 帧头:1 字节(固定 0x55) - 总长度:2 字节 - 版本:1 字节 - 配置位:1 字节(need_ACK、is_ACK、is_end 等) - 序列号:2 字节 - 指令 ID:2 字节 - 载荷 data:最大 256 字节 - 校验 check:1 字节(CRC8) - 帧尾:1 字节(固定 0xAA) 关键长度常量: - PROTOCOL_DATALEN_MAX = 256 - PROTOCOL_FRAME_MINLEN = 11 - PROTOCOL_FRAME_MAXLEN = 267 --- ## 3. 核心接口 - ProtocolInit - 初始化上下文、注入时间函数、接收函数、发送函数、回调表 - ProtocolProcess - 协议驱动入口,内部依次执行 RxProcess 与 TxProcess - ProtocolSendCmd - 提交一条业务命令到发送命令 FIFO - ProtocolRegisterCmdCallback / ProtocolRegisterCmdCallbackTable - 注册业务指令回调 回调函数类型: - Protocol_Receive_t:从底层读取字节流 - Protocol_Send_t:向底层发送字节流 - Protocol_Callback_t:业务帧/ACK 处理 --- ## 4. 从 receive_data 到 send_data 的完整流程 ### 4.1 调度层(入口) 每次调用 ProtocolProcess 都会按固定顺序执行: 1. 接收处理:RxProcess 2. 发送处理:TxProcess 这意味着接收与发送共享同一个轮询节拍,吞吐能力和实时性与 ProtocolProcess 的调用频率直接相关。 ### 4.2 接收路径(4 层) #### 第 1 层:底层拉取(receive_data) - RxReceiveData 每次申请读取最多 267 字节 - 先检查接收字节环形缓存剩余空间 - 当前策略是:剩余空间不足 267 则本轮不读取 #### 第 2 层:接收字节环形缓存 rx_cache - 物理容量:512 字节 - 逻辑有效容量:511 字节(环形队列保留 1 空位区分满/空) - 作用:吸收底层输入的字节流抖动 #### 第 3 层:解析状态机 + 组帧缓存 解析状态机顺序: 1. 等帧头 2. 等长度低字节 3. 等长度高字节 4. 收帧体直到 total_len 完成后执行: - CRC8 校验 - 帧尾校验 - 校验通过后推入接收帧 FIFO 组帧缓存大小:267 字节。 #### 第 4 层:接收帧 FIFO + 回调执行 - FIFO 深度:10 - 逻辑有效帧数:9 - RxExcuteCallback 每轮最多处理 rx_max_frames_per_cycle 帧(0 表示不限制) 处理逻辑: - ACK 帧:尝试匹配当前发送队首命令,设置 ack_received 并触发 ACK 回调 - 业务帧:按 cmd 在回调表中查找并执行 ### 4.3 发送路径(3 层) #### 第 1 层:业务命令 FIFO - ProtocolSendCmd 负责构造 Protocol_Cmd_t 并入队 - FIFO 深度:10 - 逻辑有效命令数:9 #### 第 2 层:发送命令状态机 状态机: 1. IDLE:等待队首命令 2. SEND:将队首命令编码后推入发送帧 FIFO,记录发送时间与次数 3. WAIT_ACK:等待 ACK、判断超时、决定重发或失败回调 #### 第 3 层:发送帧 FIFO -> send_data - 发送帧 FIFO 深度:10,逻辑有效 9 - 每次 TxFrameProcess 仅尝试发送 1 帧 - send_data 成功则出队,失败则保留等待下次重试 --- ## 5. 缓存分层与容量总览 接收侧: 1. rx_cache:512 字节(有效 511) 2. cmd_parse_frame:267 字节(单帧临时组包) 3. cmd_fifo:10 槽位(有效 9 帧) 发送侧: 1. cmd_fifo:10 槽位(有效 9 命令) 2. tx_frame_fifo:10 槽位(有效 9 帧) 说明:发送命令槽位的内存占用与平台指针宽度相关(回调函数指针在不同平台大小不同)。 --- ## 6. 处理效率分析 优点: - 全静态内存,时延和内存上界可控 - 状态机清晰,异常帧快速丢弃 - ACK/重传机制完整 吞吐限制点: 1. 接收门限较硬: - 只有当 rx_cache 空闲 >= 267 才拉取数据,可能降低连续流输入下的吞吐 2. 发送节拍受轮询约束 - 每个 ProtocolProcess 周期最多发送 1 帧 3. 回调处理速率受配置约束 - 每周期最大处理帧数受 rx_max_frames_per_cycle 限制 4. 编码与拷贝次数偏多 - 发送路径存在重复编码与较多内存拷贝 经验上: - 最大发送帧率约等于 ProtocolProcess 调用频率 - 最大接收回调速率约等于 调用频率 × rx_max_frames_per_cycle(当该值非 0) --- ## 7. 使用建议 - 让 ProtocolProcess 在固定周期执行,避免长时间阻塞 - 在高流量场景下评估 rx_max_frames_per_cycle,防止回调处理积压 - 底层 receive_data 与 send_data 应避免长时间阻塞 - 为关键命令设置合理 timeout_ms 与 retry_max(重试次数,不含首次发送) --- ## 8. 当前问题梳理(文末问题清单) ### P1:接收返回长度缺少上限钳制(高优先级) 现状: - receive_data 返回值 bytes_read 未强制限制到 temp_buffer 大小 - 若底层错误返回大于 267,循环写入/读取会越界 建议: - 对 bytes_read 执行最小值钳制:bytes_read = min(bytes_read, PROTOCOL_FRAME_MAXLEN) ### P2:接收读取策略过保守(中优先级) 现状: - 空闲空间不足 267 字节就不读取,容易导致上游积压 建议: - 改为按当前空闲空间请求读取,至少可读一部分 ### P3:send_interval 配置未生效(中优先级) 现状: - 配置结构中有 send_interval,但发送状态机未使用 建议: - 在 TxCmdProcess 中引入发送间隔判定,避免过快发包 ### P4:重复编码/拷贝影响 CPU 效率(中优先级) 现状: - 发送链路存在重复编码与多次 memcpy/memset 建议: - 合并编码时机,减少中间态对象和重复拷贝 ### P5:ACK 匹配范围仅队首(低到中优先级) 现状: - ACK 只与发送命令队列队首匹配 - 当前串行发送模型可工作,但扩展并发在途命令时会受限 建议: - 如需并发在途,建立 seq+cmd 的索引匹配结构 ### P6:测试样例为无限循环,难以得到稳定指标(低优先级) 现状: - 测试主循环无节拍控制,会拉高 CPU 占用 建议: - 增加固定循环次数和统计窗口,输出吞吐/丢帧/重传率 --- ## 9. 后续演进方向 - 增加协议统计信息:收包、丢包、CRC 错、重传次数、超时次数 - 增加可选的零拷贝发送模式 - 增加压力测试与边界测试(高突发、乱序 ACK、回调慢处理) - 增加统一日志钩子,便于线上排障