Dozingfiretruck пре 3 година
родитељ
комит
8983375e92
2 измењених фајлова са 136 додато и 0 уклоњено
  1. 9 0
      script/libs/xmodem/package.json
  2. 127 0
      script/libs/xmodem/xmodem.lua

+ 9 - 0
script/libs/xmodem/package.json

@@ -0,0 +1,9 @@
+{
+    "type" : "lua", // 可以是lua(纯lua), c(纯c), 或者lua-c(混合)
+    "enterpoint" : "xmodem.lua",
+    "compatibility" : {
+        "soc" : true,
+        "air" : false
+    },
+    "dependency" : ["i2c"] // 需要何种硬件或软件接口
+}

+ 127 - 0
script/libs/xmodem/xmodem.lua

@@ -0,0 +1,127 @@
+--[[
+@module xmodem
+@summary xmodem 驱动
+@version 1.0
+@date    2022.06.01
+@author  Dozingfiretruck
+@usage
+--注意:因使用了sys.wait()所有api需要在协程中使用
+-- 用法实例
+local xmodem = require "xmodem"
+sys.taskInit(function()
+    xmodem.send(2,115200,"/luadb/test.bin")
+    while 1 do
+        sys.wait(1000)
+    end
+end)
+]]
+local xmodem = {}
+
+local sys = require "sys"
+
+local HEAD
+local DATA_SIZE 
+
+local SOH           =   0x01    -- Modem数据头 128
+local STX           =   0x02    -- Modem数据头 1K
+local EOT           =   0x04    -- 发送结束
+local ACK           =   0x06    -- 应答
+local NAK           =   0x15    -- 非应答
+local CAN           =   0x18    -- 取消发送
+local CTRLZ         =   0x1A    -- 填充
+local CRC_CHR       =   0x43    -- C: ASCII字符C
+local CRC_SIZE      =   2
+local FRAME_ID_SIZE =   2
+local DATA_SIZE_SOH =   128
+local DATA_SIZE_STX =   1024
+
+local function uart_cb(id, len)
+    local data = uart.read(id, len)
+    data = data:byte(1,1)
+    sys.publish("xmodem", data)
+end
+
+--[[
+xmodem 发送文件
+@api xmodem.send(uart_id, uart_br, file_path,type)
+@number uart_id uart端口号
+@number uart_br uart波特率
+@string file_path 文件路径
+@bool type 1k/128 默认1k
+@return bool 发送结果
+@usage
+xmodem.send(2,115200,"/luadb/test.bin")
+]]
+
+function xmodem.send(uart_id, uart_br, file_path,type)
+    local ret, flen, cnt, crc
+
+    if type then
+        HEAD = SOH
+        DATA_SIZE = DATA_SIZE_SOH
+    else
+        HEAD = STX
+        DATA_SIZE = DATA_SIZE_STX
+    end
+    local XMODEM_SIZE = 1+FRAME_ID_SIZE+DATA_SIZE+CRC_SIZE
+    local packsn = 0
+    local xmodem_buff = zbuff.create(XMODEM_SIZE)
+    local data_buff = zbuff.create(DATA_SIZE)
+    local fd = io.open(file_path, "rb")
+    if fd then
+        uart.setup(uart_id,uart_br)
+        uart.on(uart_id, "receive", uart_cb)
+        local result, data = sys.waitUntil("xmodem", 120000)
+        if result and data == CRC_CHR then
+            cnt = 1
+            while true do
+                data_buff:set(0, CTRLZ)
+                ret, flen = fd:fill(data_buff,0,DATA_SIZE)
+                log.info("发送第", cnt, "包")
+                if flen > 0 then
+                    data_buff:seek(0)
+                    crc = crypto.crc16("XMODEM",data_buff)
+                    packsn = (packsn+1) & 0xff
+                    xmodem_buff[0] = 0x02
+                    xmodem_buff[1] = packsn
+                    xmodem_buff[2] = 0xff-xmodem_buff[1]
+                    data_buff:seek(DATA_SIZE)
+                    xmodem_buff:copy(3, data_buff)
+                    xmodem_buff[1027] = crc>>8
+                    xmodem_buff[1028] = crc&0xff
+                    xmodem_buff:seek(XMODEM_SIZE)
+                    log.info(xmodem_buff:used())
+                    :: RESEND ::
+                    uart.tx(uart_id, xmodem_buff)
+                    result, data = sys.waitUntil("xmodem", 10000)
+                    if result and data == ACK then
+                        cnt = cnt + 1
+                    elseif result and data == NAK then
+                        goto RESEND
+                    else
+                        log.info("发送失败")
+                        return false
+                    end
+                    if flen ~= DATA_SIZE then
+                        log.info("文件到头了")
+                        break
+                    end
+                else
+                    log.info("文件到头了")
+                    break
+                end
+            end
+            uart.write(uart_id, string.char(EOT))
+            fd:close()
+            return true
+        else
+            log.info("不支持",data) 
+            return false
+        end
+    else
+        log.info("no file") 
+        return false
+    end
+end
+
+return xmodem