跳转至

Netdrv

作者:魏健强 | 最后修改:2026-04-30

一、概述

netdrv 是指网络设备,用于初始化并管理不同的网络设备。如:4G,以太网,WIFI。还可以提供路由功能.把各种联网方式融合起来,如:4G 连接外部网络,支持以太网 lan 模式为其他以太网设备提供接入。exnetif 扩展库对 netdrv 做了进一步封装可以查看详细的 api 文档;

  1. 支持指定任意一个 netdrv 作为外网访问的出口,使用本文的 netdrv 和 exnetif 扩展库的流程对比,推荐使用 exnetif 扩展库实现,使用更简单

如:通过以太网访问外网时,使用 netdrv 和 exnetif 的流程参考下图

  1. 支持设置路由功能,如:4G 连接外部网络,支持以太网 lan 模式为其他以太网设备提供接入,使用本文的 netdrv 和 exnetif 扩展库的流程对比,推荐使用 exnetif 扩展库实现,使用更简单

  1. 本文中提到的网卡、网络适配器,网络设备,均为同一概念,如:"4G 网卡"等同于"4G 网络适配器"。

二、准备硬件环境

1、Air8101 核心板

2、AirETH_1000 配件板

3、公对母的杜邦线 11 根(连接核心板和配件板)

4、网线 1 根(一端接配件板,一端接路由器)

必选 AirETH_1000 配件板一块,Air8101 核心板和 AirETH_1000 配件板的硬件接线方式为:

Air8101核心板
AirETH_1000配件板
59/3V3
3.3v
gnd
gnd
28/DCLK
SCK
54/DISP
CSS
55/HSYN
SDO
57/DE
SDI
14/GPIO8
INT

2、网线接线说明:

  • netdrv_eth_wan 模块以太网口接路由器 LAN 口或交换机
  • netdrv_eth_lan 模块以太网口接电脑或需要上网的设备
  • netdrv_wifi_multiple 模块以太网口接电脑或需要上网的设备
  • netdrv_eth_multiple 模块以太网口接路由器 LAN 口或交换机

3、TYPE-C USB 数据线一根 Air8101 核心板和数据线的硬件接线方式为:

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

三、准备软件环境

3.1 文章内容应用

1.烧录工具:Luatools 工具

2.本demo开发测试时使用的固件为Air8101 V1006 版本固件,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;

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

LuatOS 运行所需要的 lib 文件:使用 Luatools 烧录时,勾选 添加默认 lib 选项,使用默认 lib 脚本文件。

准备好软件环境之后,接下来查看 Air8101 核心板使用说明将本篇文章中演示使用的项目文件烧录到 Air8101 核心板中。

3.2 API 介绍

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

四、实现功能概述、

1、main.lua:主程序入口;

2、netdrv_eth_wan.lua:以太网 wan

3、netdrv_eth_lan.lua:以太网 lan

4、netdrv_eth_multiple.lua:以太网连接外部网络,生成 WiFi 热点为 WiFi 终端设备提供接入

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

4.1 运行流程图

参考第一章节中的流程图

4.2 代码示例

netdrv_wifi_multiple.lua

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

直接使用Air8101核心板+以太网扩展板硬件测试即可;

本文件没有对外接口,直接在其他功能模块中require "netdrv_wifi_multiple"就可以加载运行;
]] 

dhcpsrv = require "dhcpsrv"
dnsproxy = require "dnsproxy"

local eth_adapter = socket.LWIP_USER1 -- 以太网网卡适配器编号
wlan.init()

local function eth_lan_setup()
    -- 使用8101核心板+AirETH以太网扩展板测试
    log.info("ch390", "打开LDO供电")
    gpio.setup(13, 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设备,
    -- eth_adapter 网络适配器编号
    -- netdrv.CH390外挂CH390
    -- SPI ID 1, 片选 GPIO12
    netdrv.setup(eth_adapter, netdrv.CH390, {
        spi = 0,
        cs = 15,
        irq = 8
    })
end
-- 确保ch390初始化完成,否则会出现netdrv.ipv4设置失败的情况
sys.wait(1000)
-- 设置ip, 子网掩码,网关
local ipv4, mark, gw = netdrv.ipv4(eth_adapter, "192.168.4.1", "255.255.255.0", "192.168.4.1")
log.info("ipv4", ipv4, mark, gw)
-- 开启dhcp服务器
dhcpsrv.create({
    adapter = eth_adapter
})
-- 设置dns转发
dnsproxy.setup(eth_adapter, socket.LWIP_STA)

local function wifi_sta_ap_setup()
    log.info("执行AP创建操作")
    wlan.createAP("test2", "HZ88888888")
    -- 设置ip, 子网掩码,网关
    local ipv4, mark, gw = netdrv.ipv4(socket.LWIP_AP, "192.168.5.1", "255.255.255.0", "192.168.5.1")
    log.info("LWIP_AP", ipv4, mark, gw)
    -- 详细的版本
    -- 创建一个dhcp服务器
    local dhcpsrv_opts = {
        adapter = socket.LWIP_AP, -- 监听哪个网卡, 必须填写
        mark = {255, 255, 255, 0}, -- 网络掩码, 默认 255.255.255.0
        gw = {192, 168, 5, 1}, -- 网关, 默认自动获取网卡IP,如果获取失败则使用 192.168.4.1
        ip_start = 100, -- ip起始地址, 默认100
        ip_end = 200, -- ip结束地址, 默认200
        ack_cb = function(ip, mac)
            log.info("ack_cb", "new client", ip, mac)
        end -- ack回调, 有客户端连接上来时触发, ip和mac地址会传进来
    }
    -- 开启dhcp服务器
    dhcpsrv.create(dhcpsrv_opts)
    -- 设置dns转发
    dnsproxy.setup(socket.LWIP_AP, socket.LWIP_STA)
end

local function netdrv_multiple_task_func()
    -- 设置wifi工作模式为STA+AP模式
    wlan.setMode(wlan.STATIONAP)
    -- 连接wifi
    wlan.connect("茶室-降功耗,找合宙!", "Air123456")
    -- 等待wifi_sta网络连接成功
    while not socket.adapter(socket.LWIP_STA) do
        -- 在此处阻塞等待wifi连接成功的消息"IP_READY"
        -- 或者等待1秒超时退出阻塞等待状态;
        -- 注意:此处的1000毫秒超时不要修改的更长;
        sys.waitUntil("IP_READY", 1000)
    end
    -- 开启wifi->以太网的多网融合
    eth_lan_setup()
    -- 开启wifi sta->ap的多网融合
    wifi_sta_ap_setup()
    -- 设置wifi_sta为数据出口
    netdrv.napt(socket.LWIP_STA)
end

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

netdrv_eth_wan.lua

--[[
@module  netdrv_eth_wan
@summary 以太网卡驱动模块 
@version 1.0
@date    2025.10.20
@author  魏健强
@usage
本文件为以太网卡驱动模块 ,核心业务逻辑为:
1、开启以太网wan;

直接使用Air8101核心板+以太网扩展板硬件测试即可;

本文件没有对外接口,直接在其他功能模块中require "netdrv_eth_wan"就可以加载运行;
]] 

local static_ip = false
local eth_adapter = socket.LWIP_USER1 -- 以太网网卡适配器编号
local function ip_ready_func(ip, adapter)
    log.info("netdrv_eth_wan.ip_ready_func", "IP_READY", socket.localIP(eth_adapter))
end

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

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

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

-- 此处订阅"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()
    -- 使用8101核心板+AirETH以太网扩展板测试
    log.info("ch390", "打开LDO供电")
    gpio.setup(13, 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设备,
    -- eth_adapter 网络适配器编号
    -- netdrv.CH390外挂CH390
    -- SPI ID 1, 片选 GPIO12
    netdrv.setup(eth_adapter, netdrv.CH390, {
        spi = 0,
        cs = 15,
        irq = 8
    })
end

sys.wait(1000) -- 等待以太网模块初始化完成,去掉会导致以太网初始化失败
if static_ip then
    -- 静态ip配置
    log.info("静态ip", netdrv.ipv4(eth_adapter, "192.168.4.100", "255.255.255.0", "192.168.4.1"))
else
    -- 使用dhcp动态获取ip地址
    netdrv.dhcp(eth_adapter, true)
end
log.info("LWIP_ETH", "mac addr", netdrv.mac(eth_adapter))

local function http_test()
    -- sys.waitUntil("IP_READY")
    while 1 do
        sys.wait(6000)
        log.info("http", http.request("GET", "http://httpbin.air32.cn/bytes/4096", nil, nil, {
            adapter = eth_adapter
        }).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 多网卡(WIFI STA网卡、通过SPI外挂CH390H芯片的以太网卡)驱动模块 
@version 1.0
@date    2025.10.20
@author  魏健强
@usage
本文件为多网卡驱动模块 ,核心业务逻辑为:
1、以太网连接外部网络,生成WiFi热点为WiFi终端设备提供接入 ;

直接使用Air8101核心板+以太网扩展板硬件测试即可;

本文件没有对外接口,直接在其他功能模块中require "netdrv_eth_multiple"就可以加载运行;
]] 

dhcpsrv = require "dhcpsrv"
dnsproxy = require "dnsproxy"

local static_ip = false
local eth_adapter = socket.LWIP_USER1 -- 以太网网卡适配器编号

local function netdrv_multiple_task_func()
    -- 使用8101核心板+AirETH以太网扩展板测试
    log.info("ch390", "打开LDO供电")
    gpio.setup(13, 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设备,
    -- eth_adapter 网络适配器编号
    -- netdrv.CH390外挂CH390
    -- SPI ID 1, 片选 GPIO15,中断引脚使用GPIO8
    netdrv.setup(eth_adapter, netdrv.CH390, {
        spi = 0,
        cs = 15,
        irq = 8
    })
    sys.wait(1000) -- 等待以太网模块初始化完成,去掉会导致以太网初始化失败
    if static_ip then
        -- 静态ip配置
        log.info("静态ip", netdrv.ipv4(eth_adapter, "192.168.4.100", "255.255.255.0", "192.168.4.1"))
    else
        -- 使用dhcp动态获取ip地址
        netdrv.dhcp(eth_adapter, true)
    end

    log.info("LWIP_ETH", "mac addr", netdrv.mac(eth_adapter))
    wlan.init()
    -- 等待eth_wan网络连接成功
    while not socket.adapter(eth_adapter) do
        -- 在此处阻塞等待wifi连接成功的消息"IP_READY"
        -- 或者等待1秒超时退出阻塞等待状态;
        -- 注意:此处的1000毫秒超时不要修改的更长;
        sys.waitUntil("IP_READY", 1000)
    end
    -- eth_wan -> wifi_ap
    log.info("执行AP创建操作")
    -- 开启wifi_ap热点
    wlan.createAP("test2", "HZ88888888")
    -- 设置ip, 子网掩码,网关
    local ipv4, mark, gw = netdrv.ipv4(socket.LWIP_AP, "192.168.5.1", "255.255.255.0", "192.168.5.1")
    log.info("LWIP_AP", ipv4, mark, gw)
    while netdrv.ready(socket.LWIP_AP) ~= true do
        sys.wait(100)
    end
    -- 设置dns转发
    dnsproxy.setup(socket.LWIP_AP, eth_adapter)
    -- 详细的版本
    -- 创建一个dhcp服务器
    local dhcpsrv_opts = {
        adapter = socket.LWIP_AP, -- 监听哪个网卡, 必须填写
        mark = {255, 255, 255, 0}, -- 网络掩码, 默认 255.255.255.0
        gw = {192, 168, 5, 1}, -- 网关, 默认自动获取网卡IP,如果获取失败则使用 192.168.4.1
        ip_start = 100, -- ip起始地址, 默认100
        ip_end = 200, -- ip结束地址, 默认200
        ack_cb = function(ip, mac)
            log.info("ack_cb", "new client", ip, mac)
        end -- ack回调, 有客户端连接上来时触发, ip和mac地址会传进来
    }
    dhcpsrv.create(dhcpsrv_opts)
    -- 设置以太网为数据出口
    netdrv.napt(eth_adapter)
end

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

netdrv_eth_lan.lua

--[[
@module  netdrv_eth_lan
@summary 以太网卡驱动模块 
@version 1.0
@date    2025.10.20
@author  魏健强
@usage
本文件为以太网卡驱动模块 ,核心业务逻辑为:
1、开启以太网lan;

直接使用Air8101核心板+以太网扩展板硬件测试即可;

本文件没有对外接口,直接在其他功能模块中require "netdrv_eth_lan"就可以加载运行;
]] 

dhcps = require "dhcpsrv"

local eth_adapter = socket.LWIP_USER1 -- 以太网网卡适配器编号
local function eth_lan_setup()
    -- 使用8101核心板+AirETH以太网扩展板测试
    log.info("ch390", "打开LDO供电")
    gpio.setup(13, 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设备,
    -- eth_adapter 网络适配器编号
    -- netdrv.CH390外挂CH390
    -- SPI ID 1, 片选 GPIO12,中断引脚使用GPIO8
    netdrv.setup(eth_adapter, netdrv.CH390, {
        spi = 0,
        cs = 15,
        irq = 8
    })
end
-- 确保ch390初始化完成,否则会出现netdrv.ipv4设置失败的情况
sys.wait(1000)
-- 设置ip, 子网掩码,网关
local ipv4, mark, gw = netdrv.ipv4(eth_adapter, "192.168.4.1", "255.255.255.0", "192.168.4.1")
log.info("ipv4", ipv4, mark, gw)
-- 开启dhcp服务器
dhcps.create({
    adapter = eth_adapter
})

sys.taskInit(eth_lan_setup)

main.lua

--[[
@module  main
@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑 
@version 1.0
@date    2025.10.20
@author  魏健强
@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这三位数字必须存在,但是没有任何用处,可以一直写为999
        如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
]]
PROJECT = "netdrv"
VERSION = "001.999.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"
-- 以太网连接外部网络,生成WiFi热点为WiFi终端设备提供接入 
-- require "netdrv_eth_multiple"
-- WIFI连接外部网络,支持以太网lan模式为其他以太网设备提供接入,支持生成WiFi热点为WiFi终端设备提供接入
-- require "netdrv_wifi_multiple"

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

五、功能演示

  • 如果需要开启以太网 lan,打开 require "netdrv_eth_lan",其余注释掉

模块以太网接口接其他设备,这里演示使用电脑连接,可以 dhcp 获取 ip,可以 ping 通模块

  • 如果需要开启以太网 wan,打开 require "netdrv_eth_wan",其余注释掉 模块以太网口接路由器,模块成功联网并 http 请求成功
  • 如果需要开启以太网转 wifi 的多网融合,打开 require "netdrv_eth_multiple.lua",其余注释掉

模块以太网口接路由器 LAN 口,并开启 wifi_ap 热点,这里使用电脑连接模块发出的热点,dhcp 获取到 ip,测试网络正常

  • 如果需要开启 wifi 转以太网、wifi_ap 的多网融合,打开 require "netdrv_wifi_multiple",其余注释掉

模块连接路由器 wifi,并开启以太网 LAN 口,这里使用电脑连接模块以太网接口,测试网络正常

六、总结

至此,使用 netdrv+dnsproxy+dhcpsrv 演示的单网卡初始化和多网融合的功能已经结束。如果大家在实际操作中遇到技术难题,欢迎联系合宙技术人员。