指令层描述
指令层是 AirLink 的语义核心. 每条指令以 (cmd_id, len, data) 三元组表达, 通过链路层传输.
C 语言描述
来源:
components/airlink/include/luat_airlink.h:37-42
typedef struct luat_airlink_cmd {
uint16_t cmd; // 命令 id, 范围 0x0001–0xFFFE, 0x0000/0xFFFF 保留
uint16_t len; // 数据长度, 实际使用最大 ≈ 2K
uint8_t data[0];
} luat_airlink_cmd_t;
字段描述
| 字段 | 长度 | 含义 |
|---|---|---|
| cmd | 2B | 指令 id, 高 8 位是分类 id, 低 8 位是指令编号; 范围 0x0001–0xFFFE, 0x0000 和 0xFFFF 不允许使用 |
| len | 2B | data 字段长度; 单 cmd 实际最大 ≤ 1500 字节, 超过需用 cmd 0x32 分片 |
| data | NB | 指令数据, 可以是 0 长度; 内容格式由 cmd 决定 |
编号规则
- 高 8 位 (bits 8-15): 分类 id, 例如
0x10= 设备信息,0x30= RPC,0x100= IP 包 - 低 8 位 (bits 0-7): 该分类下的具体指令
- 例如:
0x300= GPIO 分类的第 0 号指令 (setup);0x301= GPIO 分类的第 1 号指令 (set);0x311= GPIO 分类的第 17 号指令 (irq 回调)
指令 ID 分配总表
来源:
components/airlink/src/luat_airlink_cmds.c:113-215(权威命令分发表)
| 范围 | 类别 | 文档 |
|---|---|---|
| 0x01–0x02 | 链路基础 (ping/pong) | 基础指令 |
| 0x03 | 链路基础 (reset) | 基础指令 |
| 0x04–0x07 | FOTA 远程升级 | FOTA |
| 0x08 | 链路基础 (result 异步响应) | 基础指令 |
| 0x10 | 设备信息 dev_info | 基础指令 |
| 0x20 | 自定义数据 sdata | 通知与日志 |
| 0x21 | 自测 nop | 通知与日志 |
| 0x30 | 通用 nanopb RPC | 通用 RPC |
| 0x32 | cmd 分片重组 | 分片重组 |
| 0x80 | 系统通知 sys_pub | 通知与日志 |
| 0x81 | 日志透传 log | 通知与日志 |
| 0x100 | IP/MAC 包透传 | IP包指令 |
| 0x200–0x208 | WLAN 操作 | WLAN指令 |
| 0x300–0x311 | GPIO 操作 | GPIO指令 |
| 0x400–0x411 | UART 操作 | UART指令 |
| 0x500–0x511 | BT 操作 | BT指令 |
| 0x600–0x602 | PM 功耗控制 | PM指令 |
| 0x700–0x701 | PWM 操作 | PWM指令 |
| 0x800–0x803 | MOBILE (IMEI/IMSI/ICCID/MUID) | MOBILE指令 |
| 0x900–0x904 | OTP 读写 | OTP指令 |
数据要求
来源:
components/airlink/include/luat_airlink.h:31-34,src/luat_airlink_rpc.c,src/driver/luat_airlink_drv_*.c
seq_id 头
所有 driver 类指令 (GPIO/UART/WLAN/BT/PM/PWM/MOBILE/OTP) 的 data 字段前 8 字节是 seq_id (uint64_t, 小端, 单调递增).
- 来源:
luat_airlink_get_next_cmd_id()(src/luat_airlink.c) - 用途: 对端通过 cmd
0x08result 回调返回匹配的 seq_id, 客户端据此唤醒等待的协程/信号量
payload 格式示例 (以 GPIO set 0x301 为例):
[0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01] [pin:1] [level:1]
\_____________ seq_id = 1 _____________/
详见各 cmd_*.md 子文件的字段表.
payload 长度限制
| 场景 | 长度 |
|---|---|
| SPI 物理层单事务 | 固定 1600 字节 |
| 链路层头 (magic + len + crc16 + pkgid + flags) | 12 字节 |
| 指令层头 (cmd + len) | 4 字节 |
单 cmd 的 data 最大长度 |
≤ 1584 字节 (实际使用上限 1500) |
| 含 8 字节 seq_id 的 driver payload | ≤ 1576 字节 |
| cmd 0x32 分片单片最大 | AIRLINK_FRAG_MAX_DATA_LEN = 1580 |
| cmd 0x32 重组后总长上限 | 0xFFF0 (65520 字节) |
| cmd 0x30 RPC 单 payload 上限 | AIRLINK_RPC_MAX_PAYLOAD = 4096 |
长度溢出处理
- 调用方应预留判断; payload 超 1580 字节时, 自动用 cmd 0x32 分片
- 链路层不实现自动重传, 丢包由上层业务重试
- 0x0000 / 0xFFFF 是保留 cmd id, 收到应直接忽略
异步响应机制
cmd 0x08 是统一的异步结果响应通道:
[new_pkgid : 8B] // 本端 next_pkg_id
[req_pkgid : 8B] // 来自原始请求的 seq_id
[result_code: 2B] // 大端, 0 = 成功, 负值 = 错误码
[resp_payload: NB] // 业务响应数据 (可选)
| 模式 | 行为 |
|---|---|
| RPC (cmd 0x30) | 由 luat_airlink_result_send() 自动填充 [req_pkgid + result_code + payload], 系统再加 8 字节 new_pkgid 前缀 (src/luat_airlink.c:1094-1103) |
| raw driver | 调用方拼好 [req_pkgid + result_code + resp], 传入 luat_airlink_result_send() |
接收端用 req_pkgid 在 64 槽位 luat_airlink_result_reg_t 表中查找等待者, 唤醒对应信号量或协程 (src/luat_airlink.c:999-1092).
不支持的指令
对未实现的 cmd id, 应直接忽略, 不回响应. 这保证不同芯片/固件版本之间的兼容性 — 旧版本收到新版本新增的 cmd 时不会崩溃, 新版本收到旧版本未实现的 cmd 时不需特殊处理.