main.lua 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. -- LuaTools需要PROJECT和VERSION这两个信息
  2. PROJECT = "fotademo"
  3. VERSION = "1.0.0"
  4. --[[
  5. 演示用uart进行固件升级
  6. 本demo 适用于 Air780E/Air780EG/Air600E
  7. 1. 需要 V1107及以上的固件
  8. 2. 需要 LuaTools 2.1.89 及以上的升级文件生成
  9. 目录内文件的说明
  10. 1. main.lua 本文件, 是下载到模块的唯一文件
  11. 2. fota_uart.bin 演示用的脚本升级文件,不需要下载到模块
  12. 3. main.py 上位机发送升级包的程序, 不需要下载到模块
  13. fota_uart.bin 使用 LuaTools 的 "量产文件" 按钮进行生成, .bin后缀的就是脚本OTA文件
  14. 用法:
  15. 1. 先把脚本和固件烧录到模块里, 并确认开机
  16. 2. 进入命令行程序, 执行 python main.py 升级
  17. 3. 观察luatools的输出和main.py的输出
  18. 4. 模块接收正确的升级数据后,会提示1秒后重启
  19. 5. 本demo自带的脚本升级包,升级后是GPIO闪灯的demo
  20. 注意: 本demo默认是走虚拟串口进行交互, 如需改成物理串口, 修改uart_id和main.py
  21. ]]
  22. _G.sys = require "sys"
  23. -- 定义所需要的UART编号
  24. -- uart_id = 1 -- 物理UART1, 通常也是MAIN_UART
  25. uart_id = uart.VUART_0 -- 虚拟USB串口
  26. -- 循环打印当前版本, 从而直观表示是否升级成功
  27. -- sys.taskInit(function()
  28. -- while 1 do
  29. -- sys.wait(3000)
  30. -- log.info("fota", "version", VERSION)
  31. -- end
  32. -- end)
  33. -- 开始初始化uart
  34. uart_zbuff = zbuff.create(1024)
  35. uart.setup(uart_id, 115200)
  36. -- 几个状态变量, 调试用
  37. local uart_fota_state = 0
  38. local uart_rx_counter = 0
  39. local uart_fota_writed = 0
  40. uart.on(uart_id, "receive", function(id, len)
  41. -- 防御缓冲区超标的情况
  42. if uart_zbuff:used() > 8192 then
  43. log.warn("fota", "uart_zbuff待处理的数据太多了,强制清空")
  44. uart_zbuff:del()
  45. end
  46. while 1 do
  47. local len = uart.rx(id, uart_zbuff)
  48. if len <= 0 then
  49. break
  50. end
  51. -- if #s > 0 then -- #s 是取字符串的长度
  52. uart_rx_counter = uart_rx_counter + len
  53. log.info("uart", "收到数据", len, "累计", uart_rx_counter)
  54. if uart_fota_state == 0 then
  55. sys.publish("UART_FOTA")
  56. end
  57. end
  58. end)
  59. sys.taskInit(function()
  60. local fota_state = 0 -- 0还没开始, 1进行中
  61. while 1 do
  62. -- 等待升级数据到来
  63. sys.waitUntil("UART_FOTA", 1000)
  64. local used = uart_zbuff:used()
  65. if used > 0 then
  66. if fota_state == 0 then
  67. -- 等待FOTA的状态
  68. if used > 5 then
  69. local data = uart_zbuff:query()
  70. uart_zbuff:del()
  71. -- 如果接受到 #FOTA\n 代表数据要来了
  72. if data:startsWith("#FOTA") and data:endsWith("\n") then
  73. fota_state = 1
  74. log.info("fota", "检测到fota起始标记,进入FOTA状态", data)
  75. fota.init()
  76. -- 固件数据发送端应该在收到#FOTA RDY\n之后才开始发送数据
  77. uart.write(uart_id, "#FOTA RDY\n")
  78. end
  79. end
  80. else
  81. uart_fota_writed = uart_fota_writed + used
  82. log.info("准备写入fota包", used, "累计写入", uart_fota_writed)
  83. local result, isDone, cache = fota.run(uart_zbuff)
  84. log.debug("fota.run", result, isDone, cache)
  85. uart_zbuff:del() -- 清空缓冲区
  86. if not result then
  87. fota_state = 0
  88. fota.isDone()
  89. uart.write(uart_id, "#FOTA ERR\n")
  90. log.info("fota", "出错了", result, isDone, cache)
  91. elseif isDone then
  92. while true do
  93. sys.wait(100)
  94. local succ, fotaDone = fota.isDone()
  95. if not succ then
  96. fota_state = 0
  97. uart.write(uart_id, "#FOTA ERR\n")
  98. log.info("fota", "出错了")
  99. break
  100. end
  101. if fotaDone then
  102. uart_fota_state = 1
  103. log.info("fota", "已完成,1s后重启")
  104. -- 反馈给上位机
  105. uart.write(uart_id, "#FOTA OK\n")
  106. sys.wait(1000)
  107. rtos.reboot()
  108. end
  109. sys.wait(100)
  110. end
  111. else
  112. log.info("fota", "单包写入完成", used, "等待下一个包")
  113. uart.write(uart_id, "#FOTA NEXT\n")
  114. end
  115. end
  116. end
  117. end
  118. end)
  119. -- 用户代码已结束---------------------------------------------
  120. -- 结尾总是这一句
  121. sys.run()
  122. -- sys.run()之后后面不要加任何语句!!!!!