ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Flipper Zero Unleashed 固件 OTA 更新机制与更新包构建实战指南

Flipper Zero Unleashed 固件 OTA 更新机制与更新包构建实战指南 Flipper Zero Unleashed 固件 OTA 更新机制与更新包构建实战指南【免费下载链接】unleashed-firmwareFlipper Zero Unleashed Firmware项目地址: https://gitcode.com/GitHub_Trending/un/unleashed-firmware本指南以 documentation/OTA.md 为核心深入剖析 Flipper ZeroUnleashed Firmware的 OTAOver-The-Air固件更新原理从从 RAM 执行代码的特殊引导模式到备份/int内部存储、烧写主固件与 Core2 无线协议栈、恢复配置的三阶段流程再到 Update manifest 清单格式、错误码定位与更新包构建命令。读完本文你将能够理解 OTA 更新的全部内部机制掌握使用fbt与scripts/update.py构建完整版、精简版、自定义无线协议栈版及部分更新包的方法并学会根据[XX-YY]格式错误码快速定位更新失败原因。为什么 OTA 需要从 RAM 执行代码的引导模式Flipper 固件中存在一个特殊的引导模式系统会将一个精心构造的系统镜像加载到 RAM 中并把控制权移交给它。从 RAM 中执行的系统镜像对 Flipper 整个 Flash 存储拥有完整的写入权限——这是主固件从同一片 Flash 上运行时不可能做到的代码正在执行的存储介质无法被同时安全改写。OTA 固件更新正是利用了这一引导模式它还同时承担了对运行在第二颗 MCU 核心Core2上的无线电协议栈Radio Stack执行安装、卸载等操作的任务。这意味着 OTA 不仅要更新主固件还要维护双核架构下 BLE 协议栈的版本一致性与安装地址正确性这是 Flipper OTA 区别于普通单片机固件升级的核心特征。OTA 更新三阶段流程一次完整的 OTA 更新安装分为 3 个阶段阶段 1备份内部存储/int/int是 Flipper Flash 上的一块专用分区占据固件代码未使用的全部剩余空间。由于新版本固件的体积可能不同直接安装新固件会导致 Flash 重新分区从而造成数据丢失。因此在动固件之前系统会先把当前/int中的配置备份成一个普通的 tar 归档文件保存到 SD 卡上。在源码中这一阶段由 applications/system/updater/util/update_task_worker_backup.c 实现对应 update_task.h 中的UpdateTaskStageIntBackup阶段。备份前更新任务还会检查内部存储的剩余空间update_operation.c 中定义了UPDATE_MIN_INT_FREE_SPACE (2 * 4 * 1024)要求至少预留 2 个 LFS 页面共 8KB的空闲空间否则更新会被拒绝UpdatePrepareResultIntFull。阶段 2执行设备更新主固件将 updater 镜像——一种主固件的定制构建版本——加载到 RAM 并运行。Updater 按照 Update manifest 文件的描述对系统 Flash 执行一系列操作无线协议栈Radio Stack处理如果更新包捆绑了 Radio Stack 镜像updater 会先将其版本与当前已安装的版本进行比较。版本不匹配时updater 先执行协议栈卸载再写入并安装新协议栈。安装动作本身由运行在 Core2 上的专有软件 FUSSTM32 无线固件升级服务执行并会引发一系列系统重启。Option Bytes 校验与修正Option Bytes 是存放 Flipper MCU 底层配置的特殊内存区域updater 会对照 manifest 中的参考值对其进行校验与纠正。固件烧写updater 加载要烧写的.dfu固件文件先用 CRC32 校验其完整性写入系统 Flash 后再次校验写入的数据。阶段 3恢复内部存储并更新资源对 Flash 的操作完成后系统重启进入新固件并执行先前备份的/int内容恢复。如果更新包还包含额外的资源归档Resources字段指定的 tar 包则会将其解压到 SD 卡上。此外如果 manifest 中带有Splashscreen字段更新后还会安装更新完成后的开机动画见 update_task.h 中的UpdateTaskStageSplashscreenInstall等阶段。Update manifest更新包的内容清单更新包自带一份描述其内容的 manifest 清单文件默认名为update.fuf。manifest 使用 Flipper File Format——一种由键值对组成的简单文本文件。设备端由 update_manifest.c 负责解析其中定义了所有字段的键名常量见该文件 第 7-20 行。必填字段必须按以下顺序出现字段说明Filetype常量字符串必须为Flipper firmware upgrade configuration。解析时通过 update_manifest.c 第 58-60 行 与flipper_format_read_header读取并严格比较不匹配则 manifest 无效Versionmanifest 版本号当前值为 2。设备端要求manifest_version UPDATE_OPERATION_MIN_MANIFEST_VERSION(2)更老的包会被判定为OutdatedManifestVersion见 update_operation.hInfo任意字符串描述包内容例如版本号r13.3_fullTarget包所面向的硬件版本。生成时 update.py 会把-t f7这类参数剥掉首字母f后写入Loader从 RAM 执行的 Stage 2 loader 的文件名固定为updater.bin见 update.py 第 92 行Loader CRCLoader 文件的 CRC32注意以小端十六进制表示。生成逻辑见 update.py 第 180-181 行 的int2ffhex逐字节倒序排列设备端用flipper_format_read_hex读回并比较可选字段其余字段允许为空值为空时 updater 跳过与之相关的全部操作。设备端解析这些可选字段的代码见 update_manifest.c 第 73-114 行。字段说明RadioSTM 提供的无线协议栈镜像文件名生成时固定为radio.binRadio address协议栈的安装地址由 STM 在 Release Notes 中给出。不指定时 update.py 第 126-131 行 会从镜像签名中读取默认 Flash 加载地址get_flash_load_addr()并打印提示要求与 Release_Notes 核对Radio version协议栈主版本、次版本、子版本以及分支branch、发布release、栈类型stack type打包成 6 个十六进制字节。打包逻辑见 update.py 的copro_version_as_intmajor \| minor8 \| sub16 \| branch24 \| release32 \| stype40设备端用 6 字节联合体UpdateManifestRadioVersion解析见 update_manifest.hRadio CRC协议栈镜像的 CRC32Resources要解压到 SD 卡的资源 tar 归档文件名固定为resources.thsTar.Heatshrink 压缩格式见 update.py 第 24-25 行OB reference / OB mask / OB write mask用于校验和纠正 Option Bytes 的参考值。生成时 update.py 第 191-200 行 从scripts目录下的 Option Bytes 数据文件如scripts/ob.data、scripts/ob_custradio.data计算得到文件注释明确警告NEVER EVER MESS WITH THESE VALUES, YOU WILL BRICK YOUR DEVICE。设备端在 update_manifest.c 第 145-157 行 的update_manifest_has_obdata中对 mask 的一致性值与其反码相等以及参考值是否完全落在 compare mask 掩码位内做完整性检查除上述字段外源码中还存在Firmware.dfu固件文件名固定为firmware.dfu与Splashscreen更新后开机动画splash.bin两个键见 update_manifest.c 第 11、20 行后者在文档中被列为可选字段。更新包的预检与武装机制值得补充的是manifest 并不是在重启后被立刻执行的。在正式重启进入 updater 之前update_operation.c 的update_operation_prepare会做一整套预检检查/int空闲空间、确认 manifest 文件存在且有效、核对 manifest 版本与硬件 Target仅当设备硬件版本号非 0 时比较预量产设备接受任意固件、验证 Stage2 loader 存在且 CRC32 匹配然后将 manifest 路径写入 SD 卡根目录的.fupdate指针文件UPDATE_MANIFEST_POINTER_FILE_NAME并设置 RTC 引导模式为FuriHalRtcBootModePreUpdate。重启后update_operation_is_armed第 221-232 行据此判断是否存在待执行的更新失败时可用update_operation_disarm取消。OTA 更新错误码定位表OTA 更新流程被设计得尽可能防错在任何有风险的操作开始前都会先校验所有相关数据避免设备停留在部分更新或变砖的状态。即使出错updater 也允许重试失败的操作并通过错误码报告当前状态。错误码采用[XX-YY]格式XX编码失败的操作阶段YY携带该阶段中出错位置/进度的额外细节。以下为完整错误码表与 documentation/OTA.md 及 update_task.h 的阶段枚举 一一对应阶段描述代码进度说明加载更新 manifest113Updater 报告硬件版本不匹配20无法获取已保存的 manifest 路径30加载 manifest 失败40不支持的更新包版本50包与硬件目标不匹配60缺少 DFU 文件80缺少无线协议栈固件文件备份配置20-100文件系统读/写错误检查无线协议栈固件30-99读取协议栈固件文件错误100CRC 不匹配卸载无线协议栈固件40SHCI Delete 命令错误80等待命令状态出错写入无线协议栈固件50-100块读/写错误安装无线协议栈固件610SHCI Install 命令错误80等待命令状态出错Core2 忙710无法启动 C220切换 C2 到 FUS 模式失败30FUS 操作出错50切换 C2 到协议栈模式失败校验 Option Bytes8yyOption byte 代码检查 DFU 文件90打开 DFU 文件出错1-98读取 DFU 文件出错99-100DFU 文件损坏写 Flash100-100块读/写错误校验 Flash110-100块读/写错误恢复配置120-100文件系统读/写错误更新资源13-150-100SD 卡读/写错误阶段编号与源码中UpdateTaskStage枚举的顺序一致UpdateTaskStageReadManifest(1)、UpdateTaskStageIntBackup(2)、UpdateTaskStageRadioImageValidate(3)、UpdateTaskStageRadioErase(4)、UpdateTaskStageRadioWrite(5)、UpdateTaskStageRadioInstall(6)、UpdateTaskStageRadioBusy(7)、UpdateTaskStageOBValidation(8)、UpdateTaskStageValidateDFUImage(9)、UpdateTaskStageFlashWrite(10)、UpdateTaskStageFlashValidate(11)、UpdateTaskStageIntRestore(12)而资源更新对应UpdateTaskStageResourcesFileCleanup、UpdateTaskStageResourcesDirCleanup、UpdateTaskStageResourcesFileUnpack13-15。构建更新包完整包Full package构建包含固件、无线协议栈以及 SD 卡资源的完整更新包./fbt COMPACT1 DEBUG0 updater_packageCOMPACT1 DEBUG0用于生成精简、无调试符号的发布固件。精简包Minimal package仅包含固件的最小更新包./fbt COMPACT1 DEBUG0 updater_minpackage自定义更新捆绑包默认更新包使用 Bluetooth Light 协议栈。如果你的固件版本支持其他协议栈可以通过向fbt传入协议栈类型和二进制文件名来构建自定义捆绑包./fbt updater_package COMPACT1 DEBUG0 COPRO_OB_DATAscripts/ob_custradio.data COPRO_STACK_BINstm32wb5x_BLE_Stack_full_fw.bin COPRO_STACK_TYPEble_full注意COPRO_OB_DATA必须指向scripts目录下一个有效的、与你的协议栈类型匹配的 Option Bytes 参考数据文件。在某些情况下还需要在命令行中添加COPRO_DISCLAIMER...来确认你的操作意图——这对应 update.py 中的免责确认机制当你捆绑非白名单协议栈类型白名单为 BLE_FULL / BLE_LIGHT / BLE_BASIC见 update.py 第 28-33 行或内存布局可疑时脚本会要求追加--I-understand-what-I-am-doingyes对应COPRO_DISCLAIMER才会继续否则会警告你可能把设备砖化到需要 SWD 编程器才能修复的状态。构建部分更新包Partial update packages直接调用scripts/update.py可以灵活定制包内容。例如构建一个仅安装 BLE FULL 协议栈的包scripts/update.py generate \ -t f7 -d r13.3_full -v BLE FULL 13.3 \ --stage dist/f7/flipper-z-f7-updater-*.bin \ --radio lib/stm32wb_copro/firmware/stm32wb5x_BLE_Stack_full_fw.bin \ --radiotype ble_fullupdate.py generate支持的关键参数见 update.py 第 53-88 行参数说明-d/--directory输出目录必填-v/--version包的 Info 描述字符串必填-t/--target硬件目标如f7必填--stageStage2 loader 文件必填即dist/f7/flipper-z-f7-updater-*.bin--dfu要烧写的固件.dfu文件可选与 radio 至少有一个-r/--resources要打包为resources.ths的资源目录可选--radio无线协议栈镜像可选--radioaddr协议栈安装地址十六进制可选默认从镜像签名推断--radiotype协议栈类型如ble_full提供--radio时必填--stackversion校验协议栈镜像内部签名版本是否匹配可选--obdataOption Bytes 参考数据文件用于生成 OB 三字段可选--splash更新完成后播放的开机动画图片可选--I-understand-what-I-am-doing非白名单协议栈/可疑布局的免责确认可选生成过程中 update.py 还会做内存布局检查layout_check当固件与协议栈地址都已知时计算固件末尾到协议栈安装地址FLASH_BASE 0x8000000FLASH_PAGE_SIZE 4KB之间的保留区大小若固件镜像与 C2 区域重叠或保留区过小则给出警告并要求免责确认同时若 Stage2 loader 超过UPDATER_SIZE_THRESHOLD 128KB会提示旧固件无法加载。资源的打包采用 Tar Heatshrink 压缩窗口 13 / 前瞻 6见 update.py 第 43-44 行并限制单个资源文件名长度不超过 100 字符。关于update.py generate的全部参数可随时运行以下命令查看帮助scripts/update.py generate -h小结Flipper Zero 的 OTA 更新是一条完整的备份 → 预检武装 → RAM 引导执行 → 协议栈/OB/固件处理 → 恢复配置流水线/int备份与恢复保证了跨版本重分区的数据安全从 RAM 执行 updater 镜像赋予了对整片 Flash 的写权限Update manifest 以 Flipper File Format 承载 loader、固件、协议栈、资源与 Option Bytes 的元数据并支持字段级裁剪[XX-YY]错误码与UpdateTaskStage枚举一一对应让失败定位精确到阶段与进度。无论是发布固件还是为特殊无线协议栈定制包fbt与 scripts/update.py 都提供了从完整包到部分包的完整构建能力。更多细节可继续阅读 documentation/OTA.md 及相关源码。【免费下载链接】unleashed-firmwareFlipper Zero Unleashed Firmware项目地址: https://gitcode.com/GitHub_Trending/un/unleashed-firmware创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表