接收到一半断开,为什么旧程序必须还在
从失败场景反推暂存和状态记录。用两个普通文件实际收一份候选内容,每次命令结束后都可以重新读取进度。
1 · 先看直接覆盖的后果
若接收一块就覆盖当前应用,第一块写入以后旧应用已不完整,新应用又还没收全。此时断连或掉电,可能没有任何一份可启动内容。升级的第一项要求是:接收失败时仍保留一条可恢复路径。
2 · 先启动一份普通文件实验
在独立练习目录运行 · 文件内容是 12 字节人工文本
python -c "from pathlib import Path; Path('new.bin').write_bytes(b'new-demo-app')"
python ota_files.py --root update_practice init
python ota_files.py --root update_practice begin new.bin
python ota_files.py --root update_practice chunk new.bin --offset 0 --length 4
python ota_files.py --root update_practice statusinit 创建旧文件和初始状态,begin 选择非当前确认槽并登记大小、摘要和目标,chunk 只写本次四字节,status 从磁盘重新读取。每条命令都是一次独立进程,不依赖上一个 Python 进程内的变量。
3 · 重复块和错序块怎样处理
示例采用顺序传输,只接受当前进度处的新块,或已收范围内内容完全一致的重复块。未来位置的块被拒绝,重复数据不再增加进度。这个约定使停止等待和超时重传容易推理,和主线逐片确认的思想相接。
真实无线分片还要带事务编号和对应确认,不能把旧升级的重试块放进新升级。样例从同一输入文件取块并检查摘要,演示内容一致性;完整无线协议仍需根据项目三端实现。
4 · 进度记录和内容谁先持久化
示例先把候选槽标为无效,再复用候选文件;每块先写内容并刷新,再保存进度。若进程恰在内容写入后、进度更新前停止,重发同一偏移可安全重写。状态文件通过临时文件替换,避免把半段 JSON 当完整记录。
这只模拟进程重启边界。实际掉电还涉及文件系统、Flash 编程与元数据的物理原子性,普通文件的 os.replace 和 fsync 不构成芯片掉电保护证明。
5 · 只有收全,才进入下一阶段
补齐剩余八字节并检查
python ota_files.py --root update_practice chunk new.bin --offset 4 --length 8
python ota_files.py --root update_practice finishfinish 需要进度等于预期大小、实际文件长度正确、摘要一致。检查失败时旧确认槽仍保留;成功只标记待试运行,还没有永久采用新内容。
收到四字节后退出终端,再运行 status 和后续命令。重复第一块、尝试未来偏移、删去尾部内容,分别观察拒绝结果及旧槽是否完整。
资料与代码
配套文件
先复制到独立练习目录;用法见 支线示例说明。