ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AP6212 Linux驱动移植:SDIO认卡、固件加载与双模调试

AP6212 Linux驱动移植:SDIO认卡、固件加载与双模调试

简介:AP6212 驱动资料包面向在 Linux 平台适配 Broadcom AP6212 无线芯片的开发者与系统集成者,聚焦 WiFi 与蓝牙驱动的编译、移植和调试,适合具备一定内核基础、需要解决硬件识别、驱动加载及网络连接稳定性问题的人群。压缩包共 14 个文件、约 5.31MB,以 txt 说明、pdf 手册、jpg 版本对比图为主,并包含源码压缩包、补丁脚本及 C 源码等,便于按移植流程查阅与取用。已有 2038 人学习下载,说明其在同类芯片适配场景中具有一定参考价值。内容覆盖驱动源码、内核移植步骤、设备树与编译配置说明、蓝牙应用库编译设置、WiFi/蓝牙用户指南及固件与 nvram 资源,还整理了个人移植中遇到的问题与解决办法,可帮助读者理解 AP6212 的版本差异、排查加载失败与连接异常,并完成 WiFi Direct、A2DP 等功能的启用与优化。

1. AP6212 驱动在 Linux 上的第一道坎:SDIO 认不到卡,比编译失败常见得多

手上有一块带 AP6212 的板子,内核 4.19,编译 AP6212 Linux 驱动一次就过,insmod也不报错,可ip link里死活看不到 wlan0——这种事我在板卡移植现场见过太多次。AP6212 是 WiFi 走 SDIO、蓝牙走 UART 的双模模组,硬件上还多出 WL_REG_ON、BT_REG_ON 两根使能脚,任何一处没配好,表现出来的都是“驱动没装好”,实际坏的地方可能在内核配置、设备树、固件文件名,甚至在电源上电时序。

装不好轻则开机多等半分钟、扫描不到 5G 频段,重则 2.4G 一连就掉、蓝牙连一次断一次,调试时没有任何黑匣子可看,只能靠 dmesg 一行行猜。这篇写给正在板卡上移植这颗模组的人:从版本怎么选、源码怎么编、固件怎么放,一直写到装崩了怎么救。

2. 环境与版本核对:AP6212 驱动选哪套分支、配哪份固件

AP6212 的坑有一半是版本没对齐埋下的。同样一份驱动源码,放在 3.10 的厂商 SDK 里能编过,挪到 5.10 上就是一堆unknown field报错;同样一份 nvram,a0 版芯片用着正常,换成 a1 版芯片就下载固件超时。所以动手之前先把三件事定下来:内核版本、驱动形态、固件文件名。

2.1 内核版本决定驱动形态:bcmdhd 外挂还是 brcmfmac 内置

这套模组的驱动在 Linux 下有两条完全不同的路。第一条是模组厂随 SDK 发出来的 bcmdhd 源码包,编译产物是dhd.ko,走的是它自己的一套 netdev 实现,跟 cfg80211 只做半对接;第二条是内核主线里的 brcmfmac,从 4.9 开始对 43438 这颗芯片的支持就基本可用了,4.19 之后我一般直接用它,能省掉一大半维护成本。

内核版本推荐驱动形态固件存放位置典型场景
3.10 ~ 4.4bcmdhd(dhd.ko)/system/vendor/firmware或/lib/firmware厂商 SDK、老 Android BSP
4.9 ~ 4.14brcmfmac + 少量厂商补丁/lib/firmware/brcm主线化过渡期
4.19 及以上brcmfmac(首选)/lib/firmware/brcm新项目、长期维护

选 brcmfmac 就要把内核配置项开对,这几个是最容易漏的:

# 内核 .config 里必须打开的一组项 CONFIG_CFG80211=m CONFIG_MAC80211=m CONFIG_BRCMUTIL=m CONFIG_BRCMFMAC=m CONFIG_BRCMFMAC_SDIO=y CONFIG_BRCMFMAC_PROTO_BCDC=y # 43438 不支持 msgbuf 协议,这一项保持关闭 # CONFIG_BRCMFMAC_PROTO_MSGBUF is not set CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_BCM=y

BRCMFMAC_PROTO_BCDC和PROTO_MSGBUF这两个协议选项是分水岭。43438 这颗芯片只支持 BCDC,如果 menuconfig 里手滑把 msgbuf 打开,编译不报错,加载时固件也能下去,但初始化阶段会卡在brcmf_proto_msgbuf_attach上,日志只留一句failed to attach msgbuf,很容易被误判成固件问题。BT_HCIUART_BCM则是给蓝牙用的,蓝牙 H4 协议要靠它识别 bcm 的下载协议,缺了这项,hciattach会一直停在bcm43xx_init。

如果项目必须留在 bcmdhd 上(比如要跑厂商定制的 P2P 或某个私有 ioctl),那就把驱动源码和内核版本严格绑定。判断标准很简单:驱动包里include/目录下的头文件,和内核树里同名头文件的字段能对上。对不上就别硬编,换分支比改代码快。

2.2 先确认硬件怎么挂的:SDIO 总线号、串口、使能脚

驱动之前先看硬件。把板子启动到能进 shell 的程度,哪怕 WiFi 完全不通,SDIO 控制器和串口也应该在工作:

# 看 mmc 控制器有没有枚举到设备 dmesg | grep -i -E "mmc[0-9]|sdio" # 看 SDIO 设备节点,正常应该出现类似 mmc1:0001:1 的目录 ls -l /sys/bus/sdio/devices/ # 看当前 mmc 控制器的时钟与位宽 cat /sys/kernel/debug/mmc1/ios

dmesg里出现mmc1: new high speed SDIO card at address 0001这一行,说明硬件链路是通的,剩下的都是软件问题;如果只有mmc1: SDHCI controller on ... using ADMA之后再无下文,那多半是 WL_REG_ON 没拉起来、供电没到位或者bus-width写错。

使能脚的定义每家板子不一样,但套路固定:WiFi 一根 WL_REG_ON,蓝牙一根 BT_REG_ON,有的板子还有一根共用的 WL_HOST_WAKE 中断脚。这三根脚在设备树里必须描述清楚,否则驱动再对,模块也不上电。常见的 mmc-pwrseq 写法:

/* SDIO WiFi 供电与复位时序 */ &mmc1 { status = "okay"; bus-width = <4>; non-removable; keep-power-in-suspend; cap-power-off-card; max-frequency = <50000000>; mmc-pwrseq = <&wifi_pwrseq>; brcmf: wifi@1 { reg = <1>; compatible = "brcm,bcm4329-fmac"; }; }; wifi_pwrseq: wifi-pwrseq { compatible = "mmc-pwrseq-simple"; /* WL_REG_ON,低电平有效,具体 GPIO 号按板子原理图改 */ reset-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; /* 上电后等 200ms 再枚举,短了会认不到卡 */ post-power-on-delay-ms = <200>; };

non-removable表示卡是焊死的,不能让 mmc 子系统去做插拔探测;cap-power-off-card允许在挂起时断电;post-power-on-delay-ms是最容易被忽略的一行,模组内部稳压和晶振起振需要时间,很多板子给 50ms 能认出卡但跑一会儿就掉,改成 200ms 就稳了。compatible = "brcm,bcm4329-fmac"是 brcmfmac 认 SDIO 设备的通用匹配串,写错就只是枚举到设备、不绑定驱动。

蓝牙那侧走的是 UART:

/* 蓝牙挂在 uart1 上,波特率上限由 max-speed 决定 */ &uart1 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&uart1_pins>; bluetooth { compatible = "brcm,bcm43438-bt"; max-speed = <1500000>; /* BT_REG_ON,高电平有效 */ shutdown-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; }; };

max-speed是协商后的最高波特率,1500000 是这颗芯片的常用档,但有些板子的 UART 时钟分频除不尽,实测只能用 115200 或 921600,硬上高波特率会得到一堆乱码和hci0: command tx timeout。shutdown-gpios在高版本内核里由 hci_bcm 驱动接管,加载时会自动拉高,老内核没有这个节点,就得自己在hciattach前用脚本把 GPIO 拉起来。

2.3 固件与 nvram 准备:文件名对不上,驱动装了也白装

brcmfmac 是按文件名找固件的,名字错一个字符就加载失败。它认的规则是:brcmfmac<chipid>-sdio.bin和brcmfmac<chipid>-sdio.txt,43438 对应brcmfmac43430-sdio.bin。而厂商给的原始文件名通常是fw_bcm43438a1.bin和nvram_ap6212a.txt,中间需要一层改名或者软链。

# 固件统一放到 brcm 子目录下,权限 644 sudo mkdir -p /lib/firmware/brcm sudo cp fw_bcm43438a1.bin /lib/firmware/brcm/brcmfmac43430-sdio.bin sudo cp nvram_ap6212a.txt /lib/firmware/brcm/brcmfmac43430-sdio.txt sudo chmod 644 /lib/firmware/brcm/brcmfmac43430-sdio.* # 用 bcmdhd 的话保留原名,路径由模块参数指定,不用改名 sudo cp fw_bcm43438a1.bin /lib/firmware/brcm/ sudo cp nvram_ap6212a.txt /lib/firmware/brcm/ # 校验一下文件是不是拷贝过程被截断了 md5sum /lib/firmware/brcm/brcmfmac43430-sdio.bin ls -l /lib/firmware/brcm/

固件版本要和芯片版本对应。AP6212 常见两种芯片:a0 和 a1。a0 用fw_bcm43438a0.bin配nvram_ap6212.txt,a1 用fw_bcm43438a1.bin配nvram_ap6212a.txt。这两个组合不能交叉,交叉的典型症状是固件能下载进去,但brcmf_chip_recognition阶段读回 chipid 对不上,日志打印brcmf_chip_set_passive: unsupported chip。判断芯片版本最省事的办法是看模组丝印,其次是挨个试,试错成本就是一次重启。

nvram 文件里还有几个参数决定实际体验,值得单独看一眼:

# nvram_ap6212a.txt 里需要关注的几行 macaddr=00:90:4c:xx:xx:xx # 出厂 MAC,缺失会导致每次开机 MAC 变化 boardtype=0x0b3 # 板型标识,跟天线匹配有关 btc_mode=1 # 蓝牙共存模式,不开 2.4G 会和蓝牙互抢 btc_params40=0x0f # 共存参数,不同板子取值不同

macaddr缺失是最常见的一类问题。brcmfmac 找不到 MAC 时会用随机地址,表现就是每次重启 wlan0 的 MAC 都变,路由器上的 DHCP 租约表越积越长,某些做了 MAC 绑定的环境直接连不上。这种字段如果驱动包里没带,就得在产线工装里写进去。

3. 编译与加载 AP6212 驱动:从源码到 insmod 的落地步骤

版本和固件都对齐之后,才轮到编译。这一步在 x86 主机上交叉编译,产物拿到板子上insmod。看着简单,实际最容易翻车的是内核树不完整、符号版本对不上、加载顺序错。

3.1 准备内核树与交叉工具链

交叉编译模块要求主机上有一份配置和板上内核完全一致的内核树,包括.config和Module.symvers。只拷头文件不够,缺Module.symvers会在加载时报disagrees about version of symbol。

# 主机上确认工具链可用 arm-linux-gnueabihf-gcc -v # 内核树必须是板上跑的同一版本、同一配置 cd /home/dev/kernel/linux-4.19 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_prepare # 检查这两个文件是否存在,缺一个都别往下走 ls -l .config Module.symvers

modules_prepare会生成编译外部模块所需的脚本和头文件。如果手上只有板上/lib/modules/$(uname -r)/build那个软链,把它指到完整内核树,或者干脆把板上/proc/config.gz拿回来重新配一遍。.config不一致的后果很隐蔽:编译能过,加载能过,跑起来偶尔 oops,查起来毫无头绪。

3.2 改 Makefile 和三个关键宏

bcmdhd 的 Makefile 一般把内核路径写成宿主机默认值,交叉编译必须改。核心是三个变量:ARCH、CROSS_COMPILE、KERNELDIR,外加一组DHDCFLAGS。

# 驱动源码目录下的 Makefile 关键片段 ARCH ?= arm CROSS_COMPILE ?= arm-linux-gnueabihf- KERNELDIR ?= /home/dev/kernel/linux-4.19 # 告诉驱动走 SDIO 总线,而不是 USB 或 PCIe CONFIG_BCMDHD_SDIO := y # 固件与 nvram 的默认路径,和 2.3 节放的位置保持一致 CONFIG_BCMDHD_FW_PATH := "/lib/firmware/brcm/fw_bcm43438a1.bin" CONFIG_BCMDHD_NVRAM_PATH := "/lib/firmware/brcm/nvram_ap6212a.txt" # 走 cfg80211 框架,上层才能用 wpa_supplicant 的 nl80211 驱动 DHDCFLAGS += -DUSE_CFG80211 # 打开 PNO,休眠唤醒后的被动扫描要靠它 DHDCFLAGS += -DPNO_SUPPORT

CONFIG_BCMDHD_SDIO决定编译哪套总线适配代码,选错会得到一堆dhdsdio_*未定义符号。FW_PATH和NVRAM_PATH是编进模块的默认值,运行时也能用模块参数覆盖,但产线上一般直接编死,省得启动脚本里再传。USE_CFG80211影响的是上层接口:开了走 cfg80211,iw和wpa_supplicant -Dnl80211都能用;不开就只能用它私有的 wireless extensions,新发行版基本已经移除了。

改完直接编:

export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- export KERNELDIR=/home/dev/kernel/linux-4.19 make -C $KERNELDIR M=$PWD modules -j4 # 产物确认,正常会生成 dhd.ko file dhd.ko modinfo dhd.ko | head -20

-C $KERNELDIR让 make 先切到内核树读顶层 Makefile,M=$PWD再指回驱动目录,这是编译外部模块的标准写法。modinfo输出的vermagic必须和板上uname -r完全一致,不一致就说明内核树选错了,别抱侥幸心理硬加载。

3.3 insmod 加载顺序与 dmesg 观察

模块之间是有依赖的。bcmdhd 依赖 cfg80211,cfg80211 又依赖内核里已经编进去的部分;brcmfmac 依赖 brcmutil。顺序错了就是Unknown symbol in module。

# bcmdhd 路线,先依赖后主体 insmod /lib/modules/$(uname -r)/cfg80211.ko insmod /lib/modules/$(uname -r)/dhd.ko \ firmware_path=/lib/firmware/brcm/fw_bcm43438a1.bin \ nvram_path=/lib/firmware/brcm/nvram_ap6212a.txt # brcmfmac 路线,一条 modprobe 就够,依赖自动处理 modprobe brcmfmac # 无论哪条路,加载完先看这一段日志 dmesg | tail -40

成功的日志长这样:先是mmc1: new high speed SDIO card at address 0001完成枚举,接着dhd_module_init in或brcmfmac: brcmf_sdio_probe: firmware ready,然后打印固件版本和 MAC,最后出现wl0: Broadcom BCM43438 WLAN found之类的一行。只要看到 MAC 地址那一行,链路层就通了。

失败时日志停在哪个阶段,指向的问题是不一样的。停在枚举之前,回去查设备树和供电;停在固件下载,查文件名、芯片版本、nvram;停在wl0注册之前但固件已经下去,多半是 MAC 或者板型参数有问题。模块参数除了firmware_path/nvram_path,还有几个常用:

# 打开调试级别,日志更啰嗦但定位更准 insmod dhd.ko dhd_msg_level=0x1 # 强制指定 MAC,临时绕开 nvram 缺 macaddr 的问题 insmod dhd.ko mac=00:11:22:33:44:55

dhd_msg_level是按位掩码的,0x1是错误,0x7是错误加警告加信息,产线调试期开大一点,量产必须关掉,否则串口日志会被刷屏拖慢启动。

4. 配置双模:AP6212 的 wpa_supplicant 与蓝牙 HCI 初始化

wlan0 出现只是第一步,能连上 AP 才算 WiFi 通了;蓝牙那侧hci0出现也只是第一步,能扫到设备才算通。这两条路互不依赖,可以分开调,但共用一套电源和共存参数,调好一个再去动另一个。

4.1 wlan0 起来之后:wpa_supplicant 与 nl80211 的配置

如果驱动走的是 cfg80211,上层就用 wpa_supplicant 的nl80211驱动后端;如果走的是老私有接口,就得用wext。判断方式是看iw dev有没有输出,有就是 cfg80211。

# /etc/wpa_supplicant.conf ctrl_interface=/var/run/wpa_supplicant update_config=1 country=CN network={ ssid="test-ap" psk="12345678" key_mgmt=WPA-PSK proto=RSN pairwise=CCMP scan_ssid=1 }

country=CN不是摆设,它决定驱动下发的监管域,进而决定哪些信道可用。这一行缺失时,某些内核版本会把 12、13 信道标成 no-IR,表现是能扫到 AP 但连不上。scan_ssid=1是给隐藏 SSID 用的,正常 AP 开着也无妨,只是每次扫描多花一点时间。

# 前台起一次,看握手过程,调通了再改 -B 后台 wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wpa_supplicant.conf -dd # 拿到 IP udhcpc -i wlan0 # 或发行版自带客户端 dhclient wlan0 # 确认接口状态 iw dev wlan0 link

-Dnl80211指定驱动后端,写错成wext会报Failed to initialize driver interface。-dd是调试级别,会打印每一步的 EAPOL 交互,排查密码错、四次握手失败时非常有用。连上之后iw dev wlan0 link会显示当前 BSSID、信号强度和速率,这几项是判断链路质量的直接依据。

4.2 蓝牙走 UART:hciattach 与内核 hci_bcm 两条路

蓝牙这块分老新两套机制。4.9 之前基本靠用户态hciattach手动下载固件,4.9 之后内核里的 hci_bcm 能自己处理,前提是设备树写对。

老路子:

# 先把 BT_REG_ON 拉高,具体 gpio 号按板子改 gpioset gpiochip1 13=1 sleep 0.2 # bcm43xx 协议,先低速协商再切高速 hciattach /dev/ttyS1 bcm43xx 1500000 flow -t 30 # 起来了之后 hciconfig hci0 up hciconfig -a

bcm43xx是协议名,它会先按 115200 发下载命令,把BCM43438A1.hcd固件灌进去,再切到1500000。flow表示启用硬件流控,不写这参数在高速率下必然丢包。-t 30是超时秒数,默认值偏小,固件大的时候会误判失败。这个.hcd文件要放在/etc/firmware/或--bd_addr指定的路径下,路径不对就卡在bcm43xx_init不动。

新路子(4.19 及以上):

modprobe bluetooth modprobe hci_uart modprobe btbcm # 设备树里 bluetooth 节点写对的话,hci0 会自动出现 hciconfig -a rfkill list rfkill unblock bluetooth

rfkill是个容易被忘掉的开关。有些板子的默认状态下蓝牙是 soft blocked,hciconfig hci0 up会报Operation not possible due to RF-kill,这时候rfkill unblock bluetooth一下就通了,跟驱动一点关系没有。

蓝牙固件文件名通常要求是BCM43438A1.hcd,从厂商包里拷过来放到/lib/firmware/brcm/或/etc/firmware/,两个路径不同发行版认的不一样,都放一份最省事。文件版本同样要和芯片版本对上。

5. 常见问题排查:AP6212 驱动装完不认卡、固件超时、蓝牙 110

下面这几条都是我在板子上真实撞过的,按现象、原因、解决三段记,遇到同类问题时可以直接对号。

现象一:dmesg里 mmc1 只有控制器初始化,没有new high speed SDIO card,/sys/bus/sdio/devices/是空的。

原因通常是电源或时序。WL_REG_ON 没拉起来、reset-gpios的极性写反、post-power-on-delay-ms给得太短,都会导致枚举阶段读不到卡。也有一种情况是bus-width写成<1>,4 线模组按 1 线枚举,运气好能认到但速率极低,运气不好直接超时。解决办法是把万用表或示波器搭到 WL_REG_ON 上,确认上电后确实被拉高,然后把延时从 50ms 加到 200ms 再试;同时核对设备树里bus-width = <4>和non-removable两行。

现象二:卡认到了,固件下载阶段报brcmf_sdio_download_firmware: dongle is not responding或FW download failed。

原因基本是固件和芯片版本不匹配,或者 nvram 用错了。a0 芯片灌 a1 的固件、nvram_ap6212.txt和nvram_ap6212a.txt混用,都会卡在这一步。另一类原因是 SDIO 时钟太快,max-frequency给到 50MHz 时某些板子的走线撑不住。解决办法是先换固件组合,两组都试一遍,排除版本问题;还不行就把max-frequency降到 25MHz 验证,能过就说明是信号完整性问题,回去改 layout 或加串阻,而不是继续折腾驱动。

现象三:wlan0 出现了,iw dev wlan0 scan一条结果都没有,或者 MAC 每次重启都变。

MAC 每次变说明 nvram 里没有macaddr,驱动用了随机地址。扫描无结果则多半是监管域或天线问题:country没设导致信道全被禁,或者天线没接、阻抗不匹配导致灵敏度极差。解决办法是先补macaddr,把出厂 MAC 写进 nvram 或者产线工装;再用iw reg get看当前监管域,手工iw reg set CN验证一下是不是这个原因。如果设了监管域还是扫不到,那就是射频侧的问题,跟软件无关了。

现象四:insmod报disagrees about version of symbol或Invalid module format。

内核树和板上内核不是同一份。vermagic里包含内核版本、SMP 标志、抢占模式、模块版本校验,任何一项不一致都加载不了。常见于板上内核是厂商改过的,主机上用的却是官方源码。解决办法是把板上/proc/version和/proc/config.gz拿回来,用同一份配置重新编内核树,再编模块;实在拿不到配置,就在内核树里把CONFIG_MODVERSIONS关掉重编,能绕过符号校验,但这只是应急,长期用会掩盖真正的不兼容。

现象五:hciattach报Can't init device hci0: Connection timed out (110)。

110 是超时错误码,含义是发了 HCI Reset 命令但没收到回应。原因有三个方向:BT_REG_ON 没拉高、串口引脚复用没配对、波特率不对。排查顺序是先量 BT_REG_ON 电平,再用stty -F /dev/ttyS1 115200加回环测试确认串口本身通,最后才怀疑波特率。很多板子的 UART 时钟源是 24MHz,1500000 除不尽,实际协商出来的波特率有偏差,降到 921600 或 115200 就正常了。

6. 装完怎么验证:AP6212 的三层验证法

驱动装完最忌讳的是“看到 wlan0 就以为成了”。我一般按三层走一遍,每层不过就不往下走,这样出问题时能立刻定位在哪一层。

#!/bin/sh # ap6212_check.sh —— 三层验证,每层不过就退出 echo "== 第一层:链路层,SDIO 枚举 + 固件下载 ==" ls /sys/bus/sdio/devices/ || { echo "SDIO 未枚举,查供电与设备树"; exit 1; } dmesg | grep -E "brcmfmac|dhd" | tail -20 echo "== 第二层:接口层,wlan0 与 MAC ==" ip link show wlan0 || { echo "wlan0 未创建,查固件与 nvram"; exit 2; } cat /sys/class/net/wlan0/address iw dev wlan0 info echo "== 第三层:业务层,扫描与关联 ==" iw dev wlan0 scan | grep -c "SSID" || { echo "扫描为空,查监管域与天线"; exit 3; } wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wpa_supplicant.conf -B sleep 5 udhcpc -i wlan0 ping -c 4 -W 2 223.5.5.5 || { echo "连通性失败,查关联与路由"; exit 4; } echo "== 蓝牙 ==" hciconfig hci0 || { echo "hci0 未创建,查 BT_REG_ON 与串口"; exit 5; } hciconfig hci0 up && hcitool scan

这个脚本的价值在于它把“哪一层坏了”变成了一个退出码。exit 1是硬件和枚举,exit 2是驱动和固件,exit 3是射频和配置,exit 4是关联和路由,exit 5是蓝牙链路。产线上一批板子跑下来,统计退出码分布就知道该改哪一环。

第三层的ping只是最粗的连通性判断,真要压一遍链路质量,还得看吞吐:

# 板子做客户端,主机起服务端 iperf3 -c 192.168.1.100 -t 30 -i 5 # 关注重传和信号,这两个数比吞吐更能说明问题 iw dev wlan0 station dump | grep -E "signal|tx retries|tx failed"

2.4G 单天线在干净环境下 20~30Mbps 是正常区间,低于 10Mbps 就该怀疑天线或共存参数了。tx retries持续偏高,说明空口干扰严重,这时候回去看 nvram 里的btc_mode有没有开,蓝牙和 WiFi 同时工作时的共存参数是不是默认值。

三层全过,我才会把驱动固化进镜像。有一次图省事跳过了第三层,只验证到 wlan0 出现就发了版,结果现场一批板子扫描正常、关联也正常,就是拿不到 IP,最后查出来是 nvram 里的板型参数和这批板子的天线不匹配,射频校准数据不对。从那以后我每次出镜像前都强制走一遍这个脚本,三层全绿才算数。希望这套流程能帮到你,少走几次回头路。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进