跳转至

指令层描述

指令层是 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 0x08 result 回调返回匹配的 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 时不需特殊处理.

问一下 AI