那么是不是说只需要将打包好的固件放入“downloader”里面就能更新?这个是由 bootloader 的设计决定的。
举报
你的思路完全正确!OTA 并不依赖于 YMODEM 或者其他任何特定的传输协议。 YMODEM 只是一种在特定场景(如串口)下广泛使用的、可靠的文件传输协议,它被许多 Bootloader 采纳是因为它提供了校验、重传和文件信息等实用功能。
分析你的情况和问题:
通用 Bootloader 成功实现 OTA: 这证明了核心功能(接收新固件、擦写 Flash、验证、跳转)是没问题的。关键点在于 Bootloader 如何接收这个新固件。
固件内容一致但更新失败: 这正是问题的核心。仅仅将固件二进制数据写入 download 区域(我理解是你 Bootloader 预留的用于存放新固件的 Flash 区域)通常是不够的。失败的原因几乎肯定在于 Bootloader 启动时的决策逻辑:
0xA5A5A5A5)。这个标志告诉 Bootloader:“download 区域有新固件,请验证并更新”。如果你只是把数据写进去,但没有设置这个标志,Bootloader 会直接跳过更新流程,尝试启动旧的主程序。download 区域的哪个位置开始?download 区域的数据是否传输完整且没有损坏。download 区域的起始地址。偏移了哪怕一个字节,Bootloader 找到的数据就不对。通过串口2直接接收更新(无 YMODEM): 这种想法完全成立,并且是更底层、更灵活的方式。 你需要实现的是:
... 。ACK -> 上位机发下一块;校验失败或超时发送 NAK -> 上位机重发当前块。'C' 等待固件)、传输结束确认。download 区域的正确地址。ACK 请求下一块;校验失败或超时,发送 NAK 请求重发当前块。0xA5A5A5A5)。download 区内)。download 区域中固件的校验值。download 区复制到主程序区(应用起始地址)。总结与建议:
main() 函数最开始或 check_for_update() 之类的函数里。download 区。download 区的数据(不仅是内容,还包括写入的起始地址和大小)。核心要点:Bootloader 需要在重启后“知道”两件事:(1) 是否需要更新? (2) 如果需要更新,新固件在哪(地址)?它有多大?如何验证它是否完整正确(校验值)? 你之前缺少的就是让 Bootloader “知道”需要更新以及如何验证的信息(标志和元数据)。解决这个问题,你的方案就能成功。
举报
更多回帖