ymodem_receive.lua 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. --[[
  2. @module main
  3. @summary ymodem 接收文件应用功能模块
  4. @version 1.0
  5. @date 2025.10.27
  6. @author 李源龙
  7. @usage
  8. 本文件为Air780EHM核心板演示ymodem功能的代码示例,核心业务逻辑为:
  9. 1. 创建协程,调用ymodem_open函数打开ymodem接收功能,初始化zbuff,
  10. 初始化串口,创建一个ymodem对象,然后开始往串口发送'C'字符,启动ymodem接收功能。
  11. 2. 接收串口数据,并且保存到指定路径,接收完成后,自动关闭ymodem接收功能。
  12. ]]
  13. -- 根据实际设备选取不同的uartid
  14. local uartid = 1
  15. local taskName = "ymodem_open"
  16. -- 处理未识别的消息
  17. local function ymodem_open_cb(msg)
  18. log.info("ymodem_open_cb", msg[1], msg[2], msg[3], msg[4])
  19. end
  20. -- 定义一个局部变量,用于表示Ymodem协议是否正在运行
  21. local ymodem_running = false
  22. local rxbuff
  23. local ymodem_handler
  24. local ymodem_result=false
  25. --定义一个ymodem_close函数,用于关闭ymodem接收功能,包括释放zbuff,关闭串口,释放ymodem对象等操作
  26. local function ymodem_close()
  27. --释放rxbuff
  28. rxbuff:free()
  29. --关闭串口
  30. uart.close(uartid)
  31. --释放ymodem处理程序
  32. ymodem.release(ymodem_handler)
  33. end
  34. -- 定义一个ymodem_rx函数,用于接收数据
  35. local function ymodem_rx(id,len)
  36. -- 从uart接收数据到缓冲区
  37. while 1 do
  38. log.info("uart", "缓冲区", uart.rxSize(id)) -- 缓冲区中的数据数量
  39. local len = uart.rx(id, rxbuff)
  40. if len <= 0 then
  41. break
  42. end
  43. log.info("uart", "receive", id, rxbuff:used(), rxbuff:toStr())
  44. end
  45. -- 打印缓冲区已使用的大小
  46. log.info(rxbuff:used())
  47. -- 调用ymodem.receive函数,接收数据
  48. local result,ack,flag,file_done,all_done = ymodem.receive(ymodem_handler,rxbuff)
  49. ymodem_running = result
  50. log.info("result:",ymodem_running,ack,flag,file_done,all_done)
  51. rxbuff:del()
  52. --成功就发送ack和flag
  53. if result then
  54. rxbuff:copy(0, ack,flag)
  55. uart.tx(id, rxbuff)
  56. end
  57. -- 所有数据都接收完毕
  58. if all_done then
  59. -- 判断/save.bin文件是否存在
  60. local exists=io.exists("/save.bin")
  61. -- 判断/save.bin文件是否存在,存在则打印日志,显示/save.bin文件大小;不存在则打印日志,显示/save.bin文件不存在
  62. if exists then
  63. log.info("io", "save.bin file exists:", exists)
  64. --打印文件大小
  65. log.info("io", "save.bin file size:", io.fileSize("/save.bin"))
  66. else
  67. log.info("io", "save.bin file not exists")
  68. end
  69. --ymodem_running置为false,再次开始接收
  70. ymodem_running = false
  71. --ymodem_result置为true,表示接收完成
  72. ymodem_result=true
  73. --关闭ymodem,释放资源
  74. ymodem_close()
  75. end
  76. rxbuff:del()
  77. end
  78. local function uart_sent_cb(id)
  79. log.info("uart", "sent", id)
  80. end
  81. --开启ymodem接收,主要包括串口初始化,zbuff初始化,ymodem初始化等,初始化完毕之后开始发送'C',等待发送端发送数据
  82. local function ymodem_open()
  83. --初始化
  84. uart.setup(
  85. uartid,--串口id
  86. 115200,--波特率
  87. 8,--数据位
  88. 1--停止位
  89. )
  90. -- 监听串口接收事件
  91. uart.on(uartid, "receive", ymodem_rx)
  92. -- 监听串口发送事件
  93. uart.on(uartid, "sent", uart_sent_cb)
  94. -- 创建一个缓冲区,大小为1024 + 32,接收数据为1k,32为剩下的协议数据,可能不到32,保险起见,留足够的大小
  95. rxbuff = zbuff.create(1024 + 32)
  96. -- 创建一个ymodem处理程序,保存路径为"/",文件名为"save.bin"
  97. ymodem_handler = ymodem.create("/","save.bin")
  98. while not ymodem_result do
  99. -- 如果ymodem协议没有在运行,则发送请求;并重置ymodem处理程序
  100. if not ymodem_running then
  101. --YMODEM 传输文件时,接收方会先发送一个字符 'C'来启动传输过程
  102. uart.write(uartid, "C")
  103. --发送完之后重置恢复到初始状态
  104. ymodem.reset(ymodem_handler)
  105. end
  106. sys.wait(500)
  107. end
  108. end
  109. --创建并且启动一个task
  110. --运行这个task的主函数ymodem_run
  111. sys.taskInit(ymodem_open, taskName,ymodem_open_cb)