LoRa OTA 网关升级系统开发笔记(三)
系列文章目录第一篇LoRa通信基础第二篇协议层设计与CRC校验第三篇可靠传输机制ACK/超时/重传第四篇W25Q128固件管理第五篇完整的固件发送一、为什么需要可靠传输LoRa 是无线通信容易受到干扰、信号衰减等影响导致数据丢失。为了确保固件升级的可靠性需要实现ACK 确认发送方收到接收方的确认才知道数据已到达超时重传发送方等待 ACK 超时后重新发送数据SEQ 序号每个数据包有唯一序号用于识别和去重二、SEQ 序号机制2.1 序号的作用识别数据包每个数据包有唯一序号确认接收ACK 携带序号告诉发送方哪个包被接收三、优化函数3.1 优化命令与通信协议构成在命令上我们添加了发送ACK的宏定义在发送的通信协议上我们添加了数据包序列号3.2优化发送函数四、ACK 确认机制4.1 ACK 帧结构此处开始编写应用层函数添加High_App_OTA.c 与 High_App_OTA.h文件在High_App_OTA.h中添加结构体//ACK结构体 typedef struct { uint8_t node_id; //应答的ACK节点ID uint16_t ack_seq; //数据包 uint8_t ack_flag; //应答标志位 }ACK_Frame_t;4.2 发送 ACK在High_App_OTA.c文件中创建发送ACK函数在此函数中调用llcc68的发送函数把ACK有关的参数发送出去/** * 发送ACK * id * seq * 0成功 | 1失败 */ uint8_t Int_llcc68_lora_send_ack(uint8_t id, uint16_t seq) { ACK_Frame_t g_ack_frame; g_ack_frame.node_id id; g_ack_frame.ack_seq seq; g_ack_frame.ack_flag 1; uint8_t res Int_llcc68_lora_send(HEAD, id, CMD_SEND_ACK, seq, (uint8_t *)g_ack_frame, sizeof(ACK_Frame_t)); if(res ! 0) { return 1; } else return 0; }在接收到节点数据时如果校验全部通过则发送ACK给节点表示收到消息且消息无误/** * 处理节点上报的数据 */ void Int_Process_Node_Data(uint8_t node_id,uint16_t seq, uint8_t *data, uint16_t len) { switch (node_id) { case NODE_ID_01: //i to do: Int_llcc68_lora_send_ack(NODE_ID_01,seq); break; default: break; }4.3 接收与处理ACK4.3.1 优化接收解析函数Frame_t g_ota_frame; 声明全局变量把这个接收解析函数移到应用层函数代码文件去并在原有的接收函数前添加case语句如果发送的命令是发送ACK的话则进入ACK应答处理函数4.3.2 处理ACK应答函数参数是ACK_Frame_t 的函数指针在接收到数据后进入case语句如果命令是发送ACK则进入此函数记录ACK应答的ID、数据包序列号并把标志位置1后续有对ID进行细分操作的函数。ACK_Frame_t ack_frame; //声明全局变量 /** * AKC应答处理函数 * frame指针 */ static uint8_t High_OTA_Rece_ACK_Handler(Frame_t *frame) { ack_frame.node_id frame-id; //获取ACK应答的ID ack_frame.ack_seq frame-seq; //获取当前信息的seq值 ack_frame.ack_flag 1; //标志位置1表示应答 return 0; }五、超时重传机制3.1 等待 ACK带超时在发送消息后我们都需要等待ACK以确保我们的消息确认无误发送给了对方在规定时间上要是发完消息没收到该节点发送的ACK则超时进行有限次数的重传#define OTA_ACK_TIMEOUT 3000 // 超时时间 3 秒 /** * brief 等待ACK应答 * param id 期待ACK应答的节点ID * param seq 期望的序列号 * return 0成功, 1超时 */ uint8_t High_App_OTA_Wait_Ack(uint8_t node_id,uint16_t seq) { uint32_t start_tick 0; start_tick HAL_GetTick(); //获取当前系统的时间 while (1) { if (ack_frame.ack_flag 1 ack_frame.node_id node_id) // 是否应答 与 ID是否匹配 { if (ack_frame.ack_seq seq) // 判断应答序列号是否对的上 { ack_frame.ack_flag 0; // 清零标志位 ack_frame.node_id 0; // 清空应答ID return 0; } else { printf(seq error\r\n); ack_frame.ack_flag 0; // 清零标志位 ack_frame.node_id 0; // 清空应答ID return 1; } } if (HAL_GetTick() - start_tick OTA_ACK_TIMEOUT) // 判断是否超时 { printf(ack timeout\r\n); return 1; } } }3.2 带重传的发送#define OTA_MAX_RETRY 3 // 最大重试次数 /** * brief 发送数据并等待ACK带重传 * param node_id 目标节点ID * param seq 序列号 * param data 数据 * param len 数据长度 * return 0成功, 1失败 */ uint8_t High_OTA_Send_With_Retry(uint8_t node_id, uint16_t seq,uint8_t *data, uint16_t len) { uint8_t retry 0; while (retry OTA_MAX_RETPY) { // 1. 发送数据 Int_llcc68_lora_send(HEAD, node_id, CMD_SEND_DATA,seq, data, len); printf(Send seq%d, retry%d/%d\r\n, seq, retry 1, OTA_MAX_RETRY); // 2. 等待ACK if (High_App_OTA_Wait_Ack(node_id,seq) 0) { printf(ACK received! seq%d\r\n, seq); return 0; // 成功 } // 3. 超时重试 retry; printf(Timeout, retry %d/%d\r\n, retry, OTA_MAX_RETRY); HAL_Delay(100); } printf(retpy max !\r\n); return 1; // 失败 }六、测试main中导入头文件6.1 测试网关发送数据给节点并等待ACK应答F429网关代码初始化llcc68并调用发送数据并等待ACK在主循环中调用接收函数F103节点代码F103负责接收网关发送的数据在接收到数据且解析无误时发送ACK给网关。6.1.1 结果节点端F103节点端接收到网关发送的消息且接收无误发送ACK给网关网关端发送id为1seq为1成功发送且收到ACK回应6.2 节点发送数据给网关 与 超时功能测试F103节点端进行初始化并给网关发送消息1,2,3,4,5 seq为1F429网关端在main函数中进行初始化且在循环中调用接收函数并且为了测试超时函数是否能准确运行把接收到信息且无误发送ACK给注释了也就是不发送ACK给节点6.2.1 结果节点端发送消息给网关 id为1seq为1尝试发送了三次最后超时退出七、总结本篇实现了完整的可靠传输机制功能状态ACK确认✅ 已实现超时重传✅ 已实现SEQ序号✅ 已实现下一篇预告实现 W25Q128 固件管理包括元数据存储、串口接收、PC通信协议。

相关新闻

休闲小游戏圈小猫离线可玩打发时间

休闲小游戏圈小猫离线可玩打发时间

软件介绍 第二款是圈小猫,一款来自吾爱破解论坛的小游戏。刚开始看的时候觉得难度很大,但真正上手玩起来发现其实还好,没有想象中那么难。 单机离线随时玩 游戏是单机离线版本,不需要联网,随时随地都能玩。通勤路上…

2026/10/2 6:18:35 阅读更多 →
经典黑白棋单机游戏离线可玩无需联网

经典黑白棋单机游戏离线可玩无需联网

软件介绍 今天第一款是黑白棋,别被名字误导,这不是五子棋,也不是围棋,而是一款经典的策略棋类游戏。棋盘是88的方格,棋子下在格子里而不是交叉点上,玩法和规则都很独特。 棋盘和下棋方式 黑白棋的棋盘是…

2026/10/4 17:21:45 阅读更多 →
数据结构入门系列——时间复杂度与空间复杂度详解

数据结构入门系列——时间复杂度与空间复杂度详解

「 每日一句 Daily Quote 」 学而不思则罔,思而不学则殆。” — 《论语为政》 文章目录前言一、算法效率1.1 复杂度的概念二、时间复杂度1.概念介绍2. 大O的渐进表示法3. 时间复杂度计算示例3.1 示例13.2 示例23.3 示例33.4 示例43.5 示例53.6 示例63.7 示例7三、…

2026/10/4 0:00:25 阅读更多 →

最新新闻

一键接入大模型:One-Api本地安装配置实操(TaoToken统一Key接入版)

一键接入大模型:One-Api本地安装配置实操(TaoToken统一Key接入版)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:34:25 阅读更多 →
从插件市场到MCP:TaoToken 统一 Key 打通开发者插件生态的实践大纲

从插件市场到MCP:TaoToken 统一 Key 打通开发者插件生态的实践大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:34:25 阅读更多 →
本地策略与注册表协同配置技巧

本地策略与注册表协同配置技巧

###本地策略与注册表协调配置 在Windows系统中,本地安全策略和注册表是实现系统安全控制的重要工具。它们之间存在紧密的关联,通过合理配置可以提升系统的安全性。 1. 本地安全策略与注册表的关系 项目描述引用本地安全策略用于定义系统级别的安全设置…

2026/10/7 14:34:25 阅读更多 →
为什么 Codex 写 HTML 页面总跑偏?聊聊 GPT-5.5 在 Agent 场景下的意图理解体验与 TaoToken 接入

为什么 Codex 写 HTML 页面总跑偏?聊聊 GPT-5.5 在 Agent 场景下的意图理解体验与 TaoToken 接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:34:25 阅读更多 →
Android Ext4文件系统排查:从权限报错到分区修复的完整指南

Android Ext4文件系统排查:从权限报错到分区修复的完整指南

我最近帮一位朋友处理一台 Android 平板,症状特别典型:某个 App 打开后疯狂闪退,系统设置里显示存储空间还剩下十几 GB,可应用就是提示“磁盘空间不足,无法写入”。插上电脑想从/storage/emulated/0/Android/data/目录…

2026/10/7 14:34:25 阅读更多 →
Modbus转MQTT实战:工程监测中传感器数据上云的技术要点

Modbus转MQTT实战:工程监测中传感器数据上云的技术要点

做工程监测的都知道,传感器装到现场只是第一步,真正的麻烦才开始:水位计是RS485接口,网关平台那边却只认MQTT协议,现场没网线可拉,只能靠4G流量卡回传。当初我第一次接边坡监测项目时,光是想清楚…

2026/10/7 14:33:25 阅读更多 →

日新闻

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:01:58 阅读更多 →
用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:02:00 阅读更多 →
芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:02:00 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:34:12 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:34:13 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 9:29:10 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:34:12 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 11:43:46 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 13:34:55 阅读更多 →