# 4G模块固件文档(AIR724 + LuatOS-Air) ## 概述 基于 **AIR724(RDA8910)** 4G模块 + **LuatOS-Air** 固件平台,运行 Lua 脚本实现多路 TCP Socket 管理、串口命令解析转发、SIM卡查询等功能。 | 项目 | 说明 | |------|------| | 硬件平台 | AIR724 (RDA8910) | | 固件平台 | LuatOS-Air V4035 | | 底层固件 | `LuatOS-Air_V4035_RDA8910_BT_FLOAT.pac` | | 量产文件 | `4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.pac` | | OTA升级文件 | `4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.dfota.bin` | | 开发语言 | Lua 5.3 | | 串口参数 | 115200, 8N1 | --- ## 目录结构 ``` 4G/ ├── 已编译量产文件/ ← 可直接用于烧录和OTA升级 │ ├── 4G量产文件/ │ │ └── 4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.pac │ │ └── 量产烧录文件(底层固件 + 脚本合包,一键烧录) │ │ │ └── 4G远程升级文件/ │ └── 4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.dfota.bin │ └── OTA差分升级文件(用于远程空中升级) │ ├── 源代码/ ← 源码 + 开发用底层固件 │ ├── bin/ │ │ └── LuatOS-Air_V4035_RDA8910_BT_FLOAT.pac ← 底层固件(开发调试用) │ │ │ └── core/ ← 核心脚本(需烧录到模块) │ ├── main.lua ← 入口:初始化硬件、网络、串口 │ ├── cmd.lua ← 命令解析与分发 │ └── linksocket.lua ← 多路TCP Socket管理 │ ├── 烧写工具/ │ └── Luatools_v3.exe ← LuatOS官方烧录工具 │ └── lib/ ← LuatOS-Air 标准库(模块内置,无需烧录) ├── sys.lua ← 系统核心(任务调度、定时器) ├── log.lua ← 日志 ├── uart.lua ← 串口驱动 ├── socket.lua ← TCP/UDP Socket ├── socket4G.lua ← 4G Socket适配层 ├── net.lua ← 网络管理 ├── sim.lua ← SIM卡管理 ├── ril.lua ← AT命令接口 ├── pm.lua ← 电源管理 └── ...(共约50个标准库) ``` --- ## 核心脚本说明 ### 1. main.lua — 程序入口 **文件**:[源代码/core/main.lua](file:///d:/公司项目/BR_YKC/4G/源代码/core/main.lua) 启动流程: ``` main.lua 加载 ↓ require "sys" / "net" / "log" / "uart" / "netLed" / "pmd" ↓ uart.setup(1, 115200, 8, uart.PAR_NONE, uart.STOP_1) ← 初始化UART1 ↓ pmd.ldoset(2, pmd.LDO_VLCD) ← 开启网络指示灯电源 netLed.setup(true, pio.P0_1, pio.P0_4) ← 配置指示灯GPIO ↓ net.startQueryAll(8 * 1000, 60 * 1000) ← 启动网络注册(超时8s/间隔60s) ril.request("AT+RNDISCALL=0,1") ← 激活数据链路(RNDIS) ↓ require "cmd" ← 加载命令解析模块 require "linksocket" ← 加载Socket管理模块 ↓ linksocket.setRecvCallback(...) ← 注册TCP数据接收回调 uart.on(1, "receive", ...) ← 注册串口接收回调 ↓ sys.init(0, 0) sys.run() ← 启动系统(永不返回) ``` **串口数据流**: ``` STM32 → UART1 → cmd.process(rawData) ← STM32发来的命令帧 ↓ 解析55 AA帧头 ↓ 调用对应的handleCmdXX ↓ linksocket.connect/send/disconnect ↓ 4G → TCP → 云快充服务器 云快充服务器 → TCP → 4G → recvCallback(socketId, data) ↓ 组装 55 AA 01 socketId len data AA 55 ↓ UART1 → STM32 ← 下行数据转发 ``` ### 2. cmd.lua — 命令解析与分发 **文件**:[源代码/core/cmd.lua](file:///d:/公司项目/BR_YKC/4G/源代码/core/cmd.lua) 负责解析 STM32 通过 UART1 发来的 `55 AA` 帧格式命令,并调用 linksocket 接口或系统接口。 #### 帧格式 ``` 55 AA mainCmd subCmd [payload] AA 55 ``` #### 命令表 | mainCmd | subCmd | 处理函数 | 功能 | |---------|--------|----------|------| | 0x01 | socketId | `handleCmd01` | 数据发送到指定Socket。失败回复 `0x83 03 socketId 01` | | 0x02 | - | `handleCmd02` | 系统重启 (`sys.restart()`) | | 0x03 | 0x01 | `handleCmd03` | 连接Socket。调用 `linksocket.connectSocket(socketId)` | | 0x03 | 0x02 | `handleCmd03` | 断开Socket。调用 `linksocket.disconnectSocket(socketId)` | | 0x04 | 0x00 | `handleCmd04` | 设置服务器地址。回复 `0x87 00 00/01` | | 0x05 | 0x01 | `handleCmd05` | 查询ICCID。回复 `0x84 01 len iccid` | | 0x05 | 0x02 | `handleCmd05` | 查询IMSI。回复 `0x84 02 len imsi` | | 0x05 | 0x03 | `handleCmd05` | 查询IMEI。回复 `0x84 03 len imei` | | 0x06 | 0x00 | `handleCmd06` | 查询信号强度CSQ。回复 `0x85 01 csq ber` | | 0x07 | 0x00 | `handleCmd07` | 查询6个Socket链路状态。回复 `0x86 01 [6字节状态]` | #### 上行响应帧 | mainCmd | subCmd | 含义 | 触发时机 | |---------|--------|------|----------| | 0x83 | 0x01 | **TCP已连接** | Socket连接成功 | | 0x83 | 0x02 | **TCP已断开** | Socket断开/掉线 | | 0x83 | 0x03 | **TCP连接失败** | Socket连接失败/发送失败 | | 0x84 | 0x01~0x03 | SIM信息 | 查询ICCID/IMSI/IMEI结果 | | 0x85 | 0x01 | 信号强度 | 查询CSQ结果 | | 0x86 | 0x01 | 链路状态 | 查询6路Socket状态 | | 0x87 | 0x00 | 服务器配置结果 | 设置服务器地址结果 | #### 帧缓冲机制 `cmd.lua` 内部维护 `frameBuffer` 字符串,处理串口数据粘包/拆包: ``` process(rawData) → frameBuffer.append ↓ while true: 查找 55 AA ... AA 55 完整帧 找到 → 提取mainCmd/subCmd/payload → 分发处理 未找到 → 继续等待更多数据 非55AA开头 → 跳过1字节 ``` ### 3. linksocket.lua — 多路TCP Socket管理 **文件**:[源代码/core/linksocket.lua](file:///d:/公司项目/BR_YKC/4G/源代码/core/linksocket.lua) 管理 **6路独立TCP Socket**(对应STM32侧的6个充电桩),每路Socket有独立的任务循环。 #### 结构 ```lua local clients[6] = { { id = 1, socket = nil, connected = false }, { id = 2, socket = nil, connected = false }, ... } ``` #### 每个Socket的任务循环 ``` 等待 connectRequested[id] == true ↓ 等待网络就绪(socket.isReady()) + SIM卡正常(sim.getStatus()) ↓ socket.tcp():connect(server_config.ip, server_config.port) ↓ 失败 → 上报 0x83 03 socketId 1 ↓ 成功 → 上报 0x83 01 socketId 0 → 进入监控循环 ↓ 监控:asyncSelect(60, "recv") 60秒超时检测 ├── 正常 → 继续 ├── 超时/掉线 → 上报 0x83 02 socketId 0 → 回到顶部 ├── SIM卡拔出 → 上报 0x83 02 socketId 3 → 回到顶部 └── 收到断开命令 → 上报 0x83 02 socketId 0 → 回到顶部 ``` #### 外部接口 | 函数 | 说明 | |------|------| | `connectSocket(id)` | 标记id为待连接,触发对应Socket任务 | | `disconnectSocket(id)` | 标记id为待断开,关闭Socket | | `sendToSocket(id, data)` | 在已连接的Socket上发送数据 | | `setServerAddress(ip, port)` | 设置服务器地址(断开所有已连接Socket) | | `getLinkStatus()` | 获取6路Socket连接状态 | | `setRecvCallback(cb)` | 注册数据接收回调 | #### 服务器配置 默认在文件顶部配置: ```lua local server_config = { ip = "129.211.170.245", port = 9002 } ``` 可通过 `0x04` 命令动态修改(由 `drv_air724_set_server` 触发)。 --- ## 数据流完整路径 ### 上行(桩 → 云快充) ``` 充电桩 → UDP → STM32(task_ykc) ↓ charger_to_server_0Xxx() 组YKC帧 ↓ drv_air724_send_cmd(0x01, socketId, ykc_frame) ↓ UART1 → 55 AA 01 socketId len [ykc_frame] AA 55 ↓ AIR724 cmd.lua: handleCmd01(socketId, ykc_frame) ↓ linksocket.sendToSocket(socketId, ykc_frame) ↓ TCP → 云快充服务器 ``` ### 下行(云快充 → 桩) ``` 云快充服务器 → TCP → AIR724 ↓ linksocket 接收回调 ↓ 55 AA 01 socketId len [ykc_frame] AA 55 → UART1 ↓ STM32 task_air724: 解析 → ykc_route_dispatch ↓ server_to_charger.c: on_cmd_frame_type_0Xxx() ↓ 填充 g_charger_manager 结构体 / 点对点回复桩 ``` --- ## 烧写说明 AIR724 模块使用 **Luatools** 工具进行固件和脚本烧录。 ### 准备工作 1. **打开烧写工具** - 工具位置:`4G/烧写工具/Luatools_v3.exe` - 双击打开即可 2. **硬件连接** - 使用 **Type-C USB 线** 将 AIR724 模块连接到电脑 - 模块上电后,电脑会出现 **3 个新的 COM 口** ### 量产烧录(编译好的文件直接烧录) 量产文件已预先编译好,位于 `4G/已编译量产文件/4G量产文件/`,可直接烧录: 1. 打开 `Luatools_v3.exe` 2. 点击 **`下载固件`** 按钮 3. 等待官方文件下载完毕 4. 点击 **`选择文件`** 按钮, 选择**量产文件** - 文件路径:`4G/已编译量产文件/4G量产文件/4G_NETWORK_1.0.0_LuatOS-Air_V4035_RDA8910_BT_FLOAT.pac` 5. 点击 **`下载`** 6. 工具会自烧录,完成后会有提示 > **提示**:量产文件是将底层固件和 Lua 脚本打包为一个 `.pac` 文件,一次性烧录,无需分两步操作。 ### 开发调试烧录(自己修改代码后测试) 修改 Lua 代码后的开发调试阶段: 1. **创建项目** - 点击左下角的 **`创建项目`** 新建项目 2. **选择底层固件**(仅首次需要): - 点击 **`选择文件`** 按钮 - 选择底层Core文件:`4G/源代码/bin/LuatOS-Air_V4035_RDA8910_BT_FLOAT.pac` 2. **选择脚本**(每次修改代码后): - 点击 **`增加目录(递归)`** 按钮 - **选择脚本目录**:`4G/源代码/core/`(工具自动识别 `main.lua`、`cmd.lua`、`linksocket.lua`) - **选择lib目录**:`4G/源代码/lib/`(必选,用于包含外部库文件) - 点击 **`下载脚本`**(固件版本不变时)或 **`下载底层和脚本`**(全刷) ## 两种烧录方式对比 | 方式 | 适用场景 | 文件 | 操作 | |------|----------|------|------| | **量产烧录** | 批量生产、出厂烧录 | `.pac` 量产文件 | Luatools → 量产管理 → 开始烧录 | | **开发调试** | 修改Lua代码后测试 | 底层固件 `.pac` + `core/`+ `lib/` 脚本目录 | 项目管理测试 → 下载脚本 |