1、开发环境准备(这里直接参考域格资料中心)
2、VSIM 初始化模块
VSIM(虚拟 SIM 卡)初始化是网络连接的前提,需要完成 AON 电源配置、SIM 检测引脚初始化和 VSIM 状态同步。域格sdk内部集成了vsim卡得库得,只需要调api就能注册vsim。
static void vsim_init_once(void) { yopen_aon_power_on(); yopen_gpio_init(SIM_DET_PORT, GPIO_INPUT, FORCE_PULL_UP, LVL_HIGH); vsim_init(); while (vsim_status_progress() != 100) { yopen_rtos_task_sleep_ms(1000); } }关键 API 说明:
| API | 功能 | 说明 |
|---|---|---|
| yopen_aon_power_on() | 开启 AON 电源域 | AON(Always On)域保证休眠期间关键外设供电 |
| yopen_gpio_init() | 初始化 SIM 检测引脚 | 使用 GPI_1 引脚,上拉输入模式 |
| vsim_init() | 初始化 VSIM 模块 | 启动虚拟 SIM 卡服务 |
| vsim_status_progress() | 获取初始化进度 | 返回 0-100,100 表示完成 |
注意事项:
我这里用得优克联VSIM虚拟卡,sdk需要对应编译项目修改cmake 文件。有对应三个vsim得配置
# vsim 配置
#set(VSIM_NAME "VSIM_TGT")
#set(VSIM_NAME "VSIM_YSM")
set(VSIM_NAME "VSIM_UC")
3、TCP 长连接模块
TCP 连接建立包括域名解析、Socket 创建、绑定本地端口和连接服务器四个步骤。
static int tcp_connect(void) { int ret, socket_fd = -1; struct sockaddr_in local4, server_ipv4; struct addrinfo *addr = NULL; ret = lwip_getaddrinfowithcid(TEST_SOCKET_SERVER, NULL, NULL, &addr, 1); if (!addr) return -1; socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (socket_fd < 0) goto fail; memset(&local4, 0, sizeof(local4)); local4.sin_family = AF_INET; local4.sin_port = 1000; bind(socket_fd, (struct sockaddr *)&local4, sizeof(local4)); struct sockaddr_in *sin_res = (struct sockaddr_in *)addr->ai_addr; memset(&server_ipv4, 0, sizeof(server_ipv4)); server_ipv4.sin_family = addr->ai_family; server_ipv4.sin_port = htons(TEST_SOCKET_TCP_PORT); server_ipv4.sin_addr = sin_res->sin_addr; ret = connect(socket_fd, (struct sockaddr *)&server_ipv4, sizeof(server_ipv4)); if (ret < 0) goto fail; freeaddrinfo(addr); return socket_fd; fail: if (addr) freeaddrinfo(addr); if (socket_fd >= 0) close(socket_fd); return -1; }关键 API 说明:
| API | 功能 | 说明 |
|---|---|---|
| lwip_getaddrinfowithcid() | 域名解析 | 参数 cid=1 指定使用 PS 域进行解析 |
| socket() | 创建 Socket | AF_INET + SOCK_STREAM + IPPROTO_IP |
| bind() | 绑定本地端口 | 绑定端口 1000,便于服务端识别 |
| connect() | 连接服务器 | 连接到指定 IP 和端口 |
3、 休眠配置模块
休眠配置是实现低功耗的核心,需要按照 禁止休眠 → 设置深度 → 允许休眠 的顺序操作
yopen_autosleep_enable(YOPEN_NOT_ALLOW_SLEEP); yopen_set_sleep_depth(YOPEN_SLP_SLP1_STATE); yopen_rtos_task_sleep_ms(5000); yopen_autosleep_enable(YOPEN_ALLOW_SLEEP);4、完整代码
适用于物联网低功耗场景,模块在休眠状态下保持 TCP 长连接,可被网络数据或按键唤醒。
void sleep_key_demo_thread(void *arg) { int socket_fd; yopen_nw_reg_status_info_s nw_status; vsim_init_once(); do { yopen_nw_get_reg_status(0, &nw_status); yopen_rtos_task_sleep_ms(1000); } while (!(nw_status.data_reg.state == YOPEN_NW_REG_STATE_HOME_NETWORK || nw_status.data_reg.state == YOPEN_NW_REG_STATE_ROAMING)); socket_fd = tcp_connect(); if (socket_fd < 0) { yopen_rtos_task_delete(NULL); return; } yopen_autosleep_enable(YOPEN_NOT_ALLOW_SLEEP); yopen_set_sleep_depth(YOPEN_SLP_SLP1_STATE); yopen_rtos_task_sleep_ms(5000); yopen_autosleep_enable(YOPEN_ALLOW_SLEEP); while (1) { yopen_rtos_task_sleep_ms(60000); } close(socket_fd); yopen_rtos_task_delete(NULL); } application_init(sleep_key_demo_thread, "SLEEP_KEY", 12, 4, NULL);