跳转至

libfota - libfota fota升级

作者:孟伟

一、概述

FOTA远程升级功能是物联网设备的核心功能之一,它允许设备通过无线网络更新固件,而无需物理接触。在LuatOS开发模式下,固件分为两部分:core(底层核心固件)和script(用户脚本)。远程升级时,core采用差分升级方式,而 script 则采用全量覆盖升级方式。您可以选择仅升级script、仅升级core或同时升级core+script。

LuatOS主要提供了两套FOTA接口:传统的libfota和更新的libfota2,两者都支持通过合宙官方IoT平台和自建第三方HTTP服务器进行升级

需要注意的是第三方http服务器需要满足如下两点:
-- 若需要升级, 响应http 200, body为升级文件的内容
-- 若不需要升级, 响应300或以上的代码,务必注意

为了更清晰地了解这两个库的特点,下表对比了它们的主要特性。

区别项 libfota2 libfota
参数传递方式 使用opts表传递参数,结构清晰,可选参数管理方便 参数通过一长串顺序参数传递,必须按顺序填写,可选参数处理不够灵活
使用便捷性 较高。接口设计更现代,只需关注关键配置,简化了使用流程。 相对较低。需要关注较多参数,配置稍显繁琐。
功能特性 支持合宙IoT平台和自建服务器,定时升级,回调函数提供详细状态码。 同样支持合宙IoT平台和自建服务器,定时升级,回调函数提供状态码
推荐使用场景 新项目,或希望代码更清晰、易维护的项目。 旧项目维护,或对早期库有依赖的项目。

libfota是LuatOS提供的初始版FOTA接口,它需要传递比较多参数,相比ibfota2库使用起来相对复杂。对于新开发的LuatOS项目,建议优先选择libfota2来实现远程升级功能点击此处了解libfota2

二、核心示例

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

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

3、如果是新项目不建议使用此接口,建议使用libfota2仓库接口。

--注意:因使用了sys.wait(),所以api需要在协程中使用
--用法实例
local libfota = require("libfota")

-- 功能:升级包下载结果回调函数,用于返回升级包下载结果
-- 参数:
-- result:number类型
--        0表示成功
--        1表示连接失败
--        2表示url错误
--        3表示服务器断开
--        4表示接收报文错误
--        5表示使用iot平台VERSION需要使用 xxx.yyy.zzz形式
function libfota_cb(result)
    log.info("fota", "result", result)
    -- fota成功
    if result == 0 then
        rtos.reboot()   --如果还有其他事情要做,就不要立刻reboot
    end
end

--注意!!!:使用合宙iot平台,必须用luatools量产生成的.bin文件!!! 自建服务器可使用.ota文件!!!
--注意!!!:使用合宙iot平台,必须用luatools量产生成的.bin文件!!! 自建服务器可使用.ota文件!!!
--注意!!!:使用合宙iot平台,必须用luatools量产生成的.bin文件!!! 自建服务器可使用.ota文件!!!

--下方示例为合宙iot平台,地址:http://iot.openluat.com
libfota.request(libfota_cb)
-- 4个小时检查一次升级
sys.timerLoopStart(libfota.request, 4*3600*1000, libfota_cb)

三、常量详解

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

libfota核心库没有常量。

四、函数详解

libfota.request(cbFnc,ota_url,storge_location, len, param1,ota_port,libfota_timeout,server_cert, client_cert, client_key, client_password,show_otaurl)

功能

fota升级

参数

cbFnc

参数含义:升级包下载结果回调函数,用于返回升级包下载结果。回调函数的调用形式为:cbFnc(result)
         result:number类型
                0表示成功;
                1表示连接失败;
                2表示url错误
                3表示服务器断开;
                4表示接收报文错误;
                5表示使用iot平台VERSION需要使用 xxx.yyy.zzz形式
数据类型:function类型
取值范围:任意有效的函数名都行;
是否必选:必须传入此参数;
注意事项:暂无;
参数示例:如下方所示,定义了一个函数fota_cb就可以做为此参数传入
         local function fota_cb(result)
             log.info("fota", result)
             if result == 0 then
                 log.info("升级包下载成功,重启模块")
                 rtos.reboot()
             elseif result == 1 then
                 log.info("连接失败", "请检查url拼写或服务器配置(是否为内网)")
             elseif result == 2 then
                 log.info("url错误", "检查url拼写")
             elseif result == 3 then
                 log.info("服务器断开", "检查服务器白名单配置")
             elseif result == 4 then
                 log.error("FOTA 失败",
                    "原因可能有:\n" ..
                    "1) 服务器返回 200/206 但报文体为空(0 字节)—— 通常是升级包文件缺失或 URL 指向空文  件;\n" ..
                    "2) 服务器返回 4xx/5xx 等异常状态码 —— 请确认升级包已上传、URL 正确、鉴权信息有 效;\n"..
                    "3) 已经是最新版本,无需升级" )
             elseif result == 5 then
                 log.info("版本号书写错误", "iot平台版本号需要使用xxx.yyy.zzz形式")
             else
                 log.info("不是上面几种情况 result为", result)
             end
         end
ota_url

参数含义:升级URL,用于指定FOTA升级的服务器地址
数据类型:string类型
取值范围:任意有效的URL字符串
是否必选:否,不填的话默认是合宙iot平台
注意事项:暂无
参数示例:"http://xxxxxx.com/xxx/upgrade?version=" .. _G.VERSION

storge_location

参数含义:ota数据存储的起始位置
数据类型:nil,由底层决定存储位置
取值范围:无特别限制
是否必选:可选传入此参数
注意事项:暂无
参数示例:nil
len
参数含义:数据存储的最大空间
数据类型:不需要特别控制,由底层决定
取值范围:无特别限制
是否必选:可选传入此参数
注意事项:暂无
参数示例:nil
param1
参数含义:如果数据存储在spiflash时,spi_device
数据类型:userdata类型,不需要特别控制,由底层决定
取值范围:无特别限制
是否必选:可选传入此参数
注意事项:暂无
参数示例:nil
ota_port
参数含义:请求端口,默认80
数据类型:number类型
取值范围:无特别限制
是否必选:可选传入此参数
注意事项:暂无
参数示例:80
libfota_timeout
参数含义:请求超时时间,单位毫秒,默认30000毫秒
数据类型:number类型
取值范围:无特别限制
是否必选:可选传入此参数
注意事项:暂无
参数示例:30000,表示超时时间30s
server_cert
参数含义:服务器ca证书数据
数据类型:string或者nil
取值范围:无特别限制;
是否必选:可选传入此参数;
注意事项:当客户端需要验证服务器证书时,需要此参数,如果证书数据在一个文件中,要把文件内容读出来,赋值给server_ca_cert
参数示例:例如通过Luatools烧录了server_ca.crt文件,就可以通过io.readFile("/luadb/server_ca.crt")读出文件内容赋值给赋值给server_ca_cert
client_cert
参数含义:客户端证书数据;
数据类型:string或者nil
取值范围:无特别限制;
是否必选:可选传入此参数;
注意事项:当服务器需要验证客户端证书时,需要此参数,如果证书数据在一个文件中,要把文件内容读出来,赋值给client_cert
参数示例:例如通过Luatools烧录了clinet.crt文件,就可以通过io.readFile("/luadb/clinet.crt")读出文件内容赋值给赋值给client_cert
client_key
参数含义:加密后的客户端私钥数据;
数据类型:string或者nil
取值范围:无特别限制;
是否必选:可选传入此参数;
注意事项:当服务器需要验证客户端证书时,需要此参数,如果加密后的私钥数据在一个文件中,要把文件内容读出来,赋值给client_key
参数示例:例如通过Luatools烧录了clinet.key文件,就可以通过io.readFile("/luadb/clinet.key")读出文件内容赋值给client.key
client_password
参数含义:客户端私钥口令数据;
数据类型:string或者nil
取值范围:无特别限制;
是否必选:可选传入此参数;
注意事项:当服务器需要验证客户端证书时,需要此参数,如果加密后的私钥数据在一个文件中,要把文件内容读出来,赋值给client_password
参数示例:例如通过Luatools烧录了clinet.password文件,就可以通过io.readFile("/luadb/clinet.password")读出文件内容赋值给client_password
show_otaurl
参数含义:是否从日志中输出打印OTA升级包的URL路径,默认会打印
数据类型:boolean类型
取值范围:true或false
是否必选:可选传入此参数
注意事项:暂无
参数示例:false

返回值

示例

使用合宙iot服务器升级示例

--注意:因使用了sys.wait(),所以api需要在协程中使用
--用法实例
local libfota = require("libfota")

-- 功能:升级包下载结果回调函数,用于返回升级包下载结果
-- 参数:
-- result:number类型
--   0表示成功
--   1表示连接失败
--   2表示url错误
--   3表示服务器断开
--   4表示接收报文错误
--   5表示使用iot平台VERSION需要使用 xxx.yyy.zzz形式
function libfota_cb(result)
    log.info("fota", "result", result)
    -- fota成功
    if result == 0 then
        rtos.reboot()   --如果还有其他事情要做,就不要立刻reboot
    end
end

--注意!!!:使用合宙iot平台,必须用luatools量产生成的.bin文件!!! 自建服务器可使用.ota文件!!!
--注意!!!:使用合宙iot平台,必须用luatools量产生成的.bin文件!!! 自建服务器可使用.ota文件!!!
--注意!!!:使用合宙iot平台,必须用luatools量产生成的.bin文件!!! 自建服务器可使用.ota文件!!!

--下方示例为合宙iot平台,地址:http://iot.openluat.com
libfota.request(libfota_cb)
-- 4个小时检查一次升级
sys.timerLoopStart(libfota.request, 4*3600*1000, libfota_cb)
使用自建服务器升级示例

--注意:因使用了sys.wait(),所以api需要在协程中使用
--用法实例
local libfota = require("libfota")

-- 功能:升级包下载结果回调函数,用于返回升级包下载结果
-- 参数:
-- result:number类型
--   0表示成功
--   1表示连接失败
--   2表示url错误
--   3表示服务器断开
--   4表示接收报文错误
--   5表示使用iot平台VERSION需要使用 xxx.yyy.zzz形式
function libfota_cb(result)
    log.info("fota", "result", result)
    -- fota成功
    if result == 0 then
        rtos.reboot()   --如果还有其他事情要做,就不要立刻reboot
    end
end

-- 如使用自建服务器,自行更换url
-- 对自定义服务器的要求是:
-- 若需要升级, 响应http 200, body为升级文件的内容
-- 若不需要升级, 响应300或以上的代码,务必注意
libfota.request(libfota_cb,"http://xxxxxx.com/xxx/upgrade?version=" .. _G.VERSION)

-- 自建平台
sys.timerLoopStart(libfota.request, 4*3600*1000, libfota_cb, "http://xxxxxx.com/xxx/upgrade?version=" .. _G.VERSION)

五、产品支持说明

支持LuatOS开发的所有产品都支持libfota扩展库。