LuatOS核心库API——【ymodem】文件传输协议

在物联网终端开发领域,LuatOS 是不少开发者的常用工具,这款轻量级嵌入式 Lua 脚本运行框架兼实时系统,基于 Lua 5.3 做了深度优化,主要适配 4G-Cat.1、MCU 等物联网终端硬件。它以 Lua 脚本为开发基础,采用协程多任务的设计架构,还配套了完善的开发资源,70 多个核心库、20 多个扩展库,再加上 1000 余个应用 demo 示例,基本能覆盖物联网开发的各类基础场景。

一、概述

Ymodem协议是一种在串行通信(如串口)中使用的​​文件传输协议​​,它由Chuck Forsberg在Xmodem协议的基础上改进而来,核心特点是​​支持批量文件传输​​和​​每帧最多1024字节的数据块​​,相比前身Xmodem的128字节帧,传输效率显著提升。

该协议通过​​CRC-16循环冗余校验​​来检测传输错误,并利用​​ACK(确认)/NAK(否认)握手信号​​实现自动重传机制,从而保证数据传输的可靠性。

Ymodem协议在传输开始时会将​​文件名和文件大小作为元数据​​在起始帧中发送,使得接收方能够预先知晓文件信息,因此尤其适用于嵌入式系统中的​​固件升级(OTA)和Bootloader引导程序​​等场景

二、核心示例

1、核心示例是指:使用本库文件提供的核心API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

3、更加完整和详细的demo,请参考 LuatOS仓库 中各个产品目录下的demo/ymodem

lua 复制代码
-- 根据实际设备选取不同的uartid
local uartid = 1 

--初始化
local result = uart.setup(
    uartid,--串口id
    115200,--波特率
    8,--数据位
    1--停止位
)
local taskName = "ymodem_run"

-- 处理未识别的消息
local function ymodem_run_cb(msg)
    log.info("ymodem_run_cb", msg[1], msg[2], msg[3], msg[4])
end

--  定义一个局部变量,用于表示Ymodem协议是否正在运行
local ymodem_running = false 

--  创建一个缓冲区,大小为1024 + 32
local rxbuff = zbuff.create(1024 + 32) 

--  创建一个ymodem处理程序,保存路径为"/",文件名为"save.bin"
local ymodem_handler = ymodem.create("/","save.bin")

-- --  定义一个ymodem_run函数,用于发送C字符,并重置ymodem处理程序
local function ymodem_run() 
    while true do
        --  如果ymodem协议没有在运行,则发送请求;并重置ymodem处理程序
        if not ymodem_running then 
            --YMODEM 传输文件时,接收方会先发送一个字符 'C'来启动传输过程
            uart.write(uartid, "C")
            --发送完之后重置恢复到初始状态
            ymodem.reset(ymodem_handler) 
        end
        sys.wait(500)
    end
end

--  定义一个ymodem_rx函数,用于接收数据
local function ymodem_rx(id,len) 
    --  从uart接收数据到缓冲区
    while true do
        log.info("uart", "缓冲区", uart.rxSize(id)) -- 缓冲区中的数据数量
        local len = uart.rx(id, rxbuff)
        if len <= 0 then
            break
        end
        log.info("uart", "receive", id, rxbuff:used(), rxbuff:toStr())
    end
    --  打印缓冲区已使用的大小
    log.info(rxbuff:used()) 
    --  调用ymodem.receive函数,接收数据
    local result,ack,flag,file_done,all_done = ymodem.receive(ymodem_handler,rxbuff) 
    ymodem_running = result
    log.info("result:",ymodem_running,ack,flag,file_done,all_done)
    rxbuff:del()
    --成功就发送ack和flag
    if result then
        rxbuff:copy(0, ack,flag)
        uart.tx(id, rxbuff)
    end

    --  所有数据都接收完毕
    if all_done then 
        -- 判断/save.bin文件是否存在
        local exists=io.exists("/save.bin") 

        -- 判断/save.bin文件是否存在,存在则打印日志,显示/save.bin文件大小;不存在则打印日志,显示/save.bin文件不存在
        if exists then
            log.info("io", "save.bin file exists:", exists) 
            --打印文件大小
            log.info("io", "save.bin file size:", io.fileSize("/save.bin")) 
        else
            log.info("io", "save.bin file not exists") 
        end

        --ymodem_running置为false,再次开始接收
        ymodem_running = false 
    end
    rxbuff:del()
end

--  监听串口接收事件
uart.on(uartid, "receive", ymodem_rx) 

local function uart_sent_cb(id)
    log.info("uart", "sent", id) 
end
--  监听串口发送事件
uart.on(uartid, "sent", uart_sent_cb)

--创建并且启动一个task
--运行这个task的主函数ymodem_run
sys.taskInit(ymodem_run, taskName,ymodem_run_cb)

三、常量详解

核心库常量,顾名思义是由合宙LuatOS内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

ymodem核心库没有常量。

四、函数详解

ymodem.create(dir_path,file_path)

功能

创建一个ymodem处理句柄

注意事项

暂无

参数

dir_path

lua 复制代码
含义说明:保存的文件夹路径,默认是"/"路径;
数据类型:string;
取值范围:无特别限制;
是否必选:否;
注意事项:默认是"/"路径;
参数示例:ymodem.create("/")

file_path

lua 复制代码
含义说明:强制保存的文件名,默认是空,如果设置了,就会直接保存在该文件中;
数据类型:string;
取值范围:无特别限制;
是否必选:否;
注意事项:如果不填该参数,文件名默认对端发过来的文件名;
参数示例:ymodem.create("/","save.bin")

返回值

local ymodem_handler = ymodem.create("/","save.bin")

ymodem_handler

lua 复制代码
含义说明:ymodem创建成功返回的对象;
数据类型:userdata;
取值范围:无特别限制;
注意事项:无;

例子

lua 复制代码
local ymodem_handler = ymodem.create("/","save.bin")

ymodem.receive(handler, data)

功能

ymodem接收文件数据并保存

注意事项

暂无

参数

handler

lua 复制代码
含义说明:ymodem创建成功的对象;
数据类型:userdata;
取值范围:无特别限制;
是否必选:必须传入此参数;
注意事项:作为必需参数,若不提供会导致错误;
参数示例:local handler = ymodem.create("/","save.bin")
        ymodem.receive(handler, data)

data

lua 复制代码
含义说明:串口接收的数据;
数据类型:string/zbuff;
取值范围:无特别限制;
是否必选:必须传入此参数;
注意事项:作为必需参数,若不提供会导致错误;
参数示例:local handler = ymodem.create("/","save.bin")
        ymodem.receive(handler, data)

返回值

local result,ack,flag,file_done,all_done = ymodem.receive(handler, data)

result

lua 复制代码
含义说明:保存成功/失败;
数据类型:boolean;
取值范围:true/false;
注意事项:无;

ack

lua 复制代码
含义说明:ack值,需要通过串口/网络等途径返回发送方;
数据类型:number;
取值范围:0-255;
注意事项:无;

flag

lua 复制代码
含义说明:flag值,需要通过串口/网络等途径返回发送方,如果有ack值则不发送flag;
数据类型:number;
取值范围:0-255;
注意事项:无;

file_done

lua 复制代码
含义说明:文件是否接收完成;
数据类型:boolean;
取值范围:true/false 接收完成true,传输中false;
注意事项:无;

all_done

lua 复制代码
含义说明:整个传输是否完成;
数据类型:boolean;
取值范围:true/false 传输完成true,未完成false;
注意事项:无;

例子

lua 复制代码
-- 注意, 数据来源不限, 通常是uart.read得到data
local handler = ymodem.create("/","save.bin")
local result,ack,flag,file_done,all_done = ymodem.receive(handler, data)

ymodem.reset(handler)

功能

重置ymodem处理过程

注意事项

这个操作主要是把状态复位,之前传输过来的数据不会清空,下次传输不需要重新create。

参数 handler

lua 复制代码
含义说明:ymodem创建成功的对象;
数据类型:userdata;
取值范围:无特别限制;
是否必选:必须传入此参数;
注意事项:作为必需参数,若不提供会导致错误;
参数示例:local handler = ymodem.create("/","save.bin")
        ymodem.reset(handler)

返回值

例子

lua 复制代码
-- 恢复到初始状态,一般用于接收出错后重置,从而进行下一次接收
local handler = ymodem.create("/","save.bin")
ymodem.reset(handler)

ymodem.release(handler)

功能

释放ymodem处理句柄

注意事项

暂无

参数 handler

lua 复制代码
含义说明:ymodem创建成功的对象;
数据类型:userdata;
取值范围:无特别限制;
是否必选:必须传入此参数;
注意事项:作为必需参数,若不提供会导致错误;
参数示例:local handler = ymodem.create("/","save.bin")
        ymodem.release(handler)

返回值

例子

五、函数详解

支持 LuatOS 开发的8000系列和780EHM、780EGH、780EHV的产品都支持 ymodem 核心库。

今天就分享到这里啦~

相关推荐
MetrixAeroCore9 小时前
自动售货机库存上报异常物联网卡DNS解析失败修复教程
物联网
ANSIOT9 小时前
安朔科技蓝牙无感开锁方案,靠近自动解锁
网络·科技·物联网
微硬创新10 小时前
耐达讯自动化 CC-Link IE 转 PROFINET网关在污水厂智能化升级实战
人工智能·物联网·网络协议·自动化·信息与通信
YCOSA202514 小时前
雨晨 Windows 11 IOT 企业版 LTSC 24H2 轻装 2合1 26100.8968
windows·物联网
乐鑫科技 Espressif14 小时前
用 AI 开发 Zephyr-IoT 应用
人工智能·物联网·esp32·乐鑫科技·zephyr
国科安芯16 小时前
星间光链路:AS32S601型抗辐射MCU在空间激光通信终端控制中的技术实现
服务器·网络·单片机·嵌入式硬件·物联网·安全·信息与通信
慧都小妮子17 小时前
ThingsBoard PE 智慧能源:打造企业数字化能源管理平台
运维·物联网·能源·数据采集·数据可视化·thingsboard·制造业数字化
振浩微433射频芯片18 小时前
工业遥控器总在关键时刻“掉链子”?——433MHz芯片方案如何破局
网络·单片机·嵌入式硬件·物联网·工业遥控
2601_9545267519 小时前
【硬核架构】打破 IT 与 OT 的数据孤岛!基于 Rust 异步协程的工业 IoT 网关重构,兼谈顶级自动化智能仪表厂家选型指南
物联网·架构·rust
厦门辰迈智慧科技20 小时前
露天矿山高边坡综合监测与预警体系解决方案
物联网·矿山监测·矿山高边坡监测·露天矿山监测