• 正文
  • 相关推荐
申请入驻 产业图谱

RK3588+AP6256|不掉电重启AP模式踩坑调试实录

7小时前
205
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

前言:

嵌入式Linux项目中,把WiFi模组切换为AP模式是个常见需求——配网、调试、本地组网都离不开它。但AP6256这颗模组在AP模式下踩坑的概率,远比STA模式高得多。今天基于 RK3588 平台搭配 AP6256模块,给大家分享一份超实用、可直接落地的内核级 WiFi 调试笔记。

一、故障环境

1.1  开发环境

主控平台:RK3588

WiFi 芯片:AP6256(BCM43456)

内核版本:Linux 5.10

文件系统:Ubuntu 20.04

通信接口:SDIO

1.2  问题表现

你可能遇到过这些场景:

hostapd启动后,手机死活搜不到热点

搜到了热点,输入密码却反复提示"正在连接"

好不容易连上了,几秒后自动断开,周而复始

日志里一堆看不懂的报错:rsn_cap_value error、Match already configured、ctrl_iface exists...

这类故障在量产设备中极其常见:掉电重启一切正常,软件重启 / 驱动重载就 “瘸腿”,隐蔽性强、定位难度高。本文帮助大家解决不掉电软重启后 AP 模式无法创建、但 STA 模式正常的隐蔽问题。

1.3  根因分析

对比正常 / 异常两种场景的驱动日志,找到了最关键的差异点:MAC 地址来源不同。

正常的情况下,wifi模块加载后的MAC地址是读取自身的MAC地址;

不正常的情况下,wifi在加载驱动时是通过加载nvram_ap6256.txt文件中定义的mac地址。

如下图所示:


图1 nvram_ap6256.txt


图2 异常状态下的wifi驱动加载信息.log


图3 正常状态下的wifi驱动加载信息.log

二、解决方案

2.1  核心原理

AP6256的无线功能依赖bcmdhd驱动。如果驱动没起来,后面所有配置都是空中楼阁。由于wifi模块是以SDIO的通信的,相关的配置如下:

sdio_pwrseq: sdio-pwrseq {
		compatible = "mmc-pwrseq-simple";
		pinctrl-names = "default";
		pinctrl-0 = <&wifi_enable_h>;
/*
		 * On the module itself this is one of these (depending
		 * on the actual card populated):
		 * - SDIO_RESET_L_WL_REG_ON
		 * - PDN (power down when low)
		 */
		post-power-on-delay-ms = <200>;
		reset-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_LOW>;
};
wireless_wlan: wireless-wlan {
		compatible = "wlan-platdata";
		wifi_chip_type = "ap6256";
		pinctrl-names = "default";
		pinctrl-0 = <&wifi_host_wake_irq>;
		WIFI,host_wake_irq = <&gpio1 RK_PD6 GPIO_ACTIVE_HIGH>;
			status = "okay";
	};
&sdmmc {	//wifi
	max-frequency = <150000000>;
	supports-sdio;
	bus-width = <4>;
	disable-wp;
cap-sd-highspeed;
cap-sdio-irq;
	keep-power-in-suspend;
	pinctrl-names = "default";
	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>;
//sd-uhs-sdr104;
	mmc-pwrseq = <&sdio_pwrseq>;
	non-removable;
	status = "okay";
};

查询博通官方手册明确规定,在不掉电的情况下重新加载,需要把WL_REG_ON下拉至少200ms。


图4 WL_REG_ON 复位时序说明

如果复位时间不足:

STA 模式:只需要基础初始化,能正常用

AP 模式:需要完整射频 + 模式配置,直接失效

这就是 “STA 好、AP 坏” 的本质原因。

2.2  踩坑实录

第一时间在设备树sdio_pwrseq节点配置了 200ms 延时:

sdio_pwrseq: sdio-pwrseq {
    compatible = "mmc-pwrseq-simple";
    pinctrl-names = "default";
    pinctrl-0 = <&wifi_enable_h>;
    post-power-on-delay-ms = <200>;  // 这里我以为会生效
    reset-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_LOW>;
};

结果:完全不生效!

实际测量 GPIO 波形,不管设置为什么值,下拉时间永远只有20ms,远达不到 200ms 要求。

跟踪内核drivers/mmc/core/pwrseq_simple.c后,问题暴露:

①系统冷上电会依次执行:

mmc_pwrseq_simple_pre_power_on
mmc_pwrseq_simple_post_power_on

②驱动重载 / 软重启

只执行 pre_power_on,完全不执行 post_power_on

而post-power-on-delay-ms这个设备树属性,只在 post_power_on 函数里生效。所以无论设多少,都不会被调用。

2.3  最终处理

解决方案也非常直接:把延时逻辑移到 pre_power_on 里。

修改mmc_pwrseq_simple_pre_power_on函数,添加延迟的代码:

static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
{
struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
if (!IS_ERR(pwrseq->ext_clk) && !pwrseq->clk_enabled) {
		clk_prepare_enable(pwrseq->ext_clk);
		pwrseq->clk_enabled = true;
	}
	mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
+	if (pwrseq->post_power_on_delay_ms)
+		msleep(pwrseq->post_power_on_delay_ms);
}

三、调试总结

该问题在RK3568/RK3588 + AP6256/AP6275系列方案中高度通用,建议直接收藏,遇到同类 WiFi AP 故障可直接套用。

如果按照本文的顺序排查,90%的AP模式异常都能定位到根因。剩下的10%,通常是硬件层面的射频干扰或供电不稳,那就需要示波器和频谱仪上场了。

关注眺望电子,获取更多嵌入式Linux调试实战经验!

相关推荐