xt-sdk 文档 v1.0.3
xt-sdk 嵌入式 SDK API 参考
载入中...
搜索中...
未找到
xt_mobile - 蜂窝网络

版本:0.1 | 日期:2026-07-03 | 路径: platforms/components/xtiny/xt_mobile/


一、概述

xt_mobile 是 xtiny 蜂窝网络统一接口,封装设备信息获取、网络状态查询、信号质量测量、SIM 卡管理和飞行模式控制。模块采用事件驱动模型:底层网络状态变化通过回调通知应用层,上层不必轮询。

当前仅 lm620 平台实现,底层通过平台消息通道与协议栈通信。

1.1 设计原则

  • 事件驱动 :注册一个回调,被动接收 SIM 状态变化、联网/断网、时间同步事件
  • 双卡抽象 :API 通过 simid 参数支持多 SIM 卡,lm620 支持卡槽 0 和 1
  • 查询分离 :信号质量提供相对值(协议栈上报)和真实值(物理层测量)两套查询

1.2 依赖

依赖 用途
xt_error.h 错误码定义

二、核心概念

2.1 事件驱动模型

模块不提供阻塞式状态查询循环,而是通过 xt_mobile_set_event_cb 注册一个回调函数 xt_mobile_on_event_cb_t 。底层平台网络事件钩子收到事件后,映射为 xtiny 事件并调用该回调:

平台事件 xtiny 事件 触发时机
SIM 卡状态就绪 XT_MOBILE_SIM_IND SIM 卡状态变化, param 为卡槽编号
网络 IP 就绪 XT_MOBILE_IP_READY 网络已连接, param=NULL
网络 IP 断开 XT_MOBILE_IP_LOSE 网络已断开, param=NULL
NTP 时间已同步 XT_MOBILE_NTP_UPDATE NTP 时间已同步, param=NULL

注意 :事件回调在 SDK 底层线程上下文中执行,回调内不能执行长时间阻塞操作。

2.2 SIM 卡状态机

SIM 状态通过 xt_mobile_get_simstatus 查询,返回值映射为:

常量 值 含义
XT_MOBILE_USIM_READY 0 就绪
XT_MOBILE_USIM_SIMPIN 1 需要 PIN 码
XT_MOBILE_USIM_SIMPUK 2 需要 PUK 码
XT_MOBILE_USIM_NOT_READY -4 未就绪
XT_MOBILE_USIM_TIMEOUT -3 通信超时
XT_MOBILE_USIM_NOT_INSERTED -2 卡未插入
XT_MOBILE_USIM_UNKNOW -1 未知/异常

异常恢复机制 :模块内部维护一个连续异常计数器。当 get_simstatus 连续返回异常状态( ≤ XT_MOBILE_USIM_UNKNOW )达到 15 次( SIM_STATE_GET_CNT_MAX ),自动触发切卡重初始化流程(关闭射频 → 切换卡槽 → 重新上电),计数器归零。

超时处理 : get_simstatus 和 get_imsi 底层 ATI 请求超时时间均为 300ms。超时返回 XT_MOBILE_USIM_TIMEOUT 或 XT_ETIMEOUT ,并计入连续异常计数。

2.3 双卡机制

需平台 NV 配置开启双卡检测。

单卡模式 (NV 配置关闭):

  • 仅操作当前激活的卡槽
  • get_imsi / get_iccid / set_flymode / get_flymode 必须传入与 xt_mobile_get_simid() 一致的 simid ,否则返回 XT_EINVAL

双卡模式 (NV 配置开启):

  • xt_mobile_pre_init 阶段启动独立后台任务,监听卡槽变化消息
  • 任务等待双卡指示上报就绪后,查询 +CMSLOT? 获取当前卡槽
  • 若当前卡槽无卡而另一卡槽有卡,自动切换到有卡卡槽
  • get_iccid 和 get_simstatus 在双卡模式下直接返回缓存状态,不走 ATI 请求

双卡就绪判断 : get_iccid 和 get_simstatus 在双卡指示就绪前分别返回 XT_EBUSY 和 XT_MOBILE_USIM_NOT_READY 。

2.4 切卡流程

xt_mobile_set_simid 执行三段式切卡:

  1. 关闭射频
  2. 切换卡槽
  3. 重新上电

若目标卡槽与当前一致,直接返回 XT_EOK 跳过流程。

2.5 信号质量:相对值 vs 真实值

函数 数据来源 说明
xt_mobile_get_csq 协议栈上报信号质量 返回 1~31 的相对值,99 表示无效
xt_mobile_get_csq_real 物理层测量信号质量 返回 RSSI 真实 dBm 值
xt_mobile_get_cesq 协议栈上报信号质量 rsrq/rsrp 为相对值
xt_mobile_get_cesq_real 物理层测量信号质量 rsrq/rsrp 为真实 dB/dBm 值

get_cesq 和 get_cesq_real 中, rxlev / ber / rscp / ecno 字段固定为无效值(99/99/255/255),因为仅上报当前注册网络的 RAT 信号。

2.6 飞行模式

xt_mobile_set_flymode 通过 +CFUN 实现:

  • 飞行模式:射频最小功能模式(射频关闭)
  • 正常模式:射频全功能模式

进入飞行模式时会清除缓存的 IMSI 和二次 APN 信息。


三、API 参考

以下为函数签名大纲,完整的参数说明、返回值、注意事项请查看 xt_mobile(蜂窝网络) 。

3.1 事件回调

函数签名 说明
xt_err_t xt_mobile_set_event_cb(xt_mobile_on_event_cb_t on_event_cb) 注册网络事件回调

3.2 设备信息

函数签名 说明
xt_err_t xt_mobile_get_imei(char str_imei[15+1]) 获取设备 IMEI
xt_err_t xt_mobile_get_imsi(uint8_t simid, char str_imsi[15+1]) 获取 SIM 卡 IMSI
xt_err_t xt_mobile_get_iccid(uint8_t simid, char str_iccid[20+1]) 获取 SIM 卡 ICCID

3.3 网络状态

函数签名 说明
int xt_mobile_get_status(void) 获取网络注册状态(CEREG stat)
uint8_t xt_mobile_get_csq(void) 获取 CSQ 相对值(1~31)
xt_err_t xt_mobile_get_csq_real(int8_t *rssi) 获取 CSQ 真实值(dBm)
xt_err_t xt_mobile_get_cesq(struct cesq_data *ptr_data) 获取 CESQ 相对值
xt_err_t xt_mobile_get_cesq_real(struct cesq_data *ptr_data) 获取 CESQ 真实值

3.4 小区信息

函数签名 说明
xt_err_t xt_mobile_get_scell(struct scell_info *scell_info) 获取当前服务小区信息
xt_err_t xt_mobile_get_cellinfo(struct cell_info *cell_info) 同步获取邻近小区列表
xt_err_t xt_mobile_get_cellinfo_async(xt_mobile_cellinfo_ind_cb_t cb) 异步获取邻近小区列表

3.5 SIM 卡管理

函数签名 说明
int xt_mobile_get_simstatus(uint8_t simid) 获取 SIM 卡状态
xt_err_t xt_mobile_set_simid(uint8_t simid) 设置当前使用的 SIM 卡
uint8_t xt_mobile_get_simid(void) 获取当前使用的 SIM 卡编号

3.6 飞行模式

函数签名 说明
xt_err_t xt_mobile_set_flymode(uint8_t simid, uint8_t onoff) 设置飞行模式
int xt_mobile_get_flymode(uint8_t simid) 获取飞行模式状态

3.7 高级功能

函数签名 说明
xt_err_t xt_mobile_set_rrcrel(uint8_t sec) 设置 RRC 快速释放时间(0 关闭,1~60 秒)

四、编译配置

宏 默认值 说明
SIM_STATE_GET_CNT_MAX 15 SIM 异常状态连续检测次数阈值
NET_RELEASERRC_TIMEOUT_MIN 1 RRC 释放超时最小值(秒)
NET_RELEASERRC_TIMEOUT_MAX 60 RRC 释放超时最大值(秒)
DUAL_CARD_IND_WAITTING_MS 10000 双卡指示等待超时(毫秒)
XT_MOBILE_TASK_STACK_SIZE 4096 双卡监听任务栈大小(字节)
XT_MOBILE_TASK_PRIORITY osPriorityNormal 双卡监听任务优先级
XT_MOBILE_IMEI_MAX_LEN 16 IMEI 字符串缓冲区长度
XT_MOBILE_CELLINFO_MAX_LEN 10 小区信息最大条数

五、常见模式

5.1 基础使用流程

#include "xt_mobile.h"
// 1. 注册事件回调
static void on_mobile_event(uint32_t event_id, void *param)
{
switch (event_id) {
xt_printf("SIM status changed, slot=%d\n", (int)param);
break;
xt_printf("Network connected\n");
break;
xt_printf("Network lost\n");
break;
xt_printf("Time synced\n");
break;
}
}
void app_init(void)
{
xt_mobile_set_event_cb(on_mobile_event);
// xt_mobile_pre_init 由 INIT_APP_EXPORT 自动调用
}
int xt_printf(const char *fmt,...)
格式化输出
xt_err_t xt_mobile_set_event_cb(xt_mobile_on_event_cb_t on_event_cb)
注册网络事件回调
@ XT_MOBILE_SIM_IND
@ XT_MOBILE_NTP_UPDATE
@ XT_MOBILE_IP_READY
@ XT_MOBILE_IP_LOSE
XTINY 蜂窝网络模块接口

5.2 获取设备信息

char imei[16];
xt_printf("IMEI: %s\n", imei);
char imsi[16];
uint8_t simid = xt_mobile_get_simid();
xt_mobile_get_imsi(simid, imsi);
xt_printf("IMSI: %s\n", imsi);
char iccid[21];
xt_mobile_get_iccid(simid, iccid);
xt_printf("ICCID: %s\n", iccid);
xt_err_t xt_mobile_get_imsi(uint8_t simid, char str_imsi[15+1])
获取 SIM 卡 IMSI
xt_err_t xt_mobile_get_iccid(uint8_t simid, char str_iccid[20+1])
获取 SIM 卡 ICCID
uint8_t xt_mobile_get_simid(void)
获取当前使用的 SIM 卡编号
xt_err_t xt_mobile_get_imei(char str_imei[15+1])
获取设备 IMEI

5.3 查询网络状态与信号

// 网络注册状态
int stat = xt_mobile_get_status();
if (stat == 1 || stat == 5) {
xt_printf("Registered, stat=%d\n", stat);
}
// 信号强度(相对值)
uint8_t csq = xt_mobile_get_csq();
if (csq != 99) {
xt_printf("CSQ: %d/31\n", csq);
}
// 信号质量(真实值)
struct cesq_data cesq = {0};
xt_printf("RSRP=%d dBm, RSRQ=%d dB\n", cesq.rsrp, cesq.rsrq);
xt_err_t xt_mobile_get_cesq_real(struct cesq_data *ptr_data)
获取 CESQ 信号质量(真实值)
uint8_t xt_mobile_get_csq(void)
获取 CSQ 相对值
int xt_mobile_get_status(void)
获取网络注册状态
CESQ 信号质量数据结构体

5.4 SIM 卡管理

// 查询卡状态
if (state == XT_MOBILE_USIM_READY) {
xt_printf("SIM0 ready\n");
} else if (state == XT_MOBILE_USIM_NOT_INSERTED) {
// 尝试切换到 SIM1
}
#define XT_MOBILE_SIM_1
xt_err_t xt_mobile_set_simid(uint8_t simid)
设置当前使用的 SIM 卡
#define XT_MOBILE_USIM_READY
#define XT_MOBILE_SIM_0
#define XT_MOBILE_USIM_NOT_INSERTED
int xt_mobile_get_simstatus(uint8_t simid)
获取 SIM 卡状态

5.5 飞行模式

// 开启飞行模式
// 查询状态
// mode: 0=飞行模式, 1=正常模式, 4=射频关闭
// 关闭飞行模式
int xt_mobile_get_flymode(uint8_t simid)
获取飞行模式状态
xt_err_t xt_mobile_set_flymode(uint8_t simid, uint8_t onoff)
设置飞行模式

5.6 获取服务小区信息

struct scell_info scell = {0};
xt_printf("MCC=%d MNC=%d PCI=%d EARFCN=%d TAC=%d CID=%d\n",
scell.mcc, scell.mnc, scell.pci, scell.earfcn, scell.tac, scell.cid);
xt_printf("RSRP=%d RSRQ=%d RSSI=%d\n", scell.rsrp, scell.rsrq, scell.rssi);
xt_err_t xt_mobile_get_scell(struct scell_info *scell_info)
获取当前服务小区信息
服务小区信息结构体

5.7 异步获取邻近小区

int on_cellinfo(struct cell_info *info)
{
xt_printf("Found %d cells:\n", info->num);
for (int i = 0; i < info->num; i++) {
xt_printf(" [%d] PCI=%d RSRP=%d\n",
i, info->items[i].pci, info->items[i].rsrp);
}
return 0;
}
void scan_cells(void)
{
}
xt_err_t xt_mobile_get_cellinfo_async(xt_mobile_cellinfo_ind_cb_t cb)
异步获取邻近小区信息
邻近小区信息结构体
struct cell_info::@265131021054216162303064070343271254226150236030 items[10/*!< 小区信息最大数量 */]

六、反模式

反模式 问题 正确做法
事件回调中执行阻塞操作 阻塞 SDK 底层线程,导致后续事件丢失 回调仅做标记/发信号量,业务在主线程处理
set_simid 后立即调用 get_imsi 切卡流程未完成,可能返回旧卡信息或失败 等待 XT_MOBILE_SIM_IND 事件后再查询
单卡模式下传入错误的 simid 返回 XT_EINVAL 先用 xt_mobile_get_simid() 获取当前卡槽
轮询 get_simstatus 高频查询 请求通过平台消息通道发送,频繁调用会阻塞其他通信 通过 XT_MOBILE_SIM_IND 事件驱动
不判断 get_csq 返回值 99 99 表示无效值,直接使用无意义 判断 csq != 99 后再使用
对 cesq_data 的 rxlev/ber/rscp/ecno 寄予期望 lm620 上这些字段固定为无效值 仅使用 rsrp/rsrq 字段

七、已知行为与限制

项目 当前平台行为
双卡功能 需平台 NV 配置开启,否则仅单卡
双卡就绪前查询 get_iccid 返回 XT_EBUSY , get_simstatus 返回 XT_MOBILE_USIM_NOT_READY
SIM 异常自动恢复 连续 15 次异常后自动切卡重初始化
cesq_data 的 rxlev/ber/rscp/ecno 固定为 99/99/255/255(不支持)
get_cellinfo 最大条数 XT_MOBILE_CELLINFO_MAX_LEN (10),超过截断
set_rrcrel 范围 1~60 秒,0 关闭快速释放
set_rrcrel(0) 关闭 RRC 快速释放并停止定时器
切卡顺序 关闭射频 → 切换卡槽 → 重新上电,三步串行

八、示例

示例代码位于 examples/network/mobile/。

cd examples/network/mobile
xt --target windows/simulator fullclean build
xt --target windows/simulator run