Просмотр исходного кода

Merge branch 'master' of https://gitee.com/openLuat/LuatOS

梁健 6 месяцев назад
Родитель
Сommit
4aacadca8d

+ 1 - 1
components/multimedia/luat_lib_multimedia_audio.c

@@ -446,7 +446,7 @@ static int l_audio_write_raw(lua_State *L) {
     {
         buf = lua_tolstring(L, 2, &len);//取出字符串数据
     }
-	lua_pushboolean(L, !luat_audio_write_raw(multimedia_id, (uint8_t*)	, len));
+	lua_pushboolean(L, !luat_audio_write_raw(multimedia_id, (uint8_t*)buf, len));
     return 1;
 }
 

+ 4 - 27
components/network/netdrv/src/ch390h_task.c

@@ -170,7 +170,7 @@ static void ch390h_dataout_pbuf(ch390h_t* ch, struct pbuf* p) {
 }
 
 
-static err_t netif_output(struct netif *netif, struct pbuf *p) {
+err_t ch390_netif_output(struct netif *netif, struct pbuf *p) {
     // LLOGD("lwip待发送数据 %p %d", p, p->tot_len);
     ch390h_t* ch = NULL;
 
@@ -189,30 +189,6 @@ static err_t netif_output(struct netif *netif, struct pbuf *p) {
     return 0;
 }
 
-static err_t luat_netif_init(struct netif *netif) {
-    ch390h_t* ch = (ch390h_t*)netif->state;
-    netif->linkoutput = netif_output;
-    netif->output     = luat_netdrv_etharp_output;
-    #if ENABLE_PSIF
-    netif->primary_ipv4_cid = LWIP_PS_INVALID_CID;
-    #endif
-    #if LWIP_IPV6
-    netif->output_ip6 = ethip6_output;
-    #if ENABLE_PSIF
-    netif->primary_ipv6_cid = LWIP_PS_INVALID_CID;
-    #endif
-    #endif
-    netif->mtu        = 1460;
-    netif->flags      = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
-    memcpy(netif->hwaddr, ch->hwaddr, ETH_HWADDR_LEN);
-    netif->hwaddr_len = ETH_HWADDR_LEN;
-    net_lwip2_set_netif(ch->adapter_id, ch->netif);
-    net_lwip2_register_adapter(ch->adapter_id);
-    netif_set_up(ch->netif);
-    ch->status++;
-    LLOGD("luat_netif_init 执行完成 %d", ch->status);
-    return 0;
-}
 
 static void netdrv_netif_input(void* args) {
     netdrv_pkg_msg_t* ptr = (netdrv_pkg_msg_t*)args;
@@ -290,9 +266,10 @@ static int task_loop_one(ch390h_t* ch, luat_ch390h_cstring_t* cs) {
         LLOGD("初始化MAC %02X%02X%02X%02X%02X%02X", buff[0], buff[1], buff[2], buff[3], buff[4], buff[5]);
         // TODO 判断mac是否合法
         memcpy(ch->hwaddr, buff, 6);
-        netif_add(ch->netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4, ch, luat_netif_init, luat_netdrv_netif_input_main);
-        ch->status++;
+        memcpy(ch->netif->hwaddr, buff, 6);
+        ch->status = 2;
         ch->netdrv->dataout = ch390h_dataout;
+        netif_set_up(ch->netif);
         luat_ch390h_basic_config(ch);
         luat_ch390h_set_phy(ch, 1);
         luat_ch390h_set_rx(ch, 1);

+ 41 - 0
components/network/netdrv/src/luat_netdrv_ch390h.c

@@ -18,6 +18,16 @@
 
 ch390h_t* ch390h_drvs[MAX_CH390H_NUM]; // 最多支持5个CH390H同时操作
 
+#ifdef LUAT_USE_NETDRV_LWIP_ARP
+extern err_t luat_netdrv_netif_input_main(struct pbuf *p, struct netif *inp);
+extern err_t luat_netdrv_etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr);
+#else
+#define luat_netdrv_netif_input_main netif_input
+#define luat_netdrv_etharp_output ulwip_etharp_output
+#endif
+
+extern err_t ch390_netif_output(struct netif *netif, struct pbuf *p);
+
 static int ch390h_dhcp(luat_netdrv_t* drv, void* userdata, int enable) {
     ch390h_t* ch = (ch390h_t*)userdata;
     ch->dhcp = (uint8_t)enable;
@@ -50,6 +60,36 @@ static int ch390h_ctrl(luat_netdrv_t* drv, void* userdata, int cmd, void* buff,
     return 0;
 }
 
+
+static err_t ch390_netif_init(struct netif *netif) {
+    ch390h_t* ch = (ch390h_t*)netif->state;
+    netif->linkoutput = ch390_netif_output;
+    netif->output     = luat_netdrv_etharp_output;
+    #if ENABLE_PSIF
+    netif->primary_ipv4_cid = LWIP_PS_INVALID_CID;
+    #endif
+    #if LWIP_IPV6
+    netif->output_ip6 = ethip6_output;
+    #if ENABLE_PSIF
+    netif->primary_ipv6_cid = LWIP_PS_INVALID_CID;
+    #endif
+    #endif
+    netif->mtu        = 1460;
+    netif->flags      = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
+    memcpy(netif->hwaddr, ch->hwaddr, ETH_HWADDR_LEN);
+    netif->hwaddr_len = ETH_HWADDR_LEN;
+    net_lwip2_set_netif(ch->adapter_id, ch->netif);
+    net_lwip2_register_adapter(ch->adapter_id);
+    ch->status = 0;
+    LLOGD("netif init ok %d", ch->adapter_id);
+    return 0;
+}
+
+static void ch390_lwip_init(void* args) {
+    ch390h_t* ch = (ch390h_t*)args;
+    netif_add(ch->netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4, ch, ch390_netif_init, luat_netdrv_netif_input_main);
+}
+
 luat_netdrv_t* luat_netdrv_ch390h_setup(luat_netdrv_conf_t *cfg) {
     
     LLOGD("注册CH390H设备 SPI id %d cs %d irq %d", cfg->spiid, cfg->cspin, cfg->irqpin);
@@ -98,6 +138,7 @@ luat_netdrv_t* luat_netdrv_ch390h_setup(luat_netdrv_conf_t *cfg) {
         drv->dhcp = ch390h_dhcp;
         drv->ctrl = ch390h_ctrl;
         ch->netdrv = drv;
+        tcpip_callback_with_block((tcpip_callback_fn)ch390_lwip_init, ch, 1);
         extern void luat_ch390h_task_start(void);
         luat_ch390h_task_start();
         LLOGD("ch390注册完成");

+ 50 - 0
module/Air8101/demo/multi_network/WIFI_4G_ETH/Air8101_Air780EPM/Air780EPM_master/main.lua

@@ -0,0 +1,50 @@
+--[[
+必须定义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
+
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
+PRODUCT_KEY = "XPwaCKtrZywvcwTMvvdGUTtuiP6zLRTY" --换成自己的
+
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+local function print_mem()
+    -- 打印Lua虚拟机内存使用情况(默认为lua虚拟机内存)
+    log.info("mem.lua", rtos.meminfo())
+    -- 打印系统内存使用情况(“sys”为系统内存)
+    log.info("mem.sys", rtos.meminfo("sys"))
+end
+
+sys.timerLoopStart(print_mem, 3000)
+
+-- 加载功能模块
+require "network_airlink"
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行

+ 118 - 0
module/Air8101/demo/multi_network/WIFI_4G_ETH/Air8101_Air780EPM/Air780EPM_master/network_airlink.lua

@@ -0,0 +1,118 @@
+--[[
+本功能模块演示的内容为:
+1. 初始化网络,使得Air8101可以外挂Air780EPM实现4G联网功能
+2. Air780EPM与对端设备进行数据交互。
+3. 通过HTTP GET请求测试Air780EPM的网络访问外网是否正常。
+]]
+
+-- 加载需要用到的功能模块。
+dnsproxy = require("dnsproxy")
+
+
+-- 初始化网络,使得Air8101可以外挂Air780EPM实现4G联网功能。
+local function init_airlink_net()
+    -- 延时100毫秒。
+    sys.wait(100)
+    -- 初始化airlink。
+    airlink.init()
+    -- 创建桥接网络设备。
+    log.info("创建桥接网络设备")
+    netdrv.setup(socket.LWIP_USER0, netdrv.WHALE)
+    -- 启动airlink,配置Air780EPM作为SPI主机模式。
+    airlink.start(airlink.MODE_SPI_MASTER)
+
+    -- 配置IPv4地址。
+    log.info("配置IPv4地址", "192.168.111.2", "255.255.255.0", "192.168.111.1")
+    netdrv.ipv4(socket.LWIP_USER0, "192.168.111.2", "255.255.255.0", "192.168.111.1")
+    -- 延时100毫秒。
+    sys.wait(100)
+    -- 等待网络就绪,默认事件主题为IP_READY,设置超时时间为10秒。
+    sys.waitUntil("IP_READY", 10000)
+    -- 配置网络地址端口转换(NAPT),此处使用4G网络作为主网关出口。
+    netdrv.napt(socket.LWIP_GP)
+    -- 设置DNS代理。
+    dnsproxy.setup(socket.LWIP_USER0, socket.LWIP_GP)
+end
+
+-- Air780EPM发送数据信息给Air8101。
+local function airlink_sdata_Air8101()
+    while 1 do
+        -- rtos.bsp():设备硬件bsp型号;os.date():本地时间。
+        local data = rtos.bsp() .. " " .. os.date()
+
+        log.info("发送数据给对端设备", data, "当前airlink状态", airlink.ready())
+        airlink.sdata(data)
+
+        -- 此处代码用于实现Air780EPM网络状态的持续检测,并持续给对端设备发送网络状态信息,方便对端设备作应对处理。
+        -- 如果有需要,可以打开注释。
+        -- local net_state = socket.adapter(socket.LWIP_GP)
+        -- if net_state then
+        --     airlink.sdata("Air780EPM_IP_READY!!")
+        -- else
+        --     airlink.sdata("Air780EPM_IP_LOSE!!")
+        -- end
+
+        sys.wait(1000)
+    end
+end
+
+-- 一个简单的HTTP GET请求测试程序,用于判断Air780EPM的网络访问外网是否正常。
+local function http_get_test()
+    -- 6秒后再开始,让网络先初始化完成。
+    sys.wait(6000)
+    -- 循环发起HTTP GET请求,测试Air780EPM的网络访问外网是否正常。
+    while 1 do
+        log.info("发起HTTP GET请求", "https://httpbin.air32.cn/bytes/2048")
+        local code, headers, body = http.request("GET", "https://httpbin.air32.cn/bytes/2048", nil, nil, { timeout = 3000 }).wait()
+
+        -- 打印HTTP请求的结果,包括响应码code和响应体长度#body。
+        if code == 200 then
+            log.info("HTTP请求成功", "响应码", code, "响应体长度", body and #body)
+        else
+            log.error("HTTP请求失败", "错误码", code)
+        end
+
+        -- 加点延时,避免请求过快。
+        sys.wait(5000)
+    end
+end
+
+-- 订阅IP_READY事件,打印收到的信息。
+local function ip_ready(id, ip)
+    -- 打印网络就绪的信息。
+    log.info("收到IP_READY!!", id, ip)
+    -- 给对端设备发送网络状态信息。
+    -- airlink.sdata("Air780EPM_IP_READY!!")
+end
+
+-- 订阅IP_LOSE事件,打印收到的信息。
+local function ip_lose(id, ip)
+    -- 打印网络断开的信息。
+    log.info("收到IP_LOSE!!", id, ip)
+    -- 给对端设备发送网络状态信息。
+    -- airlink.sdata("Air780EPM_IP_LOSE!!")
+end
+
+-- 订阅airlink的SDATA事件,打印收到的信息。
+local function airlink_sdata(data)
+    log.info("收到AIRLINK_SDATA!!", data)
+end
+
+
+-- 初始化网络,使得Air8101可以外挂Air780EPM实现4G联网功能。
+sys.taskInit(init_airlink_net)
+
+-- 一个简单的HTTP GET请求测试程序,用于判断Air780EPM的网络访问外网是否正常。
+-- sys.taskInit(http_get_test)
+
+-- Air780EPM发送数据信息给Air8101。
+-- sys.taskInit(airlink_sdata_Air8101)
+
+-- 订阅IP_READY事件,打印收到的信息。
+-- sys.subscribe("IP_READY", ip_ready)
+
+-- 订阅IP_LOSE事件,打印收到的信息。
+-- sys.subscribe("IP_LOSE", ip_lose)
+
+-- 订阅airlink的SDATA事件,打印收到的信息。
+-- sys.subscribe("AIRLINK_SDATA", airlink_sdata)

+ 50 - 0
module/Air8101/demo/multi_network/WIFI_4G_ETH/Air8101_Air780EPM/Air8101_slave/main.lua

@@ -0,0 +1,50 @@
+--[[
+必须定义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
+
+-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
+-- 可以使用合宙的iot.openluat.com平台进行远程升级
+-- 也可以使用客户自己搭建的平台进行远程升级
+-- 远程升级的详细用法,可以参考fota的demo进行使用
+PRODUCT_KEY = "XPwaCKtrZywvcwTMvvdGUTtuiP6zLRTY" --换成自己的
+
+-- 启动一个循环定时器
+-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
+-- 方便分析内存使用是否有异常
+local function print_mem()
+    -- 打印Lua虚拟机内存使用情况(默认为lua虚拟机内存)
+    log.info("mem.lua", rtos.meminfo())
+    -- 打印系统内存使用情况(“sys”为系统内存)
+    log.info("mem.sys", rtos.meminfo("sys"))
+end
+
+sys.timerLoopStart(print_mem, 3000)
+
+-- 加载功能模块
+require "network_and_http"
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行

+ 187 - 0
module/Air8101/demo/multi_network/WIFI_4G_ETH/Air8101_Air780EPM/Air8101_slave/network_and_http.lua

@@ -0,0 +1,187 @@
+--[[
+本功能模块演示的内容有:
+1. 初始化4G和WiFi网络连接。
+2. Air8101与对端设备进行数据交互。
+3. 自动切换网络连接模式。
+4. 通过HTTP GET请求测试网络连接情况。
+]]
+
+-- 联网模式标志位,1: WiFi联网模式, 2: 4G联网模式
+local connect_mode = 1
+
+-- 初始化网络,使得Air8101可以外挂Air780EPM实现4G联网功能。
+local function init_airlink_net()
+    -- sys.wait(500)
+    -- 初始化airlink。
+    airlink.init()
+    -- 创建桥接网络设备。
+    log.info("创建桥接网络设备")
+    netdrv.setup(socket.LWIP_USER0, netdrv.WHALE)
+    -- 启动airlink,配置Air8101作为SPI从机模式。
+    airlink.start(airlink.MODE_SPI_SLAVE)
+
+    -- 配置IPv4地址。
+    log.info("配置IPv4地址", "192.168.111.1", "255.255.255.0", "192.168.111.2")
+    netdrv.ipv4(socket.LWIP_USER0, "192.168.111.1", "255.255.255.0", "192.168.111.2")
+end
+
+-- 初始化Air8101 WiFi联网配置程序。(WiFi联网功能需要用户自行配置WiFi热点名称和密码)
+local function init_wifi_net()
+    -- 输入需要连接对应WiFi热点的名称(ssid)和密码(password)
+    local ssid = "HONOR_100_Pro" -- 热点名称
+    local password = "12356789"  -- 热点密码
+    log.info("热点信息:", "热点名称:", ssid, "热点密码:", password)
+
+    -- wlan库的判断和WiFi连接。
+    if wlan and wlan.connect then
+        -- 初始化wlan库。
+        wlan.init()
+        -- 设置为WiFi STA模式。
+        wlan.setMode(wlan.STATION)
+        -- 连接WiFi热点。
+        local result = wlan.connect(ssid, password, 1)
+        if result then
+            log.info("发起连接成功")
+        else
+            log.info("发起连接失败")
+        end
+    else
+        log.info("wlan库不存在")
+    end
+end
+
+-- Air8101发送数据信息给Air780EPM。
+local function airlink_sdata_Air780EPM()
+    -- 设置网络时间同步。
+    socket.sntp()
+    while 1 do
+        -- rtos.bsp():设备硬件bsp型号;os.date():本地时间。
+        local data = rtos.bsp() .. " " .. os.date()
+        log.info("发送数据给对端设备", data, "当前airlink状态", airlink.ready())
+        airlink.sdata(data)
+        sys.wait(1000)
+    end
+end
+
+-- 一个简单的HTTP GET请求测试程序,用于判断Air8101的网络连接情况。
+local function http_get_test(mode)
+    -- 发起一个HTTP GET请求。
+    log.info(mode, "发起HTTP GET请求", "https://httpbin.air32.cn/bytes/2048")
+    local code, headers, body = http.request("GET", "https://httpbin.air32.cn/bytes/2048", nil, nil, {timeout=3000}).wait()
+
+    -- 打印HTTP请求的结果,包括响应码code和响应体长度#body。
+    if code == 200 then
+        log.info(mode, "HTTP请求成功", "响应码", code, "响应体长度", body and #body)
+        sys.publish("打印网卡信息", mode, "succeeded")
+    else
+        log.error(mode, "HTTP请求失败", "错误码", code)
+        sys.publish("打印网卡信息", mode, "failed")
+    end
+end
+
+-- 订阅airlink的SDATA事件,打印收到的信息。
+local function airlink_sdata(data)
+    -- 针对对端网络状态,发布不同事件主题。
+    if data == "Air780EPM_IP_READY!!" then
+        log.info("对端设备已联网")
+        -- 可在此处添加对端设备联网后的处理逻辑。
+        -- sys.publish("Air780EPM_IP_READY")
+    elseif data == "Air780EPM_IP_LOSE!!" then
+        log.info("对端设备已断网")
+        -- 可在此处添加对端设备断网后的处理逻辑。
+        -- sys.publish("Air780EPM_IP_LOSE")
+    end
+
+    -- 打印收到的信息。
+    log.info("收到AIRLINK_SDATA!!", data)
+end
+
+-- 切换默认网络适配器。
+local function switch_default_net_adapter(netAdapter)
+    -- 切换默认网络适配器。
+    if netAdapter == "4G" then
+        -- 切换到4G网络适配器。
+        socket.dft(socket.LWIP_USER0)
+        -- 设置DNS服务器地址。
+        socket.setDNS(socket.LWIP_USER0, 1, "192.168.111.2")
+    elseif netAdapter == "WiFi" then
+        -- 切换到WiFi网络适配器。
+        socket.dft(socket.LWIP_STA)
+        -- 设置DNS服务器地址。
+        socket.setDNS(socket.LWIP_STA, 1, "114.114.114.114")
+    end
+end
+
+-- 网络模式切换测试程序。
+local function net_mode_switch()
+    -- 30秒够4G和WiFi初始化完成了。
+    log.info("30秒后开始Air8101网络模式切换测试")
+    sys.wait(30000)
+    log.info("开始Air8101网络模式切换测试")
+
+    while 1 do
+        if connect_mode == 2 then
+            log.info("当前为4G联网模式,进行一次http请求")
+            switch_default_net_adapter("4G")
+            http_get_test("4G网络模式")
+        else
+            log.info("当前为WiFi联网模式,进行一次http请求")
+            switch_default_net_adapter("WiFi")
+            http_get_test("WiFi网络模式")
+        end
+
+        log.info("35秒后切换为另一种网络模式")
+        sys.wait(35000)
+
+        if connect_mode == 1 then
+            log.info("切换为4G联网模式")
+            connect_mode = 2
+            sys.publish("4G联网模式")
+        else
+            log.info("切换为WiFi联网模式")
+            connect_mode = 1
+            sys.publish("WiFi联网模式")
+        end
+    end
+end
+
+-- 网卡信息获取程序。
+local function net_card_info(mode, result)
+    if mode == "4G网络模式" then
+        if result == "succeeded" then
+            log.info("4G网络模式连接成功")
+        else
+            log.error("4G网络模式连接失败")
+        end
+        log.info("当前网络适配器编号:", socket.dft())
+        log.info("当前本地IP地址:", netdrv.ipv4(socket.LWIP_USER0))
+    elseif mode == "WiFi网络模式" then
+        if result == "succeeded" then
+            log.info("WiFi网络模式连接成功")
+        else
+            log.error("WiFi网络模式连接失败")
+        end
+        log.info("当前网络适配器编号:", socket.dft())
+        log.info("当前本地IP地址:", netdrv.ipv4(socket.LWIP_STA))
+        log.info("当前MAC地址:", wlan.getMac())
+        log.info("其他信息", json.encode(wlan.getInfo()))
+    end
+end
+
+-- 初始化网络,使得Air8101可以外挂Air780EPM实现4G联网功能。
+sys.taskInit(init_airlink_net)
+
+-- 初始化Air8101 WiFi联网配置程序。(WiFi联网功能需要用户自行配置WiFi热点名称和密码)
+sys.taskInit(init_wifi_net)
+
+-- Air8101发送数据信息给Air780EPM。
+sys.taskInit(airlink_sdata_Air780EPM)
+
+-- 网络模式切换测试程序。
+sys.taskInit(net_mode_switch)
+
+-- 订阅airlink的SDATA事件,打印收到的信息。
+sys.subscribe("AIRLINK_SDATA", airlink_sdata)
+
+-- 订阅打印网卡信息事件,打印网卡信息。
+sys.subscribe("打印网卡信息", net_card_info)

+ 16 - 0
module/Air8101/demo/multi_network/WIFI_4G_ETH/Air8101_Air780EPM/README.md

@@ -0,0 +1,16 @@
+# 本程序说明如下
+
+本文件中代码用于测试Air8101的三网(4G、WiFi、以太网)切换功能。(以太网部分正在持续更新)
+详细操作说明可参考:[4G - luatos@air8101 - 合宙模组资料中心](https://docs.openluat.com/air8101/luatos/app/multinetwork/4G/)
+
+## 烧录说明
+
+1、Air780EPM 开发板烧录 Air780EPM_master 文件中的程序;
+
+2、Air8101 开发板烧录 Air8101_slave 文件中的程序。
+
+## 测试时所使用的固件版本
+
+1、Air780EPM固件版本:LuatOS-SoC_V2007_Air780EPM.soc;
+
+2、Air8101固件版本:LuatOS-SoC_V1003_Air8101.soc。