Air780EPM多网融合功能实现教程(netdrv)/开发指南/开发手册

一、概述

Air780EPM 支持 4G、以太网通信,在低功耗模式下,功耗约在 1.5~2mA,PSM + 模式下,功耗低至 3~12uA。netdrv 是用于初始化和管理网络设备的核心库,可适配 Air780EPM 等硬件的 4G、以太网、WiFi 等多种联网方式,实现网络设备的统一管理,并提供路由功能,能将不同联网方式深度融合(如 4G 连接外部网络、以太网 LAN 模式为其他设备提供网络接入);exnetif 扩展库对 netdrv 进行了进一步封装,简化了网络功能开发流程,推荐优先使用 exnetif 实现网络相关功能,详细 API 可查阅对应文档。

二、准备硬件环境

  • 所需硬件:

    • Air780EPM V1.3 开发板一块。

    • TYPE-C USB 数据线一根。

    • 可上网的 SIM 卡一张。

    • 4G 天线一根。

    • 网线一根。

    • sim 卡插入开发板的 sim 卡槽

    • 天线装到开发板上

2、网线接线说明:

  • netdrv_eth_wan 模块以太网口接路由器 LAN 口或交换机

  • netdrv_eth_lan 模块以太网口接电脑或需要上网的设备

  • netdrv_4g_multiple 模块以太网口接电脑或需要上网的设备

  • netdrv_eth_multiple 模块以太网 WAN 接路由器 LAN 口或交换机,AirETH_1000 配件板 LAN 口接需要上网的设备

  • AirETH_1000 配件板接到开发板上 可以用电脑接 AirETH_1000 配件板网口

3、 TYPE-C USB 数据线直接插到核心板的 TYPE-C USB 座子,另外一端连接电脑 USB 口;

三、准备软件环境

3.1 文章内容应用

  1. 烧录工具:Luatools 工具

    1. 所需固件和脚本:

内核固件:Air780EPM V2016 版本固件((建议使用 2025 年 10 月 24 日后发布的固件))

脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air780EPM/demo/netdrv

  • LuatOS 库文件:烧录时勾选“添加默认 lib”选项。

3.2 API 介绍

本文仅介绍程序中使用到的 API 接口,详细接口说明请查看:netdrv 核心库

四、实现功能概述

  • 主要文件:

    • main.lua:主程序入口。

    • netdrv_eth_wan.lua:以太网 WAN 功能实现。

    • netdrv_eth_lan.lua:以太网 LAN 功能实现。

    • netdrv_4g_multiple.lua:4G 连接外部网络,生成 WiFi 热点为 WiFi 终端设备提供接入,支持以太网 lan 模式为其他以太网设备提供接入

    • netdrv_eth_multiple.lua:以太网连接外部网络,并提供 WiFi 热点。

4.1 运行流程

  1. 初始化网络设备(如以太网或 4G)。

  2. 配置 IP 地址(动态 DHCP 或静态 IP)。

  3. 设置 DNS 和路由。

  4. 处理网络事件(如 IP_READY 和 IP_LOSE)。

  5. 实现附加功能(如 ping 测试)。

4.2 代码示例分析:netdrv_eth_wan.lua

--[[
@module  netdrv_eth_wan
@summary “通过SPI外挂CH390H芯片的以太网卡”驱动模块 
@version 1.0
@date    2025.10.20
@usage
本文件为“通过SPI外挂CH390H芯片的以太网卡”驱动模块 ,核心业务逻辑为:
1、开启以太网wan;

直接使用Air780EPM V1.3开发板硬件测试即可;

本文件没有对外接口,直接在其他功能模块中require "netdrv_eth_wan"就可以加载运行;
]] 
local static_ip = falselocal function ip_ready_func(ip, adapter)if adapter == socket.LWIP_ETH then
        -- 在位置1和2设置自定义的DNS服务器ip地址:
        -- "223.5.5.5",这个DNS服务器IP地址是阿里云提供的DNS服务器IP地址;
        -- "114.114.114.114",这个DNS服务器IP地址是国内通用的DNS服务器IP地址;
        -- 可以加上以下两行代码,在自动获取的DNS服务器工作不稳定的情况下,这两个新增的DNS服务器会使DNS服务更加稳定可靠;
        -- 如果使用专网卡,不要使用这两行代码;
        -- 如果使用国外的网络,不要使用这两行代码;
        socket.setDNS(adapter, 1, "223.5.5.5")
        socket.setDNS(adapter, 2, "114.114.114.114")

        log.info("netdrv_eth_wan.ip_ready_func", "IP_READY", socket.localIP(socket.LWIP_ETH))
    end
end

local function ip_lose_func(adapter)if adapter == socket.LWIP_ETH then
        log.warn("netdrv_eth_wan.ip_lose_func", "IP_LOSE")
    end
end

-- 本功能在2025.9.3新增
local function ping_test()
    -- 要等联网了才能ping
    sys.waitUntil("IP_READY")while true do
        -- 必须指定使用哪个网卡
        netdrv.ping(socket.LWIP_ETH, "112.125.89.8")
        sys.waitUntil("PING_RESULT", 3000)
        sys.wait(3000)
    end
end
local function ping_res(id, time, dst)
    log.info("ping", id, time, dst); -- 获取到响应结果
end

-- 以太网联网成功(成功连接路由器,并且获取到了IP地址)后,内核固件会产生一个"IP_READY"消息
-- 各个功能模块可以订阅"IP_READY"消息实时处理以太网联网成功的事件
-- 也可以在任何时刻调用socket.adapter(socket.LWIP_ETH)来获取以太网是否连接成功

-- 以太网断网后,内核固件会产生一个"IP_LOSE"消息
-- 各个功能模块可以订阅"IP_LOSE"消息实时处理以太网断网的事件
-- 也可以在任何时刻调用socket.adapter(socket.LWIP_ETH)来获取以太网是否连接成功

-- 此处订阅"IP_READY"和"IP_LOSE"两种消息
-- 在消息的处理函数中,仅仅打印了一些信息,便于实时观察“通过SPI外挂CH390H芯片的以太网卡”的连接状态
-- 也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
sys.subscribe("IP_READY", ip_ready_func)
sys.subscribe("IP_LOSE", ip_lose_func)local function eth_wan_setup()
    -- 本demo使用Air8000开发板测试,开发板上的硬件配置为:
    -- GPIO140为CH390H以太网芯片的供电使能控制引脚
    -- 使用spi1,片选引脚使用GPIO12
    -- 如果使用的硬件不是Air8000开发板,根据自己的硬件配置修改以下参数
    log.info("ch390", "打开LDO供电")
    gpio.setup(20, 1, gpio.PULLUP) -- 打开ch390供电
    local result = spi.setup(0, -- spi_id
    nil, 0, -- CPHA
    0, -- CPOL
    8, -- 数据宽度
    25600000 -- ,--频率
    -- spi.MSB,--高低位顺序    可选,默认高位在前
    -- spi.master,--主模式     可选,默认主
    -- spi.full--全双工       可选,默认全双工
    )
    log.info("main", "open", result)if result ~= 0 then -- 返回值为0,表示打开成功
        log.info("main", "spi open error", result)return
    end
    -- 初始化指定netdrv设备,
    -- socket.LWIP_ETH 网络适配器编号
    -- netdrv.CH390外挂CH390
    -- SPI ID 1, 片选 GPIO12
    netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {
        spi = 0,
        cs = 8})
    sys.wait(1000) -- 等待以太网模块初始化完成,去掉会导致以太网初始化失败
    if static_ip then
        -- 静态ip配置
        log.info("静态ip", netdrv.ipv4(socket.LWIP_ETH, "192.168.4.100", "255.255.255.0", "192.168.4.1"))else
        -- 使用dhcp动态获取ip地址
        netdrv.dhcp(socket.LWIP_ETH, true)
    end
    log.info("LWIP_ETH", "mac addr", netdrv.mac(socket.LWIP_ETH))
    sys.taskInit(ping_test)
    sys.subscribe("PING_RESULT", ping_res)
end

local function http_test()
    -- sys.waitUntil("IP_READY")while true do
        sys.wait(6000)
        log.info("http", http.request("GET", "http://httpbin.air32.cn/bytes/4096", nil, nil, {
            adapter = socket.LWIP_ETH
        }).wait()) -- adapter指定为以太网联网方式
        log.info("lua", rtos.meminfo())
        log.info("sys", rtos.meminfo("sys"))
    end
end
sys.taskInit(eth_wan_setup)
sys.taskInit(http_test)

netdrv_eth_multiple.lua

--[[
@module  netdrv_eth_multiple
@summary 双以太网驱动模块 
@version 1.0
@date    2025.10.20
@usage
本文件为多网卡驱动模块 ,核心业务逻辑为:
1、以太网WAN连接外部网络, 其他需要上网的设备连接模块以太网LAN口上网;

直接使用Air780EPM V1.3开发板硬件测试即可;

本文件没有对外接口,直接在其他功能模块中require "netdrv_eth_multiple"就可以加载运行;
]] 
dhcpsrv = require "dhcpsrv"
dnsproxy = require "dnsproxy"local static_ip = falselocal function eth_wan_setup()
    log.info("ch390", "打开LDO供电")
    gpio.setup(20, 1, gpio.PULLUP) -- 打开ch390供电
    local result = spi.setup(0, -- spi_id
    nil, 0, -- CPHA
    0, -- CPOL
    8, -- 数据宽度
    25600000 -- ,--频率
    -- spi.MSB,--高低位顺序    可选,默认高位在前
    -- spi.master,--主模式     可选,默认主
    -- spi.full--全双工       可选,默认全双工
    )
    log.info("main", "open", result)if result ~= 0 then -- 返回值为0,表示打开成功
        log.info("main", "spi open error", result)return
    end
    -- 初始化指定netdrv设备,
    -- socket.LWIP_ETH 网络适配器编号
    -- netdrv.CH390外挂CH390
    -- SPI ID 1, 片选 GPIO12
    netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {
        spi = 0,
        cs = 8})
    sys.wait(1000) -- 等待以太网模块初始化完成,去掉会导致以太网初始化失败
    if static_ip then
        -- 静态ip配置
        log.info("静态ip", netdrv.ipv4(socket.LWIP_ETH, "192.168.4.100", "255.255.255.0", "192.168.4.1"))else
        -- 使用dhcp动态获取ip地址
        netdrv.dhcp(socket.LWIP_ETH, true)
    end
    log.info("LWIP_ETH", "mac addr", netdrv.mac(socket.LWIP_ETH))
end

local function eth_lan_setup()
    log.info("ch390", "打开LDO供电")
    gpio.setup(21, 1, gpio.PULLUP) -- 打开ch390供电
    local result = spi.setup(1, -- spi_id
    nil, 0, -- CPHA
    0, -- CPOL
    8, -- 数据宽度
    25600000 -- ,--频率
    )
    log.info("main", "open", result)if result ~= 0 then -- 返回值为0,表示打开成功
        log.info("main", "spi open error", result)return
    end

    -- 初始化指定netdrv设备,
    -- socket.LWIP_USER0 网络适配器编号
    -- netdrv.CH390外挂CH390
    -- SPI ID 1, 片选 GPIO12
    netdrv.setup(socket.LWIP_USER0, netdrv.CH390, {
        spi = 1,
        cs = 12})
    -- 确保ch390初始化完成,否则会出现netdrv.ipv4设置失败的情况
    sys.wait(1000)
    -- 设置ip, 子网掩码,网关
    local ipv4, mark, gw = netdrv.ipv4(socket.LWIP_USER0, "192.168.5.1", "255.255.255.0", "192.168.5.1")
    log.info("ipv4", ipv4, mark, gw)
    -- 开启dhcp服务器
    dhcpsrv.create({
        adapter = socket.LWIP_USER0
    })
end

local function netdrv_multiple_task_func()
    eth_wan_setup()
    eth_lan_setup()
    -- 设置dns转发
    dnsproxy.setup(socket.LWIP_USER0, socket.LWIP_ETH)
    -- 设置以太网为数据出口
    netdrv.napt(socket.LWIP_ETH)
end

local function http_test()
    -- sys.waitUntil("IP_READY")while true do
        sys.wait(6000)
        log.info("http", http.request("GET", "http://httpbin.air32.cn/bytes/4096", nil, nil, {
            adapter = socket.LWIP_ETH
        }).wait()) -- adapter指定为以太网联网方式
        log.info("lua", rtos.meminfo())
        log.info("sys", rtos.meminfo("sys"))
    end
end

-- 启动一个task,task的处理函数为netdrv_multiple_task_func
sys.taskInit(netdrv_multiple_task_func)
sys.taskInit(http_test)

netdrv_eth_lan.lua

--[[
@module  netdrv_eth_lan
@summary “通过SPI外挂CH390H芯片的以太网卡”驱动模块 
@version 1.0
@date    2025.10.20
@usage
本文件为“通过SPI外挂CH390H芯片的以太网卡”驱动模块 ,核心业务逻辑为:
1、开启以太网lan;

直接使用Air780EPM V1.3开发板硬件测试即可;

本文件没有对外接口,直接在其他功能模块中require "netdrv_eth_lan"就可以加载运行;
]] 
dhcps = require "dhcpsrv"local function eth_lan_setup()
    -- 本demo使用Air8000开发板测试,开发板上的硬件配置为:
    -- GPIO140为CH390H以太网芯片的供电使能控制引脚
    -- 使用spi1,片选引脚使用GPIO12
    -- 如果使用的硬件不是Air8000开发板,根据自己的硬件配置修改以下参数
    log.info("ch390", "打开LDO供电")
    gpio.setup(20, 1, gpio.PULLUP) -- 打开ch390供电
    local result = spi.setup(0, -- spi_id
    nil, 0, -- CPHA
    0, -- CPOL
    8, -- 数据宽度
    25600000 -- ,--频率
    )
    log.info("main", "open", result)if result ~= 0 then -- 返回值为0,表示打开成功
        log.info("main", "spi open error", result)return
    end

    -- 初始化指定netdrv设备,
    -- socket.LWIP_ETH 网络适配器编号
    -- netdrv.CH390外挂CH390
    -- SPI ID 1, 片选 GPIO12
    netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {
        spi = 0,
        cs = 8})
    -- 确保ch390初始化完成,否则会出现netdrv.ipv4设置失败的情况
    sys.wait(1000)
    -- 设置ip, 子网掩码,网关
    local ipv4, mark, gw = netdrv.ipv4(socket.LWIP_ETH, "192.168.4.1", "255.255.255.0", "192.168.4.1")
    log.info("ipv4", ipv4, mark, gw)
    -- 开启dhcp服务器
    dhcps.create({
        adapter = socket.LWIP_ETH
    })
end

sys.taskInit(eth_lan_setup)

netdrv_4g_multiple.lua

--[[
@module  netdrv_4g_multiple
@summary 多网卡(4G网卡、通过SPI外挂CH390H芯片的以太网卡)驱动模块 
@version 1.0
@date    2025.10.20
@author  魏健强
@usage
本文件为多网卡驱动模块 ,核心业务逻辑为:
1、4G连接外部网络,以太网lan模式为其他以太网设备提供接入 ;

直接使用Air780EPM V1.3开发板硬件测试即可;

本文件没有对外接口,直接在其他功能模块中require "netdrv_4g_multiple"就可以加载运行;
]] 
dhcpsrv = require "dhcpsrv"
dnsproxy = require "dnsproxy"local function lte_eth_setup()
    log.info("ch390", "打开LDO供电")
    gpio.setup(20, 1, gpio.PULLUP) -- 打开ch390供电
    local result = spi.setup(0, -- spi_id
    nil, 0, -- CPHA
    0, -- CPOL
    8, -- 数据宽度
    25600000 -- ,--频率
    )
    log.info("main", "open", result)if result ~= 0 then -- 返回值为0,表示打开成功
        log.info("main", "spi open error", result)return
    end
    -- 初始化指定netdrv设备,
    -- socket.LWIP_ETH 网络适配器编号
    -- netdrv.CH390外挂CH390
    -- SPI ID 1, 片选 GPIO12
    netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {
        spi = 0,
        cs = 8})
    -- 确保ch390初始化完成,否则会出现netdrv.ipv4设置失败的情况
    sys.wait(1000)
    -- 设置ip, 子网掩码,网关
    local ipv4, mark, gw = netdrv.ipv4(socket.LWIP_ETH, "192.168.4.1", "255.255.255.0", "192.168.4.1")
    log.info("LWIP_ETH", ipv4, mark, gw)
    -- 开启dhcp服务器
    dhcpsrv.create({adapter = socket.LWIP_ETH})
    -- 设置dns转发
    dnsproxy.setup(socket.LWIP_ETH, socket.LWIP_GP)
end

local function netdrv_multiple_task_func()
    -- 等待4G网络连接成功
    while not socket.adapter() do
        -- 在此处阻塞等待4G网卡连接成功的消息"IP_READY"
        -- 或者等待1秒超时退出阻塞等待状态;
        -- 注意:此处的1000毫秒超时不要修改的更长;
        sys.waitUntil("IP_READY", 1000)
    end
    -- 开启4G->以太网的多网融合
    lte_eth_setup()
    -- 设置4G为数据出口
    netdrv.napt(socket.LWIP_GP)
end

-- 启动一个task,task的处理函数为netdrv_multiple_task_func
sys.taskInit(netdrv_multiple_task_func)

main.lua

--[[
@module  main
@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑 
@version 1.0
@date    2025.10.20
@usage
本demo演示的核心功能为:
1.开启以太网功能
2.开启多网融合功能
更多说明参考本目录下的readme.md文件
]]
--[[
必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
PROJECT:项目名,ascii string类型
        可以随便定义,只要不使用,就行
VERSION:项目版本号,ascii string类型
        如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
            X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
            因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
]]
PROJECT = "netdrv"
VERSION = "001.000.000"

-- 在日志中打印项目名和项目版本号
log.info("main", PROJECT, VERSION)

-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
if wdt then
    --配置喂狗超时时间为9秒钟
    wdt.init(9000)
    --启动一个循环定时器,每隔3秒钟喂一次狗
    sys.timerLoopStart(wdt.feed, 3000)
end

-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
-- 启动errDump日志存储并且上传功能,600秒上传一次
-- if errDump then
--     errDump.config(true, 600)
-- end

-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
-- 可以使用合宙的iot.openluat.com平台进行远程升级
-- 也可以使用客户自己搭建的平台进行远程升级
-- 远程升级的详细用法,可以参考fota的demo进行使用

-- 启动一个循环定时器
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
-- 方便分析内存使用是否有异常
-- sys.timerLoopStart(function()
--     log.info("mem.lua", rtos.meminfo())
--     log.info("mem.sys", rtos.meminfo("sys"))
-- end, 3000)

-- 开启以太网wan
require "netdrv_eth_wan"
-- 开启以太网lan
-- require "netdrv_eth_lan"
-- 4G连接外部网络,支持以太网lan模式为其他以太网设备提供接入 
-- require "netdrv_4g_multiple"
-- 双网口模式,以太网wan连接外部网络,以太网lan口为其他以太网设备提供接入
-- require "netdrv_eth_multiple"

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

关键点解释:

  • 初始化:使用 netdrv.setup 配置以太网设备(如 CH390 芯片)。

  • IP 配置:支持动态 DHCP 或静态 IP,通过 netdrv.dhcp 或 netdrv.ipv4 实现。

  • DNS 设置:在 IP_READY 事件中自定义 DNS 服务器。

  • 事件处理:订阅 IP_READY 和 IP_LOSE 事件来响应网络状态变化。

  • 附加功能:如 ping 测试,用于网络连通性验证。

五、功能演示

  • 如果需要开启以太网 lan,打开 require “netdrv_eth_lan”,其余注释掉, 模块以太网口接电脑,模块以太网口接电脑,

  • 如果需要开启以太网 wan,打开 require “netdrv_eth_wan”,其余注释掉 模块以太网口接路由器,模块成功联网并 http 请求成功

  • 如果需要开启 4G 转以太网的多网融合,打开 require “netdrv_4g_multiple”,其余注释掉 4G 作为数据出口,需要上网的设备连接模块以太网接口上网

  • 如果需要开启以太网转 wifi 的多网融合,打开 require “netdrv_eth_multiple.lua”,其余注释掉 模块以太网 WAN 接路由器 LAN 口或交换机,电脑连接模块以太网 LAN,DHCP 获取 IP,测试网络正常。

注意:每次仅启用一个功能,其余脚本需注释掉。

六、常见问题

  • IP 获取失败:确认路由器 DHCP 服务正常,或静态 IP 设置无误。

  • 以太网初始化失败:检查 sys.wait(1000) 是否添加

  • 多网融合不通:确认 netdrv.napt() 指向正确的出口网卡

  • DNS 解析失败:检查 dnsproxy.setup() 参数顺序(LAN, WAN) 通过以上步骤,您可以高效实现网络设备管理。如需进一步帮助,请参考 exnetif 扩展库文档或提供具体问题场景。

合宙LuatOS提供一站式物联网高效解决方案,集成高速通信、外设驱动、UI交互及视觉处理,助力行业客户快速落地产品,同时实现极致低功耗一一相较于传统的”串口屏+DTU方案"或安卓方案,功耗减半,成本不足三分之

posted @ 2026-03-13 19:47  合宙LuatOS  阅读(13)  评论(0)    收藏  举报