研究了几天发现不算困难。首先要了解一点就是,差分包的制作由 “差分算法” 计算 “diff” (差分后的数据) 然后根据 “压缩算法” 进行压缩,压缩后的数据文件即为 “patch” 即差分包。
因为差分算法有开源的bsdiff,压缩算法也有开源的单片机就能用的,把这两个结合起来放单片机里就可以实现差分升级。
由于上位机负责进行差分和压缩的操作,而上位机没有ram的限制,可以随意。因此只要解压缩和解差分在单片机中实现就可以了。
如下图,对整个Flash分成3个区域。
boot区:用于存放引导程序和解压,解差分算法,其中boot区在额外留出一个扇区用于存储版本信息和跳转地址,以及用于验证是差分升级还是近端升级的校验信息。
patch区:用于存放差分包(差分包中包含以下关键信息:新旧文件的大小和校验)。
app区:用于存放执行app(old文件)和用于提供解压缩的空间。
正常而言由于ram相对有限,所以压缩能力需要根据实际ram的大小来进行操作,然而太小的压缩空间实际不利于进行数据压缩,即压缩空间预留的越小,差分包相对越大,然而对单片机压力越小,理论最小1K的单片机ram就可以,然而这样压缩率可能会很差。
假定上位机以2000字节的压缩空间进行压缩,那么下位机需要预留出至少4k的ram进行压缩合成操作(因为上位机压缩完的数据是多少,那么解压缩后的数据必然就是多少,如果不对肯定是出问题了)。假定差分包已经生成并下载完成并跳转到boot,那么boot需要处理以下步骤:
0.解析 patch
1.对版本进行校验,比对旧文件的信息与差分包旧文件信息是否一致
2.计算app空间是否能够放得下 new 文件(这里的计算需要一定判断,无论 old 文件地址在哪,只要flsh有连续的空间能够放入 new 就可以,如上图所示的情况,new 文件大小大于 old 文件大小,需要在 old 的起始地址基础上 计算 new 的长度 ,然后在计算 new 文件的起始地址)
3.解压 patch 到 new 文件起始地址(解压后的文件实际是 diff,即差分文件)
4.逐扇区读取数据到 ram 然后根据 差分算法进行解差分 将 diff 文件和 old 文件进行合并。合并后再将读出扇区的 flash 擦除在写入
5.校验合成后的新文件信息
6.擦除 old 文件 复制 new 文件到 old 起始地址
7.跳转到 new