fota_file.lua 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. --[[
  2. @module fota_file
  3. @summary 文件系统FOTA升级功能模块
  4. @version 1.0
  5. @date 2025.10.24
  6. @author 孟伟
  7. @usage
  8. -- 文件系统FOTA升级功能
  9. -- 提供从文件系统直接读取升级包进行固件升级的功能
  10. -- 可以使用luatools工具的烧录系统文件功能将升级包直接烧录到文件系统中,
  11. 本文件没有对外接口,直接在main.lua中require "fota_file"就可以加载运行;
  12. ]]
  13. local function fileUpgradeTask()
  14. -- 等待系统稳定后再开始升级
  15. sys.wait(10000)
  16. gpio.setup(13, 1) -- TF卡供电控制(AIR8101专用)
  17. local mount_ok, mount_err = fatfs.mount(fatfs.SDIO, "/sd", 24 * 1000 * 1000)
  18. if mount_ok then
  19. log.info("fatfs.mount", "挂载成功", mount_err)
  20. local data, err = fatfs.getfree("/sd") -- 获取SD卡剩余空间信息
  21. if data then
  22. -- table: 若成功会返回table, 否则返回nil
  23. -- table 中包含 total_sectors(总扇区数量), free_sectors(空闲扇区数量), total_kb(总字节数,单位kb), free_kb(空闲字节数, 单位kb)
  24. log.info("fatfs", "getfree", json.encode(data))
  25. else
  26. -- err: 导致失败的底层返回值
  27. log.info("fatfs", "err", err)
  28. end
  29. log.info("FOTA_FILE", "=== 开始文件系统升级 ===")
  30. else
  31. log.error("fatfs.mount", "挂载失败", mount_err)
  32. log.error("FOTA_FILE", "SD卡挂载失败,无法进行文件系统升级")
  33. -- 调用fota.finish(false)结束升级流程,参数false表示升级流程失败
  34. fota.finish(false)
  35. -- 尝试卸载(如果需要)
  36. fatfs.unmount("/sd")
  37. return
  38. end
  39. -- 步骤1: 初始化FOTA流程
  40. log.info("FOTA_FILE", "初始化FOTA...")
  41. if not fota.init() then
  42. log.error("FOTA_FILE", "FOTA初始化失败")
  43. return
  44. end
  45. -- 步骤2: 等待底层准备就绪
  46. log.info("FOTA_FILE", "等待底层准备...")
  47. -- while not fota.wait() do
  48. -- sys.wait(100)
  49. -- end
  50. log.info("FOTA_FILE", "底层准备就绪")
  51. -- 步骤3: 从文件系统读取升级包并启动升级
  52. local filePath = "/sd/update.bin"
  53. log.info("FOTA_FILE", "开始读取升级文件:", filePath)
  54. local result, isDone, cache = fota.file(filePath)
  55. log.info("FOTA_FILE", "升级文件写入flash中的fota分区结果", result, isDone, cache)
  56. -- 步骤4: 结束写入fota分区
  57. log.info("FOTA_FILE", "结束写入fota分区...")
  58. local result, isDone = fota.isDone()
  59. log.info("FOTA_FILE", "写入fota分区状态", "结果:", result, "完成:", isDone)
  60. if result then
  61. -- 步骤5: 处理写入结果
  62. if isDone then
  63. -- 升级文件成功写入flash中的fota分区,准备重启设备;
  64. -- 设备重启后,在初始化阶段的运行过程中会自动应用fota分区中的数据完成升级,最终升级结果可以通过观察日志中的版本号来区分。
  65. log.info("FOTA_FILE", "升级成功,准备重启设备")
  66. -- 调用fota.finish(true)结束升级流程,参数true表示正确走完流程。
  67. fota.finish(true)
  68. -- 可选:删除升级包文件
  69. -- os.remove("/update.bin")
  70. sys.wait(2000)
  71. rtos.reboot()
  72. else
  73. log.error("FOTA_FILE", "升级失败")
  74. -- -- 调用fota.finish(false)结束升级流程,参数false表示升级流程失败。
  75. fota.finish(false)
  76. end
  77. else
  78. log.error("FOTA_FILE", "升级失败:检查写入状态失败")
  79. -- -- 调用fota.finish(false)结束升级流程,参数false表示升级流程失败。
  80. fota.finish(false)
  81. end
  82. end
  83. -- 启动文件升级任务
  84. sys.taskInit(fileUpgradeTask)