生产测试与射频工具
本页介绍 AC79 AIoT SDK 中面向产线测试(MP Test)与射频(RF)验证的工具组件:wifi_story_machine 应用内的 RF 测试模式框架(WiFi/BT 产测)、RF 功率配置项、RF 校准代码(RF trim)的链接与 Bank 切换机制,以及基于 UDP 命令和 iPerf 的产测控制与吞吐量测试工具。
目的与范围
本页覆盖 AC79NN SDK 中"生产测试与射频工具"这一能力的完整实现,包括:
- RF 测试模式框架:
apps/wifi_story_machine/wifi_app_task.c中定义的 8 种测试模式(关闭、WiFi 产测、STA 测试、AP 测试、BT DUT、BT FCC、BT BQB、RF 多合一)及其通过 UDP 命令切换的机制; - 产测开关:
CONFIG_MP_TEST_ENABLE宏控制的产测行为(如 STA 测试模式下请求连接的抑制); - RF 功率配置:
apps/common/config/user_cfg.c中CFG_BT_RF_POWER_ID/CFG_BLE_RF_POWER_ID的读取路径; - RF 校准代码放置:
CONFIG_RF_TRIM_CODE_AT_RAM、CONFIG_RF_TRIM_CODE_MOVABLE、CONFIG_BANK_NUM_RF_TRIM等宏如何决定*.rf.text.cache.L2.rf_trim代码段的位置; - 网络吞吐测试:借助 iPerf 的 UDP/TCP 吞吐量测试工具入口。
与射频收发信机(RF 芯片寄存器级驱动)、协议栈细节(WiFi/BT 协议实现)相关的主题不在本页范围,属于协议/驱动类目。产线烧录(Downloader)与量产固件打包工具也不在本页范围。
概述
在消费级 AIoT 设备的量产流程中,每一台出厂的设备都需要经过射频性能与功能测试:验证 WiFi 能否正常收发、BT 能否进入 DUT/FCC/BQB 测试模式、吞吐量是否达标、RF 功率是否符合校准值等。这些测试通常由上位机(PC 产测软件)通过 UART/UDP 向设备下发命令,设备端固件解析命令后切换到对应的测试模式。
AC79 AIoT SDK 将这套产测框架放在 WiFi 故事机参考应用(apps/wifi_story_machine)中实现,核心设计为:
- 集中式模式寄存器:一个
wifi_app_hdl全局句柄中的rf_test_mode位域保存当前测试模式,所有功能模块按此状态决定行为; - UDP 命令通道:产测上位机通过 UDP 报文下发模式切换命令,设备在应用任务中解析并落盘到
rf_test_mode; - 模式与行为解耦:
WIFI_AP_TEST_MODE启动 AP + UDP Server,WIFI_STA_TEST_MODE连接指定 SSID 并启动 UDP Server,BT 模式进入协议栈测试状态; - 可裁剪的代码放置:RF 校准(RF trim)代码可通过编译宏放置于 RAM、可搬移区(movable slot)或 flash,并支持 Bank 切换,以便在产测时保证时序与存储布局灵活可控。
架构
下图展示了产测与射频工具的整体架构及各组件间的关系:
flowchart TD
subgraph sg_Host["上位机(产测软件)"]
PC["PC Test Tool"]
end
subgraph sg_Device["设备端固件"]
subgraph sg_App["wifi_story_machine 应用"]
UDP["UDP 命令接收/解析"]
HDL["wifi_app_hdl<br/>(rf_test_mode 位域)"]
TASK["wifi_app_task<br/>模式分发"]
end
subgraph sg_TestMode["测试模式"]
M0["RF_TEST_CLOSE"]
M1["WIFI_MP_TEST_MODE"]
M2["WIFI_STA_TEST_MODE"]
M3["WIFI_AP_TEST_MODE"]
M4["BT_DUT/FCC/BQB_TEST_MODE"]
M5["RF_MULTI_TEST_MODE"]
end
subgraph sg_Cfg["配置与运行时"]
CFG["user_cfg.c<br/>CFG_BT/BLE_RF_POWER_ID"]
LD["链接脚本/移动段<br/>rf_trim 代码放置"]
BANK["bank_switch.h<br/>__BANK_RF_TRIM"]
end
end
PC -->|"UDP 命令(30136/其他)"| UDP
UDP -->|"设置 rf_test_mode"| HDL
HDL --> TASK
TASK --> M0
TASK --> M1
TASK --> M2
TASK --> M3
TASK --> M4
TASK --> M5
M1 -->|"CONFIG_MP_TEST_ENABLE"| CFG
M2 -->|"抑制请求连接/启动 UDP Server"| UDP
M3 -->|"启动 AP + UDP Server"| UDP
CFG --> LD
LD --> BANK
架构要点:
- 命令入口:产测上位机通过 UDP 报文向设备下发测试模式命令,
wifi_app_task.c中的应用任务接收并校验命令字节(tmp[0] > RF_TEST_CLOSE && tmp[0] <= WIFI_AP_TEST_MODE等范围判断),随后写入__this->rf_test_mode; - 模式驱动行为:
wifi_app_hdl.rf_test_mode是 3 位位域,可表示 0~7 共 8 种模式;任务轮询该状态并启动/停止对应的网络服务(如udp_server_init(30136)); - 产测编译开关:
CONFIG_MP_TEST_ENABLE决定产测专用行为(如 STA 测试模式下禁止自动请求连接),保证产线环境下设备行为可控; - RF 运行时支撑:RF 功率校准值由
user_cfg.c从系统配置读取(CFG_BT_RF_POWER_ID/CFG_BLE_RF_POWER_ID);RF trim 代码段的存放位置由链接脚本与 Bank 宏决定,支持 RAM/可搬移/Flash 三种策略。
核心机制详解
RF 测试模式状态模型
产测框架的核心是一个 8 值枚举,定义于 apps/wifi_story_machine/wifi_app_task.c 中:
enum {
RF_TEST_CLOSE = 0,
WIFI_MP_TEST_MODE,
WIFI_STA_TEST_MODE,
WIFI_AP_TEST_MODE,
BT_DUT_TEST_MODE,
BT_FCC_TEST_MODE,
BT_BQB_TEST_MODE,
RF_MULTI_TEST_MODE,
};
Source: wifi_app_task.c
各模式含义:
| 枚举值 | 含义 | 典型用途 |
|---|---|---|
RF_TEST_CLOSE (0) | 关闭测试模式 | 默认状态/退出产测 |
WIFI_MP_TEST_MODE (1) | WiFi 量产测试模式 | 产线 WiFi 功能测试 |
WIFI_STA_TEST_MODE (2) | WiFi STA 模式测试 | 连接指定 AP 后测吞吐/信号 |
WIFI_AP_TEST_MODE (3) | WiFi AP 模式测试 | 设备开 AP,上位机连入测试 |
BT_DUT_TEST_MODE (4) | BT DUT 测试 | 蓝牙认证/产测(直接测试模式) |
BT_FCC_TEST_MODE (5) | BT FCC 测试 | 法规认证(FCC)测试 |
BT_BQB_TEST_MODE (6) | BT BQB 测试 | Bluetooth SIG BQB 认证 |
RF_MULTI_TEST_MODE (7) | 多合一 RF 测试 | 综合射频测试 |
该枚举的设计意图:将产测上位机的"命令字"与固件内部的模式一一映射,命令字即枚举值本身,省去二次翻译,同时把 BT 认证(DUT/FCC/BQB)也纳入同一套框架,产线可用同一通道覆盖 WiFi 与 BT 的测试需求。
全局状态句柄 wifi_app_hdl
模式状态保存在一个静态全局结构体中,使用位域紧凑编码:
static struct {
int udp_recv_pid;
u32 use_static_ipaddr_flag : 1;
u32 net_app_init_flag : 1;
u32 request_connect_flag : 1;
u32 save_ssid_flag : 1;
u32 mac_addr_succ_flag : 1;
u32 udp_recv_test_exit_flag : 1;
u32 rf_test_mode : 3;
u32 reserved : 23;
} wifi_app_hdl;
#define __this (&wifi_app_hdl)
Source: wifi_app_task.c
设计要点:
- 位域打包:7 个标志位 + 3 位
rf_test_mode共用一个 32 位字,兼顾 RAM 节省与原子读写的便利;rf_test_mode为 3 位,恰好容纳 0~7 的 8 种模式; __this宏:统一访问全局句柄,方便任务内多处引用;udp_recv_pid:记录 UDP 接收任务的进程 ID,用于测试退出时关闭接收任务;udp_recv_test_exit_flag:与RF_TEST_CLOSE联动,用于优雅退出测试循环。
测试命令接收与分发
应用任务通过 UDP 接收产测上位机下发的命令报文,校验后写入 rf_test_mode:
if (err == sizeof(tmp) && tmp[0] > RF_TEST_CLOSE && tmp[0] <= WIFI_AP_TEST_MODE) {
char ssid[33] = {0};
...
__this->rf_test_mode = tmp[0];
Source: wifi_app_task.c
命令处理逻辑:
- 长度校验:
err == sizeof(tmp)确保报文长度与命令字大小一致,防止粘包/半包; - 范围校验:
tmp[0] > RF_TEST_CLOSE && tmp[0] <= WIFI_AP_TEST_MODE过滤非法命令字(0 与越界值被丢弃);注意此处上限为WIFI_AP_TEST_MODE,BT 与多合一模式由后续逻辑另行处理; - 落盘模式:
__this->rf_test_mode = tmp[0]后,后续任务轮询依据该值切换行为。
退出测试时则将模式复位为关闭态:
__this->rf_test_mode = RF_TEST_CLOSE;
Source: wifi_app_task.c
WiFi AP / STA 测试模式的行为
进入 WIFI_AP_TEST_MODE 后,设备开启 AP 并在固定端口启动 UDP Server,供上位机/手机连入后直接通信:
if (__this->rf_test_mode == WIFI_AP_TEST_MODE) {
udp_server_init(30136);
Source: wifi_app_task.c
WIFI_STA_TEST_MODE 则让设备以 STA 身份连接上位机指定的 SSID,并在同一端口(30136)启动 UDP Server:
if (__this->rf_test_mode == WIFI_STA_TEST_MODE) {
udp_server_init(30136);
Source: wifi_app_task.c
固定使用端口 30136 的意义:产测上位机无需动态发现端口,降低产线脚本复杂度;AP/STA 两模式共用同一端口,上位机只需区分设备角色。
产测编译开关 CONFIG_MP_TEST_ENABLE
产线环境要求设备行为确定且可重复,因此在 STA 测试模式下会抑制正常业务逻辑(如自动请求连接):
#if defined CONFIG_MP_TEST_ENABLE
if (__this->rf_test_mode == WIFI_STA_TEST_MODE) {
__this->request_connect_flag = 0;
Source: wifi_app_task.c
设计意图:量产固件与零售固件共用同一份代码,通过 CONFIG_MP_TEST_ENABLE 裁剪产测行为;在产测模式下关闭自动连接,确保设备只响应产测上位机,避免误连周围 AP 导致测试失败或安全风险。
网络吞吐测试:iPerf 工具
除射频模式外,产测也常需要验证 WiFi 吞吐量。应用内集成了 iPerf 测试入口:
//网络测试工具,使用iperf
extern void iperf_test(void);
iperf_test();
Source: wifi_app_task.c
iperf_test 由协议栈/网络库提供(外部符号),应用层仅负责在需要时调用;配合 app_main.c 中的任务栈配置(iperf_test 任务 1024 字栈),保证吞吐测试有足够的任务栈空间:
{"iperf_test", 15, 1024, 0 },
Source: app_main.c
RF 功率配置读取
产测/校准流程会写 RF 功率值到系统配置,运行时代码从 syscfg 读取:
//-----------------------------CFG_BT_RF_POWER_ID----------------------------//
ret = syscfg_read(CFG_BT_RF_POWER_ID, &bt_power, 1);
//-----------------------------CFG_BLE_RF_POWER_ID----------------------------//
ret = syscfg_read(CFG_BLE_RF_POWER_ID, &ble_power, 1);
Source: user_cfg.c
CFG_BT_RF_POWER_ID 与 CFG_BLE_RF_POWER_ID 是系统配置(syscfg)的键 ID,分别对应经典蓝牙与 BLE 的发射功率档位。读取值经用户配置层解析后用于初始化协议栈 RF 参数——这是产测校准结果落到运行时行为的关键桥梁。
RF 校准代码段(RF trim)的链接策略
RF trim(射频校准)代码对时序敏感,SDK 提供三种放置策略,由链接脚本与编译宏共同控制:
#if !defined CONFIG_RF_TRIM_CODE_AT_RAM && !defined CONFIG_RF_TRIM_CODE_MOVABLE
*(*.rf.text.cache.L2.rf_trim)
...
#if defined CONFIG_RF_TRIM_CODE_AT_RAM
*(*.rf.text.cache.L2.rf_trim)
Source: sdk_ld_sdram.c 与 sdk_ld_sdram.c
可搬移(movable)方案在移动段中预留 RF trim 槽位:
#if defined CONFIG_RF_TRIM_CODE_MOVABLE
. = ALIGN(4);
__rf_trim_movable_slot_start = .;
*(.movable.slot.1);
__rf_trim_movable_slot_end = .;
#endif
Source: movable_data.ld
三种策略的取舍:
| 宏 | 代码段位置 | 适用场景 |
|---|---|---|
| 未定义 | Flash(经 Cache L2) | 默认,节省 RAM |
CONFIG_RF_TRIM_CODE_AT_RAM | 固定 RAM | 时序敏感、需稳定执行延迟 |
CONFIG_RF_TRIM_CODE_MOVABLE | 可搬移槽位 | 运行时按需加载,兼顾 RAM 与灵活性 |
此外,多 Bank 固件可通过 Bank 切换承载 RF trim:
#ifdef CONFIG_BANK_NUM_RF_TRIM
#define __BANK_RF_TRIM __BANK_NUM(CONFIG_BANK_NUM_RF_TRIM)
#else
#define __BANK_RF_TRIM
#endif
Source: bank_switch.h
CONFIG_BANK_NUM_RF_TRIM 指定 RF trim 所在 Bank 号,__BANK_RF_TRIM 宏用于为 RF trim 函数打上 Bank 属性,运行时由 Bank 切换机制按需换页执行——这在 flash 容量受限、代码需按 Bank 分页的大固件场景中尤为关键。
核心流程
产测命令下发与模式切换序列
下图展示产测上位机通过 UDP 命令将设备从关闭态切换到测试态、执行测试并退出测试的完整时序:
sequenceDiagram
participant PC as 产测上位机
participant UDP as UDP 接收任务
participant TASK as wifi_app_task
participant HDL as wifi_app_hdl
participant NET as 网络服务 (AP/STA/Server)
PC->>UDP: UDP 报文 [mode=WIFI_AP_TEST_MODE]
UDP->>UDP: 校验 len == sizeof(tmp)
UDP->>UDP: 校验 tmp[0] 范围 (0 < mode <= AP)
UDP->>HDL: rf_test_mode = WIFI_AP_TEST_MODE
TASK->>HDL: 轮询 rf_test_mode
TASK->>NET: udp_server_init(30136) / 开启 AP
PC->>NET: 连接 AP + UDP 测试流量
NET-->>PC: 测试结果/吞吐数据
PC->>UDP: UDP 报文 [mode=RF_TEST_CLOSE]
UDP->>HDL: rf_test_mode = RF_TEST_CLOSE
TASK->>HDL: 轮询到关闭态
TASK->>NET: 关闭 UDP Server / 退出测试循环
关键点:
- 命令校验在接收路径内完成(长度 + 范围双重校验),非法命令不会污染
rf_test_mode; - 模式切换是"写状态 + 任务轮询"的异步模型,网络服务的启停都在应用任务上下文执行,避免在 UDP 接收回调中直接操作网络栈造成重入问题;
- 退出路径与进入路径对称,
RF_TEST_CLOSE同时触发接收任务的退出标志(udp_recv_test_exit_flag)。
测试模式状态机
stateDiagram-v2
[*] --> RF_TEST_CLOSE
RF_TEST_CLOSE --> WIFI_MP_TEST_MODE: 命令 1
RF_TEST_CLOSE --> WIFI_STA_TEST_MODE: 命令 2
RF_TEST_CLOSE --> WIFI_AP_TEST_MODE: 命令 3
RF_TEST_CLOSE --> BT_DUT_TEST_MODE: 命令 4
RF_TEST_CLOSE --> BT_FCC_TEST_MODE: 命令 5
RF_TEST_CLOSE --> BT_BQB_TEST_MODE: 命令 6
RF_TEST_CLOSE --> RF_MULTI_TEST_MODE: 命令 7
WIFI_MP_TEST_MODE --> RF_TEST_CLOSE: 命令 0
WIFI_STA_TEST_MODE --> RF_TEST_CLOSE: 命令 0
WIFI_AP_TEST_MODE --> RF_TEST_CLOSE: 命令 0
BT_DUT_TEST_MODE --> RF_TEST_CLOSE: 命令 0
BT_FCC_TEST_MODE --> RF_TEST_CLOSE: 命令 0
BT_BQB_TEST_MODE --> RF_TEST_CLOSE: 命令 0
RF_MULTI_TEST_MODE --> RF_TEST_CLOSE: 命令 0
状态机要点:
- 所有测试模式都从
RF_TEST_CLOSE(0)进入,最终回到RF_TEST_CLOSE,形成"关闭 → 测试 → 关闭"的闭环,保证产线重复测试时状态可复位; - 模式之间不允许直接跳转(必须先回到关闭态),避免残留网络服务/测试状态影响下一次测试。
配置选项
| 配置项 | 类型 | 默认 | 说明 |
|---|---|---|---|
CONFIG_MP_TEST_ENABLE | 编译宏 | 未定义 | 使能产测专用行为:STA 测试模式下禁止 request_connect_flag 自动请求连接,保证设备只响应产测上位机 |
CONFIG_RF_TRIM_CODE_AT_RAM | 编译宏 | 未定义 | 将 *.rf.text.cache.L2.rf_trim 校准代码段固定链接到 RAM,保证执行时序稳定 |
CONFIG_RF_TRIM_CODE_MOVABLE | 编译宏 | 未定义 | 将 RF trim 代码放入可搬移槽位(__rf_trim_movable_slot_start ~ __rf_trim_movable_slot_end),运行时按需加载 |
CONFIG_BANK_NUM_RF_TRIM | 编译宏 | 未定义 | 指定 RF trim 代码所在 Bank 号,使 __BANK_RF_TRIM 生效,支持多 Bank 分页执行 |
CFG_BT_RF_POWER_ID | syscfg 键 | - | 经典蓝牙 RF 发射功率档位的系统配置键,产测校准写入、运行时 syscfg_read 读取 |
CFG_BLE_RF_POWER_ID | syscfg 键 | - | BLE RF 发射功率档位的系统配置键,读写路径同 BT |
| UDP 测试端口 | 常量 | 30136 | AP/STA 测试模式下 udp_server_init(30136) 使用的固定端口,产测上位机据此收发测试报文 |
CONNECT_TIMEOUT_SEC | 宏 | 60 | 连接超时秒数(#define CONNECT_TIMEOUT_SEC 60),用于 STA 模式连接指定 AP 的超时控制 |
注:
CONNECT_TIMEOUT_SEC定义见 wifi_app_task.c,udp_server_init(30136)调用见 wifi_app_task.c。
失败模式、边界情况与并发注意
- 非法命令字被忽略:接收路径只接受
tmp[0] > RF_TEST_CLOSE && tmp[0] <= WIFI_AP_TEST_MODE的命令,越界值(如 8、0xFF)与长度不符的报文会被静默丢弃,防止上位机误操作或恶意报文破坏测试状态; - BT 模式的命令边界:AP 模式校验的上限是
WIFI_AP_TEST_MODE,BT_DUT/FCC/BQB 与RF_MULTI_TEST_MODE需要额外的命令分支/校验路径,扩展新测试模式时需同步更新命令校验边界; - 状态残留:模式切换采用"写状态 + 轮询"异步模型,若上位机在旧模式服务未完全关闭时立即下发新模式,可能出现短暂的服务重叠;设计上要求先回到
RF_TEST_CLOSE再进入新模式,产测脚本应遵循该时序; - 任务栈与并发:iPerf 测试任务配置了 1024 字栈(见
app_main.c任务表),若增大测试并发(多路 UDP 流)需同步评估栈深度;wifi_app_hdl的状态读写均在同一应用任务上下文进行,未加锁——避免在其他任务/中断中直接改写rf_test_mode,否则会产生竞态; - RF trim 代码段配置互斥:
CONFIG_RF_TRIM_CODE_AT_RAM与CONFIG_RF_TRIM_CODE_MOVABLE同时定义时,链接脚本的分支行为(先判断AT_RAM)以AT_RAM为准,配置时应注意二者互斥,避免产生二义性; - Bank 切换时序:使用
CONFIG_BANK_NUM_RF_TRIM时,RF trim 函数执行期间不能发生 Bank 切换(否则取指失效),产测高频调用 RF trim 的场景应评估是否固定到 RAM 以规避该风险。
扩展点
- 新增测试模式:在
wifi_app_task.c的枚举末尾追加新值,并在命令接收/分发处补充校验边界与对应行为分支(如新增模式需要新的 UDP 端口或网络角色); - 产测专用行为:通过
CONFIG_MP_TEST_ENABLE增加产测裁剪逻辑,使同一份代码兼容量产固件与零售固件; - RF 功率档位:
CFG_BT_RF_POWER_ID/CFG_BLE_RF_POWER_ID是标准 syscfg 键,产测工具可写入新档位,运行时读取即可生效,无需改动协议栈代码; - 代码放置策略:通过
CONFIG_RF_TRIM_CODE_AT_RAM/CONFIG_RF_TRIM_CODE_MOVABLE/CONFIG_BANK_NUM_RF_TRIM三种宏组合,可按产品对成本、RAM 与时序的要求灵活布局 RF trim 代码。