一种使用LoRa通信的OTA差分升级方法(学习)

news/2024/3/29 14:43:51/文章来源:https://blog.csdn.net/Caramel_biscuit/article/details/131540361

一种使用LoRa通信的OTA差分升级方式

LoRa(Long Range Radio)是一种远距离无线电,因采用线性调频扩频技术,具有长距离和低功耗的特点,工作于非授权频段,被广泛部署与智能表计、智慧农业、智能物流等多个物联网垂直行业,前景广阔。

然而,由于LoRa通信通常采用星型组网,且目前较多应用使用LoRa“点对点”通信模式,在大面积工程应用时存在频点冲突和固件升级困难的问题。

现有的全量升级方案常用于初始化设备和恢复出厂设置时的批量升级,固件体积庞大,升级耗时,不适用于低速率的LoRa通信场景。

增量升级,又称差分升级,通过使用新旧版本的差异文件对旧固件做还原操作,差分固件体积小,适用于应用升级(In Application Programming, IAP)和空中固件升级(Over the Air)

本文提出了一种用于LoRa通信的OTA差分升级方法,使用开源差分算法Bsdiff和压缩算法FastLz77对新旧固件做差异提取并压缩,以减小固件体积。

为保证固件传输的可靠性,固件数据包使用LoRa跳频和循环异或加密技术传输。

本文详细介绍了OTA系统构成、固件包制作和传输过程,最后搭建了OTA测试环境以验证升级方案的可靠性。

OTA升级原理和系统组成

由于LoRa通信的速率不高,以最高速率(扩频因子SF=7、编码率CR=4/5、带宽BW=500kHz时)传输255字节的理论时间为135ms。因此,OTA升级方案应选择差分固件升级,通过对待升级的固件做差分,减小固件体积。

差分升级主要包括差分包制作、差分包传输、差分包还原三部分。首先将新固件与旧固件做差分,得到补丁文件;之后将补丁文件通过LoRa通信下发至待升级的终端设备;最后终端设备根据补丁文件和已有旧固件执行还原操作得到新固件。将新固件写入FLASH,设置终端程序跳转到新固件的位置并执行,实现空中升级。

系统由LoRa主、从节点构成。

  • LoRa服务器为Master节点,由PC上位机和USB转LoRa设备构成;
  • LoRa待升级终端为Slave节点,每个Slave节点有唯一的ID号,服务器已知各Slave节点ID号。
  • 待升级的新固件定义为New,旧固件定义为Old,补丁文件定义为Patch。

此外,需按功能划分Slave节点固件和升级参数的存储区域,在应用程序执行过程中,将OTA接收的固件包存入相应区域。

FLASH分区为BootLoader_Flash、APPA_Flash、APPB_Flash、Patch_Flash、Update_Flash、Other_Flash。

  • BootLoader_Flash用于启动固件存放空间,负责patch文件的还原,新固件启动引导。
  • APPA_Flash、APPB_Flash和Patch_Flash分别用于存放新固件、旧固件和补丁固件。
  • Updata_Flash:用于存放升级固件信息
  • Other_Flash是其它信息的预留空间

构建patch补丁固件

Slave节点的FLASH存储器一般按照完整扇区进行擦除后写入,升级固件需要按扇区大小分包写入。

因此,patch补丁固件按FLASH扇区大小进行分块做差分,每个FLASH块的差分结果增加相应块序号信息和校验信息,组成patch固件子包patch_pkg_i。

最后将新固件信息和patch固件子包信息合并成完整的patch补丁固件。
Patch补丁固件包具体生成步骤如下:

  1. 固件分块。将新固件和旧固件按Slave节点的FLASH扇区大小(FLASH_Page_size=1024B,2048B等),分成若干个固件子块。
    New = {New_pkg_1,…,New_pkg_n}
    Old= {Old_pkg_1,…,Old_pkg_n}
  2. 子块差分。对比具有相同块号的新、旧固件子块(New_pkg_i,Old_pkg_i)内容的一致性,若两子块内容相同,则不对新固件子块创建补丁内容,否则使用开源差分算法Bsdiff计算两子块内容的差分结果bsdiff_out_i,若新的固件子块数大于旧固件子块数(n>m),则多出的新固件子块数不计算差分,直接将新固件子块内容作为差分结果。
  3. 差分块压缩。由于差分结果具有高度稀疏特性,采用压缩算法可进一步减小固件的数据量。调用fasLz77算法对新固件子块差分结果bsdiff_out_i进行压缩,得到新固件第i个子块的补丁bsdiff_fastLz77_out_i。
  4. 合并子块补丁。将新固件信息和压缩后的固件子块补丁组合,创建patch固件。patch固件由头信息块patch_header和各子信息块patch_pkg_i依次排列构成,其中头信息patch_header包括总差分包数patch_pkg_total、新固件的文件大小newFile_size、新固件的md5信息摘要newFile_md5;子信息块patch_pkg_i由当前子块序号i、子块差分压缩包大小size_t、子块差分压缩包bsdiff_fastLz77_out_i、子块差分压缩包的CRC8校验值组成。

LoRa固件传输

由于LoRa传输容量有限,单次无法发送全部patch补丁固件,需要拆分patch补丁固件进行多次传输。

Master节点将Patch补丁固件按照单次最大传输字节长度(Max_Send_Size)可分为若干(nSend)包,send_pkg_1,send_pkg2,…,send_pkg_n。

Master与Slave每次交互发送一个OTA数据包OTA_pkg_i,OTA数据包由OTA_header、OTA_Size、send_pkg_i和summ32校验值构成,发送至Slave节点,采用报文内容加密和跳频方式传输。

报文加密

采用指定秘钥循环异或的方式对报文加密。首先计算Slave节点ID值的128位信息摘要MD5,将明文报文与计算的MD5值依次按字节遍历做异或处理,生成加密报文。

由于采用异或加密,因此解密与加密的过程相同。
其中,Master对报文加密,Slave对报文解密,加解密方式描述如下:

假设原始报文的明文字节数组A=[a1,a2,…,an],密文字节数组为B=[b1,b2,…,bn],共计n字节;Slave节点的ID为ID=[id1,id2,…,idm]共计m字节。

  1. 计算MD5。计算Slave节点ID的128位MD5信息摘要值,MD5(ID)=[md5_1,md5_2,…,md5_16]
  2. 循环异或加密。将明文与计算的MD5值依次按字节遍历做异或加l解密处理:b1=a1 ⊕ md5_1 ;b2=a2 ⊕ md5_2 ;…;b16=a16 ⊕ md5_16 ;b17=a17 ⊕ md5_1 ;b18=a18 ⊕ md5_2 ;… ;bn=an ⊕ md5_x。完成加解密。

跳频传输

补丁固件使用LoRa传输时会极大占用当前通信信道,严重干扰其它使用当前信道的设备正常工作。因此,在传输补丁固件包时使用跳频传输方式,在多个业务信道随机传输,避免信道拥堵。跳频传输步骤如下:

  1. 划分信道。将LoRa信道频率按照0.2MHz划分为若干通信信道CH=[ch_1,…,ch_x,ch_x+1,…,ch_y,…,ch_n]
  2. Master节点设置信道信息。Master节点发送(ch_x)的报文中带有Slave响应节点的跳频信息ch_y,Master节点发送结束后对应的Slave响应频点(ch_y)接收Slave回复报文,如果Slave节点为及时响应,则Master节点使用上次的频点(ch_x)重发报文信息,并切换至Slave响应频点(ch_y)等待响应,再次超市响应则结束当前数据传输。
  3. 频点选择。跳频频点ch_y由Master节点随机在所有备选信道中选取。

传输流程

Master固件传输
Master节点首先初始化为默认信道(ch_1),在默认信道发送报文读取指定ID的Slave节点运行状态。

固件传输之前先在默认信道下发OTA升级信息,同时设置Slave节点应答频点ch_x并切换Master的接收频点ch_x,等待终端应答。若终端正常应答,Master发送第u个OTA数据包,并指定终端应答频点ch_y,切换Master的接收频点为ch_y,等待终端应答,重复该过程直到patch固件发送完成。

Slave固件接收
Slave节点处于空闲状态时,切换LoRa通信模式为接收模式,并设定接受信道为默认信道(ch_1)。接收到报文信息后,立即进行解密处理,如果解密后的报文满足patch补丁固件传输流程,则根据报文进行回复。

Slave节点固件更新

Slave节点接收完OTA升级包后,将执行固件更新操作,还原固件并检查固件的一致性。

运行BootLoader引导程序,读取Patch_Flash区域的patch补丁固件信息,提取patch_header和patch子信息块patch_pkg_i;从patch子信息块patch_pkg_i提取子块差分压缩包bsdiff_fastLz77_out_i和子块差分压缩包的CRC8校验值。

使用fastLz77解压算法对子块差分压缩包bsdiff_fastLz77_out_i解压,计算解压后数据包的CRC8校验值,如果计算的校验值与子信息块patch_pk_i的校验值相同,则使用bspatch还原算法和APPB_Flash存储区第i个删去的固件信息还原新固件子包,并将其写入APPA_Flash存储区第i个扇区,重复直到还原所有子信息块。

一致性校验根据OTA升级信息,从APPA_Flash存储区读取指定长度为新固件newFile_size字节数的数据,计算MD5值。

如果计算的MD5值与新固件的MD5信息摘要newFile_md5相同,则OTA升级成功,将APPA_Flash存储区的新固件拷贝至APPB_Flash存储区;否则OTA升级失败。将APPB_Flash存储区的旧固件拷贝至APPA_Flash存储区,清楚Patch_Flash存储区和相关OTA升级信息、

OTA升级测试

为验证基于LoRa通信的OTA升级的可靠性,搭建包括1个Master节点和10个Slave节点的测试环境。

  • Master节点由PC端电脑软件和LoRa透传模组组成
  • PC端电脑软件完成对Slave节点的OTA升级流程和协议控制,此外还制作patch文件
  • LoRa透传模组接口为USB转LoRa,负责将PC端电脑软件发出到USB口的数据转换成LoRa通信无线方式发送。

同步Master节点和Slave节点的LoRa跳频信道划分,配置默认信道为ch_1:472.5MHz,从472.7~465.1MHz,间隔0.2MHz,共计62个跳频信道。其余LoRa通信参数设置为带宽500kHz,编码率4/5、扩频因子12.为模拟信道冲突,10个SLAVE节点都在ch_1信道每隔10s随机发送业务数据。

Master节点选择测试用新固件new.bin,大小为31.2KB;旧固件old.bin,大小为33KB;依次执行固件分包、子包差分、子包压缩、patch文件拼包操作,生成patch补丁固件源文件。其中,固件按照扇区1KB进行分包,patch补丁固件源文件大小为2.3KB。

OTA传输的有效patch数据包设置为255字节,Master节点将patch补丁固件按照255字节分成10个数据包,每个数据包增加头文件信息OTA_header、整包数据量OTA_Size和sum32校验值,构成OTA数据包。

Master节点发送报文由Slave节点1的ID计算MD5值循环异或加密;默认信道472.5MHz发送广播报文,查询该Slave节点1的状态、固件版本号,发送OTA固件升级信息,并设置随机响应信道

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

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

相关文章

云原生之深入解析K8S的请求和限制

一、Kubernetes 限制和请求 在 Kubernetes 中使用容器时,了解涉及的资源是什么以及为何需要它们很重要。有些进程比其它进程需要更多的 CPU 或内存,这很关键,永远不应该让进程饥饿,知道了这一点,那么应该正确配置容器…

python中多态的作用是什么?

在强类型语言(例如Java或C#)中,多态是指允许使用一个父类类型的变量或常量来引用一个子类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果。即使用父类的类型来调用子类的方法。 在Python中,多态指在不考虑对象类型…

SQL中的——左连接(Left join)、右连接(Right join)、内连接(Inner join)

前言 最近有一个开发需求,需要实现一个复杂年度报表,前后端都是博主开发,这里的业务逻辑比较复杂,也很锻炼sql能力,这里博主也将表的内外连接做了一个整理分享给大家 一、概念 首先还是介绍一下这三个的定义 1.Lef…

MySQL容器无法输入或显示中文异常解决

如果使用docker创建了MySQL容器,但是进入容器后发现无法输入中文,也就是在插入数据的时候中文直接显示为空,数据表里的中文也显示为空,解决方法是: 1,临时方法 该方法只在每一次进入容器的命令上添加参数&a…

【Linux从入门到精通|开发工具】---gcc/g++的基本使用

个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【Linux专栏】🎈 本专栏旨在分享学习Linux的一点学习心得,欢迎大家在评论区讨论💌 接下来我们来学习L…

超实用攻略!GPT能玩的这么6,你居然还不知道?

开篇 自古以来,智者皆知学无止境,而在我们身边,正有一款奠基于这个原则的AI机器人—ChatGPT,他擅长从网络上学习各种知识,然后把这些知识用在他的对话中。没错,它就是天马行空的闲话家,无所不谈的取经者。可你知道怎样让它更加符合你的使用需求,适应你的工作节奏么?哦…

github中Mermaid的用法

这个东西是最近推出&#xff0c;首先是自己的repository中新建一个readme.md文件 需要一点前端的知识&#xff0c;就是先导入一个依赖文件&#xff0c;然后再写甘特图&#xff0c;如下&#xff1a; ### 甘特图 [<a href"https://mermaid-js.github.io/mermaid/#/gant…

前端设计必备的5款效率工具

前端设计工具以更低的成本提供更快的移动开发&#xff0c;他们帮助前端开发人员有效地创建响应设计&#xff0c;但找到一个实用的前端设计工具并不容易&#xff0c;在这里&#xff0c;为您整理了五个免费和易于使用的前端页面工具! 1.即时设计 即时设计是一款免费的在线 UI 设…

go-Nunu,一个好用的脚手架推荐,助你快速构建Go应用

虽然直接使用go-gin等框架也很简单&#xff0c;但是涉及数据库、jwt认证、配置文件和日志记录等全套的服务&#xff0c;一个个集成进来也挺费事。关键是一个个集成&#xff0c;很难做到结构清晰和分层合理。这里推荐一个好用的脚手架Nunu&#xff0c;太好用啦&#xff0c;可以让…

el-dialog 层级问题混乱

使用 element -UI 的弹窗时&#xff0c;一般来说弹窗的层级应该比较高&#xff0c;背景置灰。 下边这个弹窗是正常情况下的&#xff1a; 有时候出现这样的情况&#xff1a; 解决问题&#xff1a; 只需要 在标签里边添加 append-to-body 属性问题就解决了。

c#/c++ 通过系统api监视文件变化的问题

再分享个比较经典的案例&#xff0c;在很多场景下&#xff0c;我们都要去监视某个文件夹下的文件变化&#xff0c;在创建、修改或删除的时候触发一些行为。众所周知&#xff0c;c#有个实现类叫FileSystemWatcher&#xff0c;可以用来监视目录包括子目录下文件的变化&#xff0c…

Pygame中获取键盘按键的方法

1 事件与队列 在Pygame中&#xff0c;将用户对游戏的操作叫做“事件”。键盘按键是一种事件&#xff0c;鼠标点击和游戏手柄的输入也是一种事件。在Pygame的子模块locals中&#xff0c;对这些事件进行了定义。当用户通过键盘、鼠标或者游戏手柄对游戏进行操作后&#xff0c;产…

Stable Diffusion 模型界面介绍

Stable Diffusion 模型界面介绍 界面1 图1 Stable Diffusion 模型界面1 ①&#xff1a;选择的模型&#xff0c;及Stable Diffusion进行生成图片是使用的模型。其中.ckpt为大模型 ②&#xff1a;prompt --> 正向提示词。表示你的想法&#xff0c;你想要生成一副什么样的图…

IMX6ULL 移植篇-uboot 网络命令NFS

一. uboot 网络操作命令 本文介绍 nfs 命令的使用&#xff0c;具体是&#xff1a;通过 NFS服务向开发板下载 zImage内核镜像文件。 二. nfs 命令 nfs命令使用的目的&#xff1a;为了方便开发板调试。 nfs(Network File System) 网络文件系统&#xff0c;通过 nfs 可以在计算…

Redis【实战篇】---- 达人探店

Redis【实战篇】---- 达人探店 1. 达人探店 - 发布探店笔记2. 达人探店 - 查看探店笔记3. 达人探店 - 点赞功能4. 达人探店 - 点赞排行榜 1. 达人探店 - 发布探店笔记 发布探店笔记 探店笔记类似点评网站的评价&#xff0c;往往是图文结合。对应的表有两个&#xff1a; tb_bl…

记录力扣热题-100——从链表中找到刷题感觉

目录 一. &#x1f981; 前言二. &#x1f981; 解题过程1. 题目2. 思路一3. 思路二 三. &#x1f981; 文末活动内容简介本书结构关于代码 一. &#x1f981; 前言 狮子此前已经很久没有碰过算法题了&#xff0c;对于之前好不容易攒起来的题感又没了…最近准备面试&#xff0…

这些代码,差点把我气出内伤

先问大家一个小问题&#xff1a;你觉得看别人代码累&#xff0c;还是自己写代码累&#xff1f; 我相信有很多朋友会说&#xff0c;当然是自己写代码累了&#xff0c;要思考逻辑、要动手敲键盘&#xff0c;身心俱疲啊&#xff1b;但是&#xff0c;如果你需要经常阅读别人的代码…

leetcode 141.环形链表(快慢指针追击问题)

⭐️ 往期相关文章 &#x1f4ab;链接1&#xff1a;链表分割 &#x1f4ab;链接2&#xff1a;链表中倒数第k个结点(快慢指针问题) &#x1f4ab;链接3&#xff1a;leetcode 876.链表的中间结点(快慢指针问题) &#x1f4ab;链接4&#xff1a;leetcode 206.反转链表 &#x1f4…

vue echarts k线图 子功能设置

1 图中自定义选择区间, 手动鼠标拉取区间显示 2 底部数据选择条 dataZoom: [{type: inside,xAxisIndex: [0, 1],start: 98,end: 100},{show: true, // 这个是打开数据 选择条xAxisIndex: [0, 1],type: slider,top: 85%,start: 98,end: 100}], 3 鼠标在 k线图 选择区域 显示 的…

简历石沉大海!这份新鲜出炉的测试用人需求分析报告揭示了原因

最近有朋友吐槽简历投递后石沉大海&#xff0c;而主动打电话面试的除了外包还是外包。软件测试就业形势真的这么糟糕了&#xff1f; 小酋决定用数据揭开真相。因此小酋选取“软件测试”、“自动化测试”、“测试开发”作为搜索关键词&#xff0c;统计了 无忧网 近一个月用人市…