STM32收发数据包中间件——ProtoFlow,更方便的打包解包助手

引言

在嵌入式开发中,数据包封装是不可或缺的一环。手动编写协议不仅耗时,还容易出错。ProtoFlow 的出现,就是为了让数据包封装变得简单、高效、可靠。它不仅占用资源少,还能适配多种场景,是你项目的理想助手。
项目地址:Github仓库:https://github.com/nanwanuser/ProtoFlow

项目简介

ProtoFlow 是一个专为数据包封装和解析设计的轻量级协议栈,旨在帮助嵌入式开发者快速、高效地处理数据打包需求。无论你的项目使用串口、SPI、I2C,还是 CAN 等通信方式,ProtoFlow 都能提供灵活、可配置的数据包封装功能,让你专注于核心开发,而无需为通信细节操心。

为什么选择 ProtoFlow?

在嵌入式开发中,数据包封装是不可或缺的一环。手动编写协议不仅耗时,还容易出错。ProtoFlow 的出现,就是为了让数据包封装变得简单、高效、可靠。它不仅占用资源少,还能适配多种场景,是你项目的理想助手。

ProtoFlow 的核心亮点

  • 专注于数据包封装:提供灵活的帧结构,支持动态长度数据包(最大 256 字节)。
  • 轻量高效:协议栈占用不到 2KB Flash,适合资源有限的 MCU。
  • 多场景适用:支持串口、SPI、I2C、CAN 等多种通信方式的数据包封装。
  • 可靠传输:可选 CRC16 校验,确保数据完整性。
  • 简单易用:直观的 API 和示例代码,快速集成到 STM32 项目中。

ProtoFlow 项目

特性

  • 轻量级协议栈(<2KB Flash)
  • 支持动态长度数据包(最大 256 字节)
  • 可配置帧头帧尾(默认 0xAA55/0x55AA)
  • 支持 CRC16 校验(可选启用)
  • 状态机驱动解析(9 种解析状态)
  • 全中断驱动设计(零阻塞)
  • 自动重同步机制
  • 多通信方式支持:不仅限于串口,可扩展到 SPI、I2C、CAN 等
  • 适用于多种数据通信场景

快速开始

1. 添加文件到工程

# 复制以下文件到 STM32 工程目录
protoflow.h protoflow.c

2. 协议配置(protoflow.h)

// 帧结构配置
#define FRAME_HEADER      0xAA55      // 2 字节帧头
#define FRAME_END         0x55AA      // 2 字节帧尾
#define MAX_DATA_LENGTH   256         // 最大数据长度
#define USE_CRC16         1           // 启用 CRC16 校验(0-禁用 1-启用)// 硬件抽象声明(用户必须实现)
void user_transmit(uint8_t *data, uint16_t len);  // 通信发送函数(支持多种通信方式)

3. 示例代码集成(以串口为例)

// main.c
#include "protoflow.h"int main(void) {// HAL 初始化MX_USART1_UART_Init();protoflow_init();  // 协议栈初始化while(1) {// 主循环处理}
}// 串口接收中断回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {if(huart->Instance == USART1) {uint8_t data = huart->Instance->DR;parse_byte(data);  // 字节解析}
}

API 说明

数据打包发送

/*** @brief  打包并发送数据* @param  cmd    : 命令字(1 字节)* @param  data   : 有效载荷数据指针* @param  len    : 数据长度(0~MAX_DATA_LENGTH)* @retval 实际发送的数据包长度*/
uint16_t pack_data_transmit(uint8_t cmd, uint8_t *data, uint16_t len);

数据解析

/*** @brief  解析接收字节(将接收到的字节传入,解析后在 user_package_handler 中使用数据包)* @param  byte : 接收到的字节*/
void parse_byte(uint8_t byte);

回调函数(用户实现)

/*** @brief  完整数据包回调* @param  cmd  : 接收到的命令字* @param  data : 数据缓冲区指针* @param  len  : 有效数据长度*/
void user_package_handler(uint8_t cmd, uint8_t *data, uint16_t len);

典型应用场景

数据发送(以串口为例)

// 发送温湿度传感器数据
void send_sensor_data(float temp, float humidity) {uint8_t payload[4];// 转换为 16 位整型(0.1℃ 精度)uint16_t temp_raw = (uint16_t)(temp * 10);uint16_t humi_raw = (uint16_t)(humidity * 10);payload[0] = temp_raw >> 8;payload[1] = temp_raw & 0xFF;payload[2] = humi_raw >> 8;payload[3] = humi_raw & 0xFF;pack_data_transmit(0x01, payload, sizeof(payload));  // 自动发送
}

数据接收处理

// 接收控制指令(示例:PWM 控制)
void user_package_handler(uint8_t cmd, uint8_t *data, uint16_t len) {switch(cmd) {case 0xA1:  // 电机控制if(len == 4) {uint16_t speed = (data[0] << 8) | data[1];uint16_t duration = (data[2] << 8) | data[3];set_motor(speed, duration);}break;case 0xA2:  // LED 亮度调节if(len == 2) {uint16_t brightness = (data[0] << 8) | data[1];set_led_brightness(brightness);}break;}
}

移植指南

必须实现的硬件接口

ProtoFlow 支持多种通信方式,用户需根据具体硬件实现发送函数。例如:

串口:

void user_transmit(uint8_t *data, uint16_t len) {HAL_UART_Transmit(&huart1, data, len, 100);
}

SPI:

void user_transmit(uint8_t *data, uint16_t len) {HAL_SPI_Transmit(&hspi1, data, len, 100);
}

I2C:

void user_transmit(uint8_t *data, uint16_t len) {HAL_I2C_Master_Transmit(&hi2c1, DEVICE_ADDR, data, len, 100);
}

配置步骤

  1. 在 protoflow.h 中配置协议参数(帧头、帧尾、最大数据长度、CRC16 等)
  2. 根据通信方式实现 user_transmit 发送函数
  3. 实现 user_package_handler 数据回调函数
  4. 在通信接收中断中调用 parse_byte()(如串口接收中断)
  5. 调用 protoflow_init() 初始化协议栈

注意事项

  • 帧结构:Header(2) + Length(2) + Cmd(1) + Data(n) + CRC16(2) + End(2)
  • 数据长度字段:包含命令字(1 字节)+ 数据长度
  • CRC16:启用时数据包增加 2 字节校验码
  • DMA 建议:使用 DMA 传输时,保持缓冲区有效直到发送完成

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/898798.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Xcode16.1使用MonkeyDev运行Tiktok报错分析

问题1&#xff1a; Build input files cannot be found: /usr/lib/libc.dylib, /usr/lib/libstdc.dylib. Did you forget to declare these files as outputs of any script phases or custom build rules which produce them? 解决办法&#xff1a;在TARGETS的dylib中的Bui…

R语言交互项-formula

R语言交互项-formula 交互项的模型交互项的几种情形连续变量和连续变量连续变量和分类变量分类变量和分类变量总结交互项的模型 统计中的交互和相关是完全不同的两个概念,交互项是指两个或者多个变量对因变量的协同效应,关注变量对因变量的联合影响,比如变量X对Y的影响是否因…

图解AUTOSAR_SWS_IPDUMultiplexer

AUTOSAR IPDUMultiplexer模块详解 PDU复用器模块架构与实现分析 目录 1. IPDU Multiplexer概述2. 模块配置模型 2.1 配置结构概述2.2 配置类详解2.3 配置关系说明3. 架构设计 3.1 模块位置与接口3.2 内部组件结构3.3 接口交互模式4. 操作序列 4.1 PDU传输流程4.2 PDU传输流程详…

手机怎么换网络IP有什么用?操作指南与场景应用‌

在数字化时代&#xff0c;手机已经成为我们日常生活中不可或缺的一部分&#xff0c;无论是工作、学习还是娱乐&#xff0c;手机都扮演着至关重要的角色。而在手机的使用过程中&#xff0c;网络IP地址作为设备在互联网上的唯一标识符&#xff0c;其重要性和作用不容忽视。本文将…

CH32V208GBU6沁恒协议栈BUG:在主机Write的同一包notify会造成主机一直Write不成功

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…

unsloth微调QwQ32B(4bit)

unsloth微调QwQ32B(4bit) GPU: 3090 24G unsloth安装部署 pip 安装 pip install unsloth --index https://pypi.mirrors.usrc.edu.cn/simplesource /etc/network_turbopip install --force-reinstall --no-cache-dir --no-deps githttps://github.com/unslothai/unsloth.git​…

JavaScript案例0322

以下是一些涵盖不同高级JavaScript概念和应用的案例&#xff0c;每个案例都有详细解释&#xff1a; 案例1&#xff1a;实现 Promise/A 规范的手写 Promise class MyPromise {constructor(executor) {this.state pending;this.value undefined;this.reason undefined;this.o…

Dify 0.15.3 输入变量无法被重新赋值问题-解决方法

目录 一、问题描述 二、解决方法 2.1 原因 2.2 修改源码 2.3 重新打包 dify-api 镜像 2.4 修改 docker-compose.yaml 文件 2.5 重启启动镜像 一、问题描述 Dify 0.15.3 是一个比较稳定的版本&#xff0c;Dify 1.0 是一个大版本更新&#xff0c;目前还有很多 Bug。但是&a…

SQL Server查询计划操作符(7.3)——查询计划相关操作符(11)

7.3. 查询计划相关操作符 98&#xff09;Table Scan&#xff1a;该操作符从查询计划参数列确定的表中获取所有数据行。如果其参数列中出现WHERE:()谓词&#xff0c;则只返回满足该谓词的数据行。该操作符为逻辑操作符和物理操作符。该操作符具体如图7.3-98节点1所示。 图 7.3-…

数据库练习2

目录 1.向heros表中新增一列信息&#xff0c;添加一些约束&#xff0c;并尝试查询一些信息 2.课堂代码练习 插入语句 INSERT INTO 删除语句DELETE和TRUNCATE 更新语句UPDATE和replace 查询语句SELECT 条件查询 select语句中的特殊情况 ​​​查询排序 order by 分组查询…

Java架构师成长之路

概述 本教程主要从6个方面&#xff0c;全面讲解Java技术栈的知识。 1.性能调优 深入理解MySQL底层原理、索引逻辑&#xff0c;数据结构与算法。使用Explain进行优化分析MVCC原理剖析日志机制解析 2.框架源码 掌握Spring底层原理带你手写一个Spring解析IOC、AOP源码、以及事…

资金管理策略思路

详细描述了完整交易策略的实现细节&#xff0c;主要包括输入参数、变量定义、趋势判断、入场与出场条件、止损与止盈设置等多个方面。 输入参数&#xff08;Input&#xff09;&#xff1a; EntryFrL (.6)&#xff1a;多头入场的前一日波动范围的倍数。 EntryFrS (.3)&#xff1…

k8s--集群内的pod调用集群外的服务

关于如何让同一个局域网内的Kubernetes服务的Pod访问同一局域网中的电脑上的服务。 可能的解决方案包括使用ClusterIP、NodePort、Headless Service、HostNetwork、ExternalIPs&#xff0c;或者直接使用Pod网络。每种方法都有不同的适用场景&#xff0c;需要逐一分析。 例如&…

数据模型,数据建模,组件,核心价值,使用,意义

数据模型 一组由符号,文本组成的集合, 用以准确表达信息景观, 达到有效交流,沟通的目的 数据建模 是发现,分析和确定数据需求的过程,是一种称为数据模型的精确形式表示和传递这些需求 数据模型的组件 实体, 关系, 属性和域 数据模型的核心价值 交流性 精确性 数据模型的…

【QA】外观模式在Qt中有哪些应用?

1. QWidget及其布局管理系统 外观模式体现 QWidget 是Qt中所有用户界面对象的基类&#xff0c;而布局管理系统&#xff08;如 QVBoxLayout、QHBoxLayout、QGridLayout 等&#xff09;就像是一个外观类。客户端代码&#xff08;开发者编写的界面代码&#xff09;通常不需要直接…

解锁云原生后端开发新姿势:腾讯云大模型API实战攻略

目录 云原生后端与大模型融合的开篇之章​ 探秘云原生后端开发​ 云原生后端是什么​ 云原生后端架构核心要素​ 微服务架构​ 容器化技术​ 服务发现与配置管理​ Kubernetes 编排​ 走进腾讯云大模型知识引擎​ 引擎独特功能与优势​ DeepSeek - R1、V3 两款模型 …

AWS NoSQL解决方案全景图

&#xff08;技术架构对比表&#xff09; 服务名称数据模型协议兼容性核心架构特性适用场景DynamoDB键值/文档原生API分布式SSD、自动分片高并发事务处理DocumentDB文档型MongoDB 4.0存储计算分离、6副本日志体系JSON数据聚合分析MemoryDB键值流数据Redis 6.2多AZ持久化、微秒…

【拒绝算法PUA】LeetCode 2116. 判断一个括号字符串是否有效

目录 系列文章目录 专题总结&#xff1a; C刷题技巧总结&#xff1a; 题目 2116. 判断一个括号字符串是否有效 难度 描述 解题方法1 系列文章目录 专题总结&#xff1a; 【拒绝算法PUA】0x00-位运算【拒绝算法PUA】0x01- 区间比较技巧【拒绝算法PUA】0x02- 区间合并技…

常见中间件漏洞攻略-Tomcat篇

一、 CVE-2017-12615-Tomcat put方法任意文件写入漏洞 第一步&#xff1a;开启靶场 第二步&#xff1a;在首页抓取数据包&#xff0c;并发送到重放器 第三步&#xff1a;先上传尝试一个1.txt进行测试 第四步&#xff1a;上传后门程序 第五步&#xff1a;使用哥斯拉连接 二、后…

《精益创业》第十三章《尾声:杜绝浪费》总结

核心思想&#xff1a; “杜绝浪费”是精益创业的终极目标与核心理念&#xff0c;其本质是通过系统性识别并消除一切不创造用户价值的活动&#xff0c;将有限资源聚焦于真正驱动增长的“价值流”。浪费不仅指物质损耗&#xff0c;更包括时间、人力与机会成本的隐性流失。 一、精…