init: Air780EPM 官方 LuatOS 项目代码基线

- 来源: 合宙 LuatOS 官方仓库 air780epm 模块完整代码
- 路径: luatos/air780epm/module/Air780EPM/demo 含官方 demo(含 mqtt/mqtts/socket/uart 等)
- 后续: 基于 demo 开发 UART<->MQTT 数据上报功能
This commit is contained in:
wangfq
2026-08-31 08:53:49 +08:00
commit 173dd6874f
813 changed files with 125484 additions and 0 deletions
@@ -0,0 +1,63 @@
--[[
@module main
@summary LuatOS用户应用脚本文件入口,总体调度应用逻辑
@version 1.0
@date 2025.10.23
@author 拓毅恒
@usage
本demo演示的核心功能为:
移动网络功能测试,包括SIM卡管理、基站数据查询、频段(Band)测试和修改、移动网络信息获取(IMEI/IMSI/信号强度等)以及SIM卡状态监控。
通过加载mobile_test模块来运行相关测试功能。
更多说明参考本目录下的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 = "mobiledemo"
VERSION = "001.999.000"
log.info("main", "project name is ", PROJECT, "version is ", VERSION)
-- 如果内核固件支持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)
-- 为避免代码冲突 mobile_test 和 sim_switch_test 同时只能运行一个!!!
-- 加载 mobile_test 功能模块
require "mobile_test"
-- 加载 sim_switch_test 功能模块(双卡切换功能)
-- require "sim_switch_test"
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!
@@ -0,0 +1,143 @@
--[[
@module mobile_test
@summary Air780EPM mobile功能测试模块
@version 1.0
@date 2025.10.21
@author 拓毅恒
@usage
本文件为 Air780EPM 开发板演示移动网络功能的代码示例,核心业务逻辑包括:
1. SIM卡管理和选择(自动选卡功能)
2. 基站数据查询(订阅式和轮询式两种方式)
3. 频段(Band)测试和修改
4. 移动网络信息获取(IMEI、IMSI、信号强度等)
5. SIM卡状态监控
]]
require("sys")
-- 对于双卡的设备, 可以设置为自动选sim卡
-- 但是SIM1所在管脚就强制复用为SIM功能, 占用4个IO口(gpio4/5/6/23),不可以再复用为GPIO
-- mobile.simid(2)
mobile.simid(2,true)--优先用SIM0
-- 设置默认APN
-- 注意:APN 必须在入网前就设置好;在国内公网卡基本上都不需要设置APN, 专网卡才需要设置
mobile.apn(0,1,"","","",nil,0)
-- 基站数据的查询
-- 订阅式, 模块本身会周期性查询基站信息,但通常不包含临近小区
local function sub_cell_info_task()
log.info("cell", json.encode(mobile.getCellInfo()))
end
sys.subscribe("CELL_INFO_UPDATE", sub_cell_info_task)
-- 轮询式, 包含临近小区信息,这是手动搜索,和上面的自动搜索冲突,开启一个就行
local function get_cell_info_task()
sys.wait(5000)
mobile.config(mobile.CONF_SIM_WC_MODE, 2)
while 1 do
mobile.reqCellInfo(10)
sys.wait(11000)
log.info("cell", json.encode(mobile.getCellInfo()))
mobile.config(mobile.CONF_SIM_WC_MODE, 2)
end
end
-- 获取sim卡的状态
local function get_sim_status_task(status, value)
log.info("sim status", status)
if status == 'RDY' then
log.info("sim", "sim OK", value)
end
if status == 'NORDY' then
log.info("sim", "NO sim", value)
end
if status == 'GET_NUMBER' then
log.info("number", mobile.number(0))
end
if status == "SIM_WC" then
log.info("sim", "write counter", value)
end
end
sys.subscribe("SIM_IND", get_sim_status_task)
-- SIM 卡热插拔功能,通过gpio中断通过上下边沿电平触发中断
-- 设置防抖,使用wakeup2脚,常量为gpio.WAKEUP2
-- 自己设计其他gpio热插拔只需要替换对应的gpio即可
gpio.debounce(gpio.WAKEUP2,500)
-- 设置中断触发,拔卡进入飞行模式,插卡进出飞行模式,val值为上升沿或者下降沿触发0/1
local function sim_hot_plug(val)
if val == 0 then
log.info("插卡")
mobile.flymode(0,true)
mobile.flymode(0,false)
else
log.info("拔卡")
mobile.flymode(0,true)
end
end
gpio.setup(gpio.WAKEUP2,sim_hot_plug)
-- 定义测试band和移动网络信息的函数
local function mobileinfo_task()
-- -- 开启SIM暂时脱离后自动恢复,30秒搜索一次周围小区信息
-- mobile.setAuto(10000,30000, 5) -- 此函数仅需要配置一次
-- log.info("************开始测试band************")
-- local band = zbuff.create(40)
-- local band1 = zbuff.create(40)
-- mobile.getBand(band)
-- log.info("当前使用的band:")
-- for i=0,band:used()-1 do
-- log.info("band", band[i])
-- end
-- band1[0] = 38
-- band1[1] = 39
-- band1[2] = 40
-- mobile.setBand(band1, 3) --改成使用38,39,40
-- band1:clear()
-- mobile.getBand(band1)
-- log.info("修改后使用的band:")
-- for i=0,band1:used()-1 do
-- log.info("band", band1[i])
-- end
-- mobile.setBand(band, band:used()) --改回原先使用的band,也可以下载的时候选择清除fs
-- mobile.getBand(band1)
-- log.info("修改回默认使用的band:")
-- for i=0,band1:used()-1 do
-- log.info("band", band1[i])
-- end
-- log.info("************band测试完毕************")
log.info("status", mobile.status())
sys.wait(2000)
while 1 do
log.info("imei", mobile.imei())
log.info("imsi", mobile.imsi())
log.info("apn", mobile.apn()) -- 获取当前APN
log.info("status", mobile.status())
log.info("iccid", mobile.iccid())
log.info("csq", mobile.csq()) -- 4G模块的CSQ并不能完全代表强度
log.info("rssi", mobile.rssi()) -- 需要综合rssi/rsrq/rsrp/snr一起判断
log.info("rsrq", mobile.rsrq())
log.info("rsrp", mobile.rsrp())
log.info("snr", mobile.snr())
log.info("simid", mobile.simid()) -- 这里是获取当前SIM卡槽
-- log.info("apn", mobile.apn(0,1))
-- sys内存
log.info("lua", rtos.meminfo())
log.info("sys", rtos.meminfo("sys"))
sys.wait(15000)
end
end
-- 轮询式查找小区, 包含临近小区信息,与上面订阅式搜索冲突,开启一个就行
-- sys.taskInit(get_cell_info_task)
-- 启动测试任务
sys.taskInit(mobileinfo_task)
sys.run()
@@ -0,0 +1,290 @@
## 功能模块介绍
1、main.lua:主程序入口,负责初始化系统环境和加载移动网络测试模块;
2、mobile_test.lua:移动网络功能测试模块,演示Air780EPM的移动网络相关功能;
3、sim_switch_test.luaSIM卡自动切换功能测试模块,实现卡1/卡2网络异常自动切换;
## 演示功能概述
1、mobile_test:演示以下几种应用场景的使用方式
- SIM卡配置和管理功能演示;
- 基站数据查询(订阅式和轮询式)功能演示;
- SIM卡状态订阅功能演示;
- 频段(Band)测试和修改功能演示;
- 移动网络信息获取(IMEI/IMSI/信号强度等)功能演示;
2、sim_switch_test:演示以下三种SIM卡切换方式:
- 轮询主动指定simid切换sim卡:定期检查网络状态,网络异常时主动切换到指定SIM卡
- 轮询自适应切换sim卡:系统自动选择最优SIM卡,无需手动指定(注:自适应模式需要设备使用V2022及以上固件才可以使用)
- 中断方式主动指定simid切换sim卡:按键触发(WAKEUP0引脚)中断切换SIM卡
## 演示硬件环境
1、Air780EPM开发板一块 + 可上网的SIM卡一张 + 4G天线一根:
- SIM卡插入开发板的SIM卡槽
- 天线装到开发板上
2、TYPE-C USB数据线一根,Air780EPM开发板和数据线的硬件接线方式为:
- Air780EPM开发板通过TYPE-C USB口供电;(外部供电/USB供电 拨动开关 拨到 USB供电一端)
- TYPE-C USB数据线直接插到核心板的TYPE-C USB座子,另外一端连接电脑USB口;
## 演示软件环境
1、Luatools下载调试工具
2、Air780EPM 版本固件:[Air780EPM 版本固件](https://docs.openluat.com/air780epm/luatos/firmware/version/)
## 演示核心步骤
### 5.1 mobile_test 演示步骤
1、搭建好硬件环境
2、确保SIM卡已正确插入开发板
3、确保main.lua中加载了mobile_test模块(默认加载):
```lua
-- 加载 mobile_test 功能模块
require "mobile_test"
-- 加载 sim_switch_test 功能模块(双卡切换功能)
-- require "sim_switch_test"
```
4、Luatools烧录内核固件和demo脚本代码
5、烧录成功后,自动开机运行,通过串口日志可以观察到以下信息:
- SIM卡状态监控信息
- 基站数据查询结果
- 移动网络信息(IMEI/IMSI/信号强度等)
- 频段测试和修改结果
``` lua
[2025-10-23 15:58:31.141][000000000.361] I/user.main project name is mobiledemo version is 001.000.000
[2025-10-23 15:58:31.142][000000000.370] I/mobile sim set to 2 , ret 0
[2025-10-23 15:58:31.144][000000000.373] I/user.************开始测试band************
[2025-10-23 15:58:31.161][000000001.774] I/user.当前使用的band:
[2025-10-23 15:58:31.163][000000001.775] I/user.band 1
[2025-10-23 15:58:31.165][000000001.775] I/user.band 3
[2025-10-23 15:58:31.167][000000001.775] I/user.band 5
[2025-10-23 15:58:31.169][000000001.776] I/user.band 8
[2025-10-23 15:58:31.170][000000001.776] I/user.band 34
[2025-10-23 15:58:31.172][000000001.776] I/user.band 38
[2025-10-23 15:58:31.173][000000001.776] I/user.band 39
[2025-10-23 15:58:31.175][000000001.777] I/user.band 40
[2025-10-23 15:58:31.176][000000001.777] I/user.band 41
[2025-10-23 15:58:31.178][000000001.791] I/user.修改后使用的band:
[2025-10-23 15:58:31.179][000000001.792] I/user.band 38
[2025-10-23 15:58:31.180][000000001.792] I/user.band 39
[2025-10-23 15:58:31.182][000000001.793] I/user.band 40
[2025-10-23 15:58:31.183][000000001.799] I/user.修改回默认使用的band:
[2025-10-23 15:58:31.184][000000001.800] I/user.band 1
[2025-10-23 15:58:31.186][000000001.800] I/user.band 3
[2025-10-23 15:58:31.187][000000001.800] I/user.band 5
[2025-10-23 15:58:31.189][000000001.800] I/user.band 8
[2025-10-23 15:58:31.190][000000001.801] I/user.band 34
[2025-10-23 15:58:31.191][000000001.801] I/user.band 38
[2025-10-23 15:58:31.193][000000001.801] I/user.band 39
[2025-10-23 15:58:31.195][000000001.802] I/user.band 40
[2025-10-23 15:58:31.196][000000001.802] I/user.band 41
[2025-10-23 15:58:31.198][000000001.802] I/user.************band测试完毕************
[2025-10-23 15:58:48.147][000000018.809] I/user.imei 864793080175404
[2025-10-23 15:58:48.149][000000018.809] I/user.imsi 460240452233401
[2025-10-23 15:58:48.151][000000018.810] I/user.status 1
[2025-10-23 15:58:48.153][000000018.810] I/user.iccid 89860855102480513401
[2025-10-23 15:58:48.155][000000018.810] I/user.csq 27
[2025-10-23 15:58:48.157][000000018.811] I/user.rssi -58
[2025-10-23 15:58:48.158][000000018.811] I/user.rsrq -9
[2025-10-23 15:58:48.160][000000018.811] I/user.rsrp -87
[2025-10-23 15:58:48.161][000000018.812] I/user.snr 16
[2025-10-23 15:58:48.163][000000018.812] I/user.simid 0
[2025-10-23 15:58:48.169][000000018.812] I/user.apn cmiot.MNC024.MCC460.GPRS
[2025-10-23 15:58:48.171][000000018.813] I/user.lua 4194296 56552 56552
[2025-10-23 15:58:48.172][000000018.813] I/user.sys 3202992 355468 360724
[2025-10-23 15:58:56.722][000000027.379] I/user.cell [{"mnc":0,"dlbandwidth":5,"tdd":0,"earfcn":1300,"ulbandwidth":5,"band":3,"mcc":460,"pci":219,"rsrp":-86,"tac":18511,"rssi":-57,"rsrq":-9,"snr":16,"cid":190213964},{"mnc":15,"earfcn":1300,"pci":219,"rsrp":-86,"tac":18511,"mcc":460,"rsrq":-9,"snr":16,"cid":190213964},{"mnc":0,"earfcn":40936,"pci":368,"rsrp":-103,"tac":18511,"mcc":460,"rsrq":-7,"snr":0,"cid":192844432}]
[2025-10-23 15:58:56.726][000000027.382] I/user.sim status SIM_WC
[2025-10-23 15:58:56.728][000000027.383] I/user.sim write counter 2
```
6、日志中会实时显示移动网络相关信息的变化,可通过观察日志来验证功能是否正常工作
### 5.2 sim_switch_test 演示步骤
1、硬件准备:Air780EPM开发板一块 + 可上网的SIM卡两张 + 4G天线一根
2、确保两张SIM卡已正确插入开发板的卡1和卡2插槽
#### 5.2.2 软件配置
1、修改main.lua,注释掉mobile_test模块,启用sim_switch_test模块:
```lua
-- 加载 mobile_test 功能模块
-- require "mobile_test"
-- 加载 sim_switch_test 功能模块(双卡切换功能)
require "sim_switch_test"
```
2、选择切换方式:在sim_switch_test.lua文件末尾,选择您想要使用的切换方式(三选一):
```lua
-- 启动双卡切换任务(三选一)
-- 轮询主动指定simid切换sim卡
sys.taskInit(sim_switch_task)
-- 轮询自适应切换sim卡
-- sys.taskInit(sim_switch_adaptive_task)
-- 中断方式主动指定simid切换sim卡
-- sys.taskInit(sim_switch_irq_task)
```
#### 5.2.3 烧录和运行
1、使用Luatools烧录内核固件和demo脚本代码
2、烧录成功后,自动开机运行
#### 5.2.4 三种切换方式说明
##### 1. 轮询主动指定simid切换sim卡(默认启用)
- 功能:定期检查网络状态,网络异常时主动切换到指定SIM卡
- 特点:使用mobile.simid()直接指定SIM卡索引进行切换,切换逻辑明确可控
- 日志示例:
``` lua
[2026-01-14 13:14:00.055][000000000.230] I/user.main project name is mobiledemo version is 001.000.000
[2026-01-14 13:14:00.057][000000000.239] I/mobile sim set to 0 , ret 0
[2026-01-14 13:14:00.060][000000000.240] I/user.sim_switch 初始SIM卡: 0
[2026-01-14 13:14:00.063][000000000.240] I/user.sim_switch 当前SIM卡: 0 网络状态: 0
[2026-01-14 13:14:00.066][000000000.240] I/user.sim_switch 正在等待网络连接...
[2026-01-14 13:14:00.222][000000000.727] I/user.sim_switch SIM卡正常
[2026-01-14 13:14:01.727][000000002.246] D/mobile cid1, state0
[2026-01-14 13:14:01.731][000000002.246] D/mobile bearer act 0, result 0
[2026-01-14 13:14:01.734][000000002.247] D/mobile NETIF_LINK_ON -> IP_READY
[2026-01-14 13:14:01.738][000000002.273] D/mobile TIME_SYNC 0
[2026-01-14 13:14:14.700][000000015.241] I/user.sim_switch 网络连接成功
[2026-01-14 13:14:24.704][000000025.241] I/user.sim_switch 当前SIM卡: 0 网络状态: 1
[2026-01-14 13:14:24.713][000000025.241] I/user.sim_switch 网络已经连接
-- 此时将SIM卡从SIM0换到SIM1,模拟SIMO网络异常
[2026-01-14 13:14:30.556][000000031.085] I/user.sim_switch 无SIM卡
[2026-01-14 13:14:30.680][000000031.222] D/mobile cid1, state2
[2026-01-14 13:14:30.686][000000031.222] D/mobile NETIF_LINK_OFF -> IP_LOSE
[2026-01-14 13:14:34.706][000000035.242] I/user.sim_switch 当前SIM卡: 0 网络状态: 0
[2026-01-14 13:14:34.713][000000035.242] I/user.sim_switch 正在等待网络连接...
[2026-01-14 13:14:40.533][000000041.083] prvSimCheck 494:sim error and reset stack
[2026-01-14 13:14:40.728][000000041.258] I/user.sim_switch 无SIM卡
[2026-01-14 13:14:49.695][000000050.243] I/user.sim_switch 网络连接失败,切换到SIM卡 1
[2026-01-14 13:14:49.759][000000050.300] I/mobile sim set to 1 , ret 0
[2026-01-14 13:14:50.126][000000050.648] I/user.sim_switch SIM卡正常
[2026-01-14 13:14:51.782][000000052.304] D/mobile cid1, state0
[2026-01-14 13:14:51.786][000000052.304] D/mobile bearer act 0, result 0
-- SIM1联网成功
[2026-01-14 13:14:51.790][000000052.305] D/mobile NETIF_LINK_ON -> IP_READY
[2026-01-14 13:14:51.795][000000052.331] D/mobile TIME_SYNC 0
[2026-01-14 13:14:59.763][000000060.301] I/user.sim_switch 当前SIM卡: 1 网络状态: 1
[2026-01-14 13:14:59.766][000000060.301] I/user.sim_switch 网络已经连接
[2026-01-14 13:15:09.763][000000070.302] I/user.sim_switch 当前SIM卡: 1 网络状态: 1
[2026-01-14 13:15:09.765][000000070.302] I/user.sim_switch 网络已经连接
[2026-01-14 13:15:19.761][000000080.303] I/user.sim_switch 当前SIM卡: 1 网络状态: 1
[2026-01-14 13:15:19.765][000000080.303] I/user.sim_switch 网络已经连接
```
##### 2. 轮询自适应切换sim卡
- 功能:系统自动选择最优SIM卡,无需手动指定
- 特点:设置mobile.simid(2)启用自适应模式,由系统智能选择最佳SIM卡
- 注意事项:自适应模式需要设备使用V2022及以上固件才可以使用
- 日志示例:
```lua
[2026-01-14 13:58:25.030][000000000.205] I/user.main project name is mobiledemo version is 001.000.000
[2026-01-14 13:58:25.031][000000000.212] I/mobile sim set to 2 , ret 0
[2026-01-14 13:58:25.080][000000000.538] I/user.sim_switch 无SIM卡
[2026-01-14 13:58:25.348][000000000.881] I/user.sim_switch SIM卡正常
[2026-01-14 13:58:27.159][000000002.698] D/mobile cid1, state0
[2026-01-14 13:58:27.161][000000002.699] D/mobile bearer act 0, result 0
[2026-01-14 13:58:27.162][000000002.700] D/mobile NETIF_LINK_ON -> IP_READY
[2026-01-14 13:58:27.195][000000002.760] D/mobile TIME_SYNC 0
[2026-01-14 13:58:27.662][000000003.213] I/user.sim_switch 初始SIM卡: 0
[2026-01-14 13:58:27.666][000000003.213] I/user.sim_switch 当前SIM卡: 0 网络状态: 1
[2026-01-14 13:58:27.667][000000003.214] I/user.sim_switch 网络已经连接
[2026-01-14 13:58:37.650][000000013.214] I/user.sim_switch 当前SIM卡: 0 网络状态: 1
[2026-01-14 13:58:37.653][000000013.214] I/user.sim_switch 网络已经连接
-- 此时将SIM卡从SIM0换到SIM1,模拟SIMO网络异常
[2026-01-14 13:58:55.744][000000031.288] I/user.sim_switch 无SIM卡
[2026-01-14 13:58:55.977][000000031.535] D/mobile cid1, state2
[2026-01-14 13:58:55.979][000000031.535] D/mobile NETIF_LINK_OFF -> IP_LOSE
[2026-01-14 13:58:57.660][000000033.216] I/user.sim_switch 当前SIM卡: 0 网络状态: 0
[2026-01-14 13:58:57.665][000000033.216] I/user.sim_switch 正在等待网络连接...
[2026-01-14 13:59:05.734][000000041.286] prvSimCheck 494:sim error and reset stack
[2026-01-14 13:59:05.928][000000041.467] I/user.sim_switch 无SIM卡
[2026-01-14 13:59:06.300][000000041.813] I/user.sim_switch SIM卡正常
[2026-01-14 13:59:07.839][000000043.369] D/mobile cid1, state0
[2026-01-14 13:59:07.841][000000043.370] D/mobile bearer act 0, result 0
-- SIM1联网成功
[2026-01-14 13:59:07.842][000000043.370] D/mobile NETIF_LINK_ON -> IP_READY
[2026-01-14 13:59:07.860][000000043.426] D/mobile TIME_SYNC 0
[2026-01-14 13:59:12.655][000000048.217] I/user.sim_switch 网络连接成功
[2026-01-14 13:59:22.664][000000058.217] I/user.sim_switch 当前SIM卡: 0 网络状态: 1
[2026-01-14 13:59:22.668][000000058.217] I/user.sim_switch 网络已经连接
[2026-01-14 13:59:32.654][000000068.218] I/user.sim_switch 当前SIM卡: 0 网络状态: 1
[2026-01-14 13:59:32.658][000000068.218] I/user.sim_switch 网络已经连接
```
##### 3. 中断方式主动指定simid切换sim卡
- 功能:按键触发(WAKEUP0引脚)中断切换SIM卡
- 特点:下降沿触发中断,带有500ms防抖,实时打印当前SIM卡状态和网络状态
- 硬件要求:需连接WAKEUP0引脚到按键或触发设备
- 日志示例:
```lua
[2026-01-14 14:14:37.858][000000000.215] I/user.main project name is mobiledemo version is 001.000.000
[2026-01-14 14:14:37.860][000000000.224] I/user.sim_switch 初始SIM卡: 0
[2026-01-14 14:14:37.862][000000000.224] I/mobile sim set to 0 , ret 0
[2026-01-14 14:14:37.864][000000000.224] I/user.sim_switch 当前SIM卡: 0 网络状态: 0
[2026-01-14 14:14:38.035][000000000.713] I/user.sim_switch SIM卡正常
[2026-01-14 14:14:39.150][000000001.822] D/mobile cid1, state0
[2026-01-14 14:14:39.152][000000001.823] D/mobile bearer act 0, result 0
[2026-01-14 14:14:39.153][000000001.824] D/mobile NETIF_LINK_ON -> IP_READY
[2026-01-14 14:14:39.177][000000001.881] D/mobile TIME_SYNC 0
[2026-01-14 14:14:47.524][000000010.225] I/user.sim_switch 当前SIM卡: 0 网络状态: 1
[2026-01-14 14:14:57.532][000000020.226] I/user.sim_switch 当前SIM卡: 0 网络状态: 1
-- 此时将SIM卡从SIM0换到SIM1,模拟SIMO网络异常
[2026-01-14 14:15:08.373][000000031.055] I/user.sim_switch 无SIM卡
[2026-01-14 14:15:08.611][000000031.300] D/mobile cid1, state2
[2026-01-14 14:15:08.613][000000031.301] D/mobile NETIF_LINK_OFF -> IP_LOSE
[2026-01-14 14:15:17.526][000000040.226] I/user.sim_switch 当前SIM卡: 0 网络状态: 0
[2026-01-14 14:15:18.348][000000041.054] prvSimCheck 494:sim error and reset stack
[2026-01-14 14:15:18.540][000000041.228] I/user.sim_switch 无SIM卡
[2026-01-14 14:15:27.526][000000050.226] I/user.sim_switch 当前SIM卡: 0 网络状态: 0
[2026-01-14 14:15:28.532][000000051.226] prvSimCheck 494:sim error and reset stack
[2026-01-14 14:15:28.725][000000051.401] I/user.sim_switch 无SIM卡
-- 此时将WAKEUP0短接,模拟按键按下
[2026-01-14 14:15:56.795][000000079.501] I/user.sim_switch 按键触发,开始切换到SIM卡: 1
[2026-01-14 14:15:56.798][000000079.508] I/mobile sim set to 1 , ret 0
[2026-01-14 14:15:56.799][000000079.508] I/user.sim_switch SIM卡切换成功,当前使用SIM卡: 1
[2026-01-14 14:15:57.250][000000079.857] I/user.sim_switch SIM卡正常
[2026-01-14 14:16:14.280][000000096.961] D/mobile cid1, state0
[2026-01-14 14:16:14.282][000000096.961] D/mobile bearer act 0, result 0
-- SIM1联网成功
[2026-01-14 14:16:14.283][000000096.962] D/mobile NETIF_LINK_ON -> IP_READY
[2026-01-14 14:16:14.334][000000097.031] D/mobile TIME_SYNC 0
[2026-01-14 14:16:17.519][000000100.226] I/user.sim_switch 当前SIM卡: 1 网络状态: 1
[2026-01-14 14:16:27.527][000000110.226] I/user.sim_switch 当前SIM卡: 1 网络状态: 1
```
@@ -0,0 +1,179 @@
--[[
@module sim_switch_test
@summary 双卡切换功能测试模块
@version 1.1
@date 2026.1.6
@author 拓毅恒
@usage
本文件为 Air780EPM 核心板演示双卡切换功能的代码示例,提供三种切换方式:
1. 轮询主动指定simid切换sim卡(sim_switch_task
- 定期检查网络状态,网络异常时主动切换到指定SIM卡
- 使用mobile.simid()直接指定SIM卡索引进行切换
2. 轮询自适应切换sim卡(sim_switch_adaptive_task
- 系统自动选择最优SIM卡,无需手动指定
- 设置mobile.simid(2)启用自适应模式
- 注:自适应模式需要设备使用V2022及以上固件才可以使用!!!
3. 中断方式主动指定simid切换sim卡(sim_switch_irq_task
- 按键触发(WAKEUP0引脚)中断切换SIM卡
- 下降沿触发中断,带有500ms防抖
- 实时打印当前SIM卡状态和网络状态
核心业务逻辑包括:
- SIM卡自动切换功能(卡1网络异常切换到卡2,卡2网络异常切换到卡1)
- 网络状态监控和自动恢复机制
- 合理的切换间隔和超时控制
- SIM卡状态订阅和监控
使用说明:
- 在main.lua中require此模块即可启用双卡切换功能
- 确保同时注释掉mobile_test模块以避免代码冲突
- 同时只能选择一种切换方式启用
- 模块会自动管理网络状态并在需要时执行SIM卡切换
]]
-- 开启SIM脱离后自动恢复,30秒搜索一次周围小区信息
mobile.setAuto(10000, 30000, 5, nil, 30000) -- 此函数仅需要配置一次
-- 轮询主动指定simid切换sim卡
local function sim_switch_task()
-- 当前使用的SIM卡索引(0或1
local current_sim = 0
-- 初始选择SIM0
mobile.simid(current_sim)
log.info("sim_switch", "初始SIM卡:", current_sim)
while true do
-- 获取当前网络状态
local status = mobile.status()
log.info("sim_switch", "当前SIM卡:", current_sim, "网络状态:", status)
-- 如果网络状态不是"REGISTERED"或"REGISTERED_ROAMING",则等待一段时间后检查是否联网成功
if status ~= mobile.REGISTERED and status ~= mobile.REGISTERED_ROAMING then
log.info("sim_switch", "正在等待网络连接...")
-- 联网超时时间(15秒)
sys.wait(15000)
-- 再次检查网络状态
status = mobile.status()
if status ~= mobile.REGISTERED and status ~= mobile.REGISTERED_ROAMING then
-- 网络连接失败,切换到另一张SIM卡
current_sim = current_sim == 0 and 1 or 0
log.info("sim_switch", "网络连接失败,切换到SIM卡", current_sim)
-- 切换SIM卡
mobile.simid(current_sim)
else
log.info("sim_switch", "网络连接成功")
end
else
log.info("sim_switch", "网络已经连接")
end
sys.wait(10000) -- 每10秒检查一次网络状态
end
end
-- 轮询自适应切换sim卡
-- 注:自适应模式需要设备使用V2022及以上固件才可以使用!!!
local function sim_switch_adaptive_task()
-- 自适应方式切换SIM卡
mobile.simid(2)
-- 等待设置完毕
sys.wait(3000)
-- 获取当前使用的SIM卡索引
local current_sim = mobile.simid()
log.info("sim_switch", "初始SIM卡:", current_sim)
while true do
-- 获取当前网络状态
local status = mobile.status()
current_sim = mobile.simid()
log.info("sim_switch", "当前SIM卡:", current_sim, "网络状态:", status)
-- 如果网络状态不是"REGISTERED"或"REGISTERED_ROAMING",则等待一段时间后检查是否联网成功
if status ~= mobile.REGISTERED and status ~= mobile.REGISTERED_ROAMING then
log.info("sim_switch", "正在等待网络连接...")
-- 联网超时时间(15秒)
sys.wait(15000)
-- 再次检查网络状态
status = mobile.status()
if status ~= mobile.REGISTERED and status ~= mobile.REGISTERED_ROAMING then
-- 网络连接失败,切换到另一张SIM卡
current_sim = current_sim == 0 and 1 or 0
log.info("sim_switch", "网络连接失败,切换到SIM卡", current_sim)
else
log.info("sim_switch", "网络连接成功")
end
else
log.info("sim_switch", "网络已经连接")
end
sys.wait(10000) -- 每10秒检查一次网络状态
end
end
-- 全局变量:中断方式切换SIM卡时的当前SIM卡索引
local current_sim_irq = 0
-- 设置中断触发回调函数
local function sim_switch_callback()
-- 按键触发后,切换到另一张SIM卡
current_sim_irq = current_sim_irq == 0 and 1 or 0
log.info("sim_switch", "按键触发,开始切换到SIM卡:", current_sim_irq)
-- 指定simid切换SIM卡
local result = mobile.simid(current_sim_irq)
if result then
log.info("sim_switch", "SIM卡切换成功,当前使用SIM卡:", current_sim_irq)
else
log.error("sim_switch", "SIM卡切换失败")
end
end
-- 中断方式主动指定simid切换sim卡
local function sim_switch_irq_task()
-- 初始化全局变量
current_sim_irq = 0
log.info("sim_switch", "初始SIM卡:", current_sim_irq)
-- 设置默认使用SIM0
mobile.simid(current_sim_irq)
-- 配置WAKEUP0引脚防抖(500ms
gpio.debounce(gpio.WAKEUP0, 500)
-- 配置WAKEUP0引脚为下降沿触发中断
gpio.setup(gpio.WAKEUP0, sim_switch_callback, gpio.PULLUP, gpio.FALLING)
-- 定时打印当前状态的循环
while true do
local status = mobile.status()
log.info("sim_switch", "当前SIM卡:", current_sim_irq, "网络状态:", status)
sys.wait(10000) -- 每10秒打印一次
end
end
-- 获取sim卡的状态
local function get_sim_status_task(status)
if status == 'RDY' then
log.info("sim_switch", "SIM卡正常")
end
if status == 'NORDY' then
log.info("sim_switch", "无SIM卡")
end
end
sys.subscribe("SIM_IND", get_sim_status_task)
-- 启动双卡切换任务(三选一)
-- 轮询主动指定simid切换sim卡
sys.taskInit(sim_switch_task)
-- 轮询自适应切换sim卡
-- 注:自适应模式需要设备使用V2022及以上固件才可以使用!!!
-- sys.taskInit(sim_switch_adaptive_task)
-- 中断方式主动指定simid切换sim卡
-- sys.taskInit(sim_switch_irq_task)