LISA Modem 组件

ML307 4G/LTE 模块驱动组件,为 ARCS 平台提供基于 AT 命令的蜂窝网络通信能力,支持 TCP/UDP/SSL 连接、DNS 解析,并与 NetDev 抽象层集成实现多网卡管理。

功能特性

  • AT 命令通信: 完整的 AT 命令发送与响应解析框架

  • URC 处理: 自动检测和分发未经请求的结果码(Unsolicited Result Code)

  • TCP/SSL 连接: 支持 TCP 和 SSL/TLS 安全连接

  • UDP 通信: 支持 UDP 数据报收发

  • DNS 解析: 通过 4G 模块进行域名解析

  • 多连接支持: 同时支持 6 个 TCP/UDP 连接(ID 0-5)

  • 网络状态监控: 实时监控网络注册状态和 IP 地址获取

  • 电源管理: 支持休眠模式和模块重启

  • NetDev 集成: 与 SAL 层集成,提供标准 Socket API

  • 线程安全: 所有接口支持多任务并发访问

配置选项

prj.conf 中启用组件:

CONFIG_LISA_MODEM=y              # 启用 LISA Modem 组件
CONFIG_SAL_USING_POSIX=y         # 启用 SAL 套接字抽象层(可选)
CONFIG_LISA_NETWORK=y            # 启用 LISA 网络组件(可选,用于 NetDev 集成)

API 接口

模块初始化

/* 初始化 4G 模块(阻塞式,等待网络就绪) */
int lisa_modem_module_init(void);

TCP 连接

/* 创建 TCP 连接 */
ml307_tcp_t *ml307_tcp_create(at_uart_t *uart, int id);

/* 连接服务器 */
int ml307_tcp_connect(ml307_tcp_t *tcp, const char *host, uint16_t port);

/* 发送数据 */
int ml307_tcp_send(ml307_tcp_t *tcp, const char *data, size_t len);

/* 断开连接 */
int ml307_tcp_disconnect(ml307_tcp_t *tcp);

/* 销毁连接 */
void ml307_tcp_destroy(ml307_tcp_t *tcp);

/* 设置数据接收回调 */
void ml307_tcp_on_stream(ml307_tcp_t *tcp, ml307_on_stream_cb cb, void *user_data);

/* 设置断开连接回调 */
void ml307_tcp_on_disconnected(ml307_tcp_t *tcp, ml307_on_disconnected_cb cb, void *user_data);

UDP 通信

/* 创建 UDP 连接 */
ml307_udp_t *ml307_udp_create(at_uart_t *uart, int id);

/* 连接远程地址 */
int ml307_udp_connect(ml307_udp_t *udp, const char *host, uint16_t port);

/* 发送数据 */
int ml307_udp_send(ml307_udp_t *udp, const char *data, size_t len);

/* 关闭连接 */
int ml307_udp_close(ml307_udp_t *udp);

/* 销毁连接 */
void ml307_udp_destroy(ml307_udp_t *udp);

SSL/TLS 连接

/* 创建 SSL 连接 */
ml307_tcp_t *ml307_tcp_create_ssl(at_uart_t *uart, int id);

/* 连接服务器(使用 SSL) */
int ml307_tcp_connect(ml307_tcp_t *tcp, const char *host, uint16_t port);

DNS 解析

/* 域名解析 */
int ml307_dns_resolve(const char *hostname, char *ip_buf, size_t buf_len);

网络状态

/* 获取网络状态 */
network_status_t ml307_wrapper_get_network_status(ml307_wrapper_t *wrapper);

/* 检查网络是否就绪 */
bool ml307_wrapper_is_network_ready(ml307_wrapper_t *wrapper);

/* 等待网络就绪 */
int ml307_network_check(ml307_wrapper_t *wrapper, uint32_t timeout_ms);

AT 命令接口

/* 发送 AT 命令 */
at_response_t *at_uart_send_command(const char *cmd, uint32_t timeout_ms, bool wait_ok);

/* 设置 URC 回调 */
void at_uart_register_urc_callback(const char *prefix, at_urc_callback_t cb, void *user_data);

/* 启用调试输出 */
void at_uart_set_debug(bool enable);

使用示例

基础初始化示例

#include "lisa_modem.h"
#include "lisa_log.h"

#define LOG_TAG "modem_example"

int modem_init_example(void)
{
    LISA_LOGI(LOG_TAG, "Initializing 4G modem...");

    /* 初始化 4G 模块(阻塞等待网络就绪) */
    int ret = lisa_modem_module_init();
    if (ret != 0) {
        LISA_LOGE(LOG_TAG, "Modem init failed: %d", ret);
        return -1;
    }

    LISA_LOGI(LOG_TAG, "4G modem initialized successfully");
    return 0;
}

TCP 通信示例

#include "ml307_tcp.h"
#include "lisa_log.h"

#define LOG_TAG "tcp_example"

/* 数据接收回调 */
static void on_data_received(const char *data, size_t len, void *user_data)
{
    LISA_LOGI(LOG_TAG, "Received %d bytes: %.*s", (int)len, (int)len, data);
}

/* 连接断开回调 */
static void on_disconnected(void *user_data)
{
    LISA_LOGI(LOG_TAG, "Connection closed");
}

int tcp_example(void)
{
    /* 1. 创建 TCP 连接实例 */
    ml307_tcp_t *tcp = ml307_tcp_create(NULL, 0);
    if (!tcp) {
        LISA_LOGE(LOG_TAG, "Failed to create TCP instance");
        return -1;
    }

    /* 2. 设置回调(连接前设置) */
    ml307_tcp_on_stream(tcp, on_data_received, NULL);
    ml307_tcp_on_disconnected(tcp, on_disconnected, NULL);

    /* 3. 连接服务器 */
    if (ml307_tcp_connect(tcp, "httpbin.org", 80) != 0) {
        LISA_LOGE(LOG_TAG, "Connect failed");
        ml307_tcp_destroy(tcp);
        return -1;
    }

    LISA_LOGI(LOG_TAG, "Connected to server");

    /* 4. 发送 HTTP 请求 */
    const char *request = "GET /get HTTP/1.1\r\n"
                          "Host: httpbin.org\r\n"
                          "Connection: close\r\n\r\n";

    if (ml307_tcp_send(tcp, request, strlen(request)) < 0) {
        LISA_LOGE(LOG_TAG, "Send failed");
    }

    /* 5. 等待响应(回调中处理) */
    lisa_os_thread_sleep(5000);

    /* 6. 断开连接并清理 */
    ml307_tcp_disconnect(tcp);
    ml307_tcp_destroy(tcp);

    return 0;
}

UDP 通信示例

#include "ml307_udp.h"
#include "lisa_log.h"

#define LOG_TAG "udp_example"

/* UDP 数据接收回调 */
static void on_udp_data(const char *data, size_t len, void *user_data)
{
    LISA_LOGI(LOG_TAG, "UDP received: %.*s", (int)len, data);
}

int udp_example(void)
{
    /* 1. 创建 UDP 实例 */
    ml307_udp_t *udp = ml307_udp_create(NULL, 1);
    if (!udp) {
        return -1;
    }

    /* 2. 设置回调 */
    ml307_udp_on_data(udp, on_udp_data, NULL);

    /* 3. 连接远程地址 */
    if (ml307_udp_connect(udp, "time.nist.gov", 37) != 0) {
        ml307_udp_destroy(udp);
        return -1;
    }

    /* 4. 发送数据 */
    ml307_udp_send(udp, "hello", 5);

    /* 5. 等待响应 */
    lisa_os_thread_sleep(3000);

    /* 6. 清理 */
    ml307_udp_close(udp);
    ml307_udp_destroy(udp);

    return 0;
}

SSL/TLS 安全连接示例

#include "ml307_tcp.h"
#include "lisa_log.h"

#define LOG_TAG "ssl_example"

int ssl_example(void)
{
    /* 1. 创建 SSL 连接实例 */
    ml307_tcp_t *ssl = ml307_tcp_create_ssl(NULL, 2);
    if (!ssl) {
        return -1;
    }

    /* 2. 连接 HTTPS 服务器 */
    if (ml307_tcp_connect(ssl, "httpbin.org", 443) != 0) {
        ml307_tcp_destroy(ssl);
        return -1;
    }

    LISA_LOGI(LOG_TAG, "SSL connected");

    /* 3. 发送 HTTPS 请求 */
    const char *request = "GET /get HTTP/1.1\r\n"
                          "Host: httpbin.org\r\n"
                          "Connection: close\r\n\r\n";

    ml307_tcp_send(ssl, request, strlen(request));

    /* 4. 等待响应 */
    lisa_os_thread_sleep(5000);

    /* 5. 清理 */
    ml307_tcp_disconnect(ssl);
    ml307_tcp_destroy(ssl);

    return 0;
}

DNS 解析示例

#include "ml307_dns.h"
#include "lisa_log.h"

#define LOG_TAG "dns_example"

int dns_example(void)
{
    char ip_buf[16];

    /* 解析域名 */
    if (ml307_dns_resolve("www.baidu.com", ip_buf, sizeof(ip_buf)) == 0) {
        LISA_LOGI(LOG_TAG, "Resolved IP: %s", ip_buf);
    } else {
        LISA_LOGE(LOG_TAG, "DNS resolve failed");
        return -1;
    }

    return 0;
}

与 NetDev 集成示例

#include "netdev.h"
#include "lisa_modem.h"
#include "lisa_log.h"

#define LOG_TAG "netdev_modem"

/* 网络状态回调 */
static void on_modem_status(struct netdev *netdev, enum netdev_cb_type type)
{
    switch (type) {
    case NETDEV_CB_STATUS_LINK_UP:
        LISA_LOGI(LOG_TAG, "4G link up");
        break;
    case NETDEV_CB_STATUS_LINK_DOWN:
        LISA_LOGI(LOG_TAG, "4G link down");
        break;
    case NETDEV_CB_STATUS_INTERNET_UP:
        LISA_LOGI(LOG_TAG, "4G internet available");
        break;
    default:
        break;
    }
}

int netdev_modem_example(void)
{
    /* 1. 初始化网络设备子系统 */
    netdev_init();

    /* 2. 初始化 4G 模块 */
    lisa_modem_module_init();

    /* 3. 注册 4G 网络设备(优先级 500,低于 WiFi) */
    app_netdev_register("ml307", 500);

    /* 4. 设置状态回调 */
    struct netdev *modem_dev = netdev_get_by_name("ml307");
    if (modem_dev) {
        netdev_set_status_callback(modem_dev, on_modem_status);
    }

    /* 5. 现在可以使用标准 Socket API */
    /* SAL 层会自动选择可用的网络设备 */

    return 0;
}

架构说明

┌─────────────────────────────────────────────────────────┐
│                   应用层 (Application)                   │
│     HTTP Client / MQTT Client / Custom Protocols        │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│              ml307_wrapper.h/c (高级管理层)              │
│   - 模块初始化与重启                                     │
│   - 网络注册监控 (+CREG URC)                            │
│   - PDP 上下文管理 (+MIPCALL URC)                       │
│   - 连接工厂 (TCP/SSL)                                  │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│         ml307_tcp.h/c  &  ml307_udp.h/c (连接层)        │
│   - 连接生命周期管理 (connect/disconnect)               │
│   - 数据传输(自动 Hex 编码)                           │
│   - URC 处理 (MIPOPEN, MIPCLOSE, MIPSEND, MIPURC)      │
│   - 流数据与断开回调                                    │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│                at_uart.h/c (AT 命令层)                   │
│   - 命令/响应同步 (EventGroups)                         │
│   - URC 解析与分发                                      │
│   - 参数解析 (string/int/double)                        │
│   - 动态缓冲区管理                                      │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│              lisa_uart (ARCS SDK UART 驱动)              │
└─────────────────────────────────────────────────────────┘

支持的 AT 命令

命令

说明

AT+CREG

网络注册状态查询

AT+MIPCALL

PDP 上下文激活/查询

AT+MIPOPEN

打开 TCP/UDP 连接

AT+MIPCLOSE

关闭连接

AT+MIPSEND

发送数据

AT+MDNSGIP

DNS 域名解析

AT+CSQ

信号强度查询

AT+CPIN

SIM 卡状态查询

AT+COPS

运营商查询

性能参数

参数

数值

模块初始化时间

3-5 秒

网络注册时间

5-30 秒(取决于信号)

TCP 连接时间

1-10 秒

数据发送延迟

100-500ms

数据接收延迟

100-500ms

最大连接数

6 个(ID 0-5)

单包最大数据

730 字节

内存占用

模块

内存

at_uart

~8KB(缓冲区 + 实例)

ml307_tcp

~2KB / 连接

ml307_wrapper

~1KB

总计

~11KB + (2KB × 连接数)

使用注意事项

  1. 初始化顺序: 必须先调用 lisa_modem_module_init() 初始化模块

  2. 回调设置: 必须在 connect 之前设置数据接收回调

  3. 连接 ID: 使用 0-5 的连接 ID,不同连接使用不同 ID

  4. 数据分包: 大数据自动分包(730 字节/包),无需手动处理

  5. Hex 编码: 数据传输自动进行 Hex 编码/解码

  6. 回调上下文: URC 回调在 UART 任务上下文中执行,回调函数应尽快返回

  7. 网络状态: 发起连接前应确认网络已就绪

  8. 资源释放: 使用完毕后调用 destroy 函数释放资源

  9. 调试模式: 调用 at_uart_set_debug(true) 可查看 AT 命令交互日志

  10. 线程安全: 所有接口线程安全,可在多任务环境中使用

故障排查

模块无响应

/* 启用调试查看 AT 交互 */
at_uart_set_debug(true);

/* 尝试重启模块 */
ml307_wrapper_reboot(modem);
lisa_os_thread_sleep(5000);

网络注册失败

/* 检查 SIM 卡 */
at_uart_send_command("AT+CPIN?", 1000, true);

/* 检查信号强度 */
at_uart_send_command("AT+CSQ", 1000, true);

/* 检查运营商 */
at_uart_send_command("AT+COPS?", 1000, true);

TCP 连接失败

  • 确认网络已就绪:ml307_wrapper_is_network_ready()

  • 检查连接 ID 是否冲突(0-5)

  • 验证服务器地址和端口

  • 信号弱时增加超时时间

文件说明

  • include/lisa_modem.h - 模块主头文件

  • include/ml307_tcp.h - TCP/SSL 连接接口

  • include/ml307_udp.h - UDP 连接接口

  • include/ml307_wrapper.h - 高级管理接口

  • include/at_uart.h - AT 命令接口

  • src/ml307_tcp.c - TCP/SSL 实现

  • src/ml307_udp.c - UDP 实现

  • src/ml307_wrapper.c - 模块管理实现

  • src/at_uart.c - AT 命令实现

  • sal/netdev_at.c - NetDev 适配层实现

  • Kconfig - 组件配置选项

  • CMakeLists.txt - 构建配置