mkyx-001/cellular_modem

1.2.0

Latest
uploaded 1 day ago
USB RNDIS cellular modem driver (AT control + RNDIS data plane)

Readme

# cellular_modem

USB RNDIS 蜂窝模组驱动组件(ESP-IDF / ESP32-S2 · S3 · P4)。

该组件提供:
- RNDIS 数据面接入(`esp_netif`)
- CDC AT 控制面(自动拨号、APN 识别、状态监控)
- 连接看门狗与自动恢复逻辑
- 可选数据面诊断(DNS/ICMP/TCP)

> 当前默认参数针对常见 USB 蜂窝模组场景,USB VID/PID 可通过配置注入,便于跨项目复用。

## 目录结构

```text
cellular_modem/
├── CMakeLists.txt
├── Kconfig
├── idf_component.yml
├── cellular_modem.c
└── include/
    └── cellular_modem.h
```

## 依赖

- ESP-IDF `>= 5.0`
- `espressif/usb`
- `espressif/iot_usbh_rndis`

`idf_component.yml` 已声明依赖,使用组件管理器时会自动拉取。

## 快速开始

### 1) 在项目中添加依赖

如果你从 ESP Component Registry 引用:

```yaml
dependencies:
  mkyx-001/cellular_modem: "^1.1.0"
```

### 2) 初始化与拨号

```c
#include "cellular_modem.h"

void app_main(void)
{
    cell_modem_hw_config_t hw = {
        .rst_gpio = GPIO_NUM_22,
        .usb_peripheral_map = BIT1,   // ESP32-P4 FS PHY 常见配置
        .usb_vid = 0,                 // 0 = 使用组件默认值
        .usb_pid_rndis = 0,           // 0 = 使用组件默认值
        .usb_pid_composite = 0,       // 0 = 使用组件默认值
    };

    cell_modem_config_t cfg = {
        .at_interface_num = 2,
        .auto_configure_rndis = false,
        .auto_activate_pdp = true,
        .apn = NULL,                  // NULL = 自动识别运营商 APN
        .enable_diag = true,
        .diag_tcp_host = NULL,        // 可选,如 "example.com"
        .diag_tcp_port = 443,
    };

    // 可选:提前硬复位,加快上电收敛
    cell_modem_early_hardware_reset(hw.rst_gpio);

    ESP_ERROR_CHECK(cell_modem_init(&hw, &cfg));

    // 阻塞等待蜂窝数据就绪
    if (cell_modem_wait_for_pdp_ready(120000)) {
        // Ready
    } else {
        // Timeout
    }
}
```

## 例程

仓库根目录提供最小可运行例程:

- `examples/cellular_modem_basic`

运行方式:

```bash
cd examples/cellular_modem_basic
idf.py set-target esp32p4
idf.py build flash monitor
```

如你的复位引脚不是 GPIO22,可在 `examples/cellular_modem_basic/main/main.c` 中修改
`CELL_MODEM_RST_GPIO`。

## 主要 API

- `cell_modem_init()`: 初始化组件并启动后台监控
- `cell_modem_deinit()`: 反初始化并释放资源
- `cell_modem_get_state()`: 查询当前状态
- `cell_modem_get_net_info()`: 获取 RNDIS IP/网关等信息
- `cell_modem_is_connected()`: 是否已获得本地 IP
- `cell_modem_is_pdp_ready()`: 是否蜂窝数据面就绪
- `cell_modem_wait_for_pdp_ready()`: 阻塞等待就绪
- `cell_modem_register_status_callback()`: 注册状态回调
- `cell_modem_get_signal_strength()`: 获取 CSQ 信号值
- `cell_modem_is_data_path_ok()`: 数据面是否已验证可达(TCP/ICMP 探针通过,区别于 `is_pdp_ready()` 的 AT 拨号成功)

详细类型与注释见 `include/cellular_modem.h`。

## Kconfig

菜单路径:
- `Cellular Modem (USB RNDIS)`

参数:
- `CELL_MODEM_DEFAULT_APN`
  - 当 IMSI/COPS 无法识别运营商时的默认 APN(默认 `3gnet`)

## 常见问题

- 启动后长时间未就绪:
  - 检查 USB 供电与数据线
  - 检查 `rst_gpio` 和模组复位时序
  - 检查 SIM 卡状态和天线
  - 按需显式设置 `cfg.apn`
- RNDIS 有 IP 但业务不通:
  - 打开 `enable_diag`
  - 配置 `diag_tcp_host` 验证业务目标连通性
  - 用 `cell_modem_is_data_path_ok()` 判断真实上下行可达(区别于 `cell_modem_is_pdp_ready()`)

## 已知限制(Known Limitations)

- **SIM 卡热插拔检测仅复合模式支持**
  - `auto_configure_rndis=false`(复合模式,RNDIS + AT CDC 共存)时,monitor 任务会周期发 `AT+CPIN?` 复检 SIM 在位状态,连续 3 次失败才认定 SIM 丢失(避免小区切换瞬态误报)。
  - `auto_configure_rndis=true`(纯 RNDIS 模式)时,模式切换后 AT CDC 接口消失,CPIN 与 CSQ 周期查询均不可用。此模式下 SIM 拔插需通过硬复位或上电重启感知。
- **信号丢失但 RNDIS 链路未断时的自愈**
  - 数据面诊断(`enable_diag=true` + `diag_tcp_host` 配置)启用后,diag 任务会在首次通过后以 60s 周期复查数据面;复查失败时降级状态并触发 4G 看门狗硬复位,信号恢复后自动重拨。
  - 未启用数据面诊断时,信号差但 RNDIS 链路未断且 DHCP 租约仍存的场景下,组件无法感知数据面失效,需外部重启或开启诊断。
- **看门狗触发硬复位会断开当前所有 TCP 连接**:30s 无连接即复位模组,量产场景需评估上层业务的断连重连能力。

## 版本发布建议

- 使用 SemVer 版本号(`major.minor.patch`)
- 每次发布前更新 `idf_component.yml` 中的 `version`
- 上传命令:

```bash
compote component upload --namespace mkyx-001 --name cellular_modem
```

## License

Apache-2.0,见 `LICENSE`。

Links

To add this component to your project, run:

idf.py add-dependency "mkyx-001/cellular_modem^1.2.0"

download archive

Stats

  • Archive size
    Archive size ~ 36.39 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

mkyx-001/cellular_modem version: 1.2.0
|