314 lines
11 KiB
Markdown
314 lines
11 KiB
Markdown
|
|
# 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/` 脚本目录 | 项目管理测试 → 下载脚本 |
|