linux & android平台WIFI休眠唤醒问题

来源:互联网 发布:ubuntu安装分区详解 编辑:程序博客网 时间:2024/05/21 21:45

这两周很痛苦,因为自己负责的WIFI模块休眠唤醒有问题,导致每天晚上都睡不好觉,第二天没有精神上班。

不过所幸的是,这两天找到了方法解决了,现在想把经验和大家分享下。

把调试环境和硬件说一下:

硬件平台:三星S5PV210

kernel: 2.6.35

android:2.3.4

WIFI驱动使用SDIO接口,有独立的上电及复位接口。

先上问题:

在WIFI打开的情况下,在WIFI的设置界面,按“MENU”键,选择高级->Wi-Fi休眠策略->充电时永不休眠/永不休眠,然后按POWER键使机器进入深度休眠,唤醒后WIFI不正常,软件跑飞。

跑飞的LOG:

[   96.430142] DAPM sequencing finished, waiting 2ms
[   96.432989] DAPM sequencing finished, waiting 2ms
[   96.437106] smdkc110-rtc smdkc110-rtc: rtc disabled, re-enabling
[   96.437127] smdkc110-rtc smdkc110-rtc: rtc disabled, re-enabling
[   96.437143] smdkc110-rtc smdkc110-rtc: rtc disabled, re-enabling
[   96.437185] pm_op(): platform_pm_suspend+0x0/0x64 returns -16
[   96.437197] PM: Device alarm failed to suspend: error -16
[   96.437206] PM: Some devices failed to suspend
[   96.437541] PM: resume of devices complete after 0.321 msecs
[   96.486343] Restarting tasks ... 
[   96.493614] done.
[   96.499432] suspend: exit suspend, ret = -16 (2012-06-12 08:24:09.352134502 UTC)
[   96.508291] DAPM sequencing finished, waiting 2ms
[   96.515022] DAPM sequencing finished, waiting 2ms
[   96.518930] dai_active 0, IISMOD 00000100, IISCON 8050c491
[   96.526857] Inside s5p_i2s_resume..@550
[   97.430432] dhdsdio_disconnect: Enter
[   97.432612] dhdsdio_release: Enter
[   97.436029] kernel BUG at drivers/mmc/core/sdio_io.c:29!
[   97.441340] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[   97.449358] pgd = c0004000
[   97.452023] [00000000] *pgd=00000000
[   97.455578] Internal error: Oops: 817 [#1] PREEMPT
[   97.460342] last sysfs file: /sys/devices/platform/sec-fake-battery/power_supply/battery/technology
[   97.469354] Modules linked in: dhd
[   97.472737] CPU: 0    Not tainted  (2.6.35.7 #72)
[   97.477422] PC is at __bug+0x20/0x2c
[   97.480971] LR is at schedule+0x274/0x2e8
[   97.484955] pc : [<c0033dcc>]    lr : [<c0448298>]    psr: 60000013
[   97.484961] sp : df89ddc8  ip : df89dcd0  fp : df89ddd4
[   97.496391] r10: dfa991c4  r9 : dfa991c0  r8 : df87b050
[   97.501591] r7 : df87b058  r6 : bf02a670  r5 : bf02a668  r4 : db9ced80
[   97.508090] r3 : 00000000  r2 : 00000000  r1 : 00000002  r0 : 00000042
[   97.514591] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
[   97.521870] Control: 10c5387d  Table: 4f078019  DAC: 00000017
[   97.527587] 
[   97.527590] PC: 0xc0033d4c:
[   97.531832] 3d4c  e89da800 c0567cee e1a0c00d e92dd800 e24cb004 e1a0c001 e1a03002 e1a01000
[   97.539978] 3d6c  e1a0200c e59f0004 eb104f83 e89da800 c0567d05 e1a0c00d e92dd800 e24cb004
[   97.548123] 3d8c  e1a0c001 e1a03002 e1a01000 e1a0200c e59f0004 eb104f78 e89da800 c0567d1c
[   97.556269] 3dac  e1a0c00d e92dd800 e24cb004 e1a02001 e1a01000 e59f000c eb104f6f e3a03000
[   97.564415] 3dcc  e5833000 eafffffe c0567d33 e1a0c00d e92dd800 e24cb004 e59f0004 e30012e1
[   97.572561] 3dec  ebffffee c0567d4c e1a0c00d e92dd800 e24cb004 e1a01000 e59f000c eb104f5e
[   97.580706] 3e0c  e59f0008 e30012c5 ebffffe4 c0567d64 c0567d4c e1a0c00d e92dd800 e24cb004
[   97.588852] 3e2c  e59f000c eb104f54 e59f0008 eb104f52 e89da800 c0567d84 c0567dbb e1a0c00d
[   97.596999] 
[   97.597001] LR: 0xc0448218:
[   97.601244] 8218  0a000001 e1570006 0a000012 e59f20d8 e5963170 e5922000 e0223003 e1b03423
[   97.609390] 8238  0a000001 e1a00006 ebefc4a9 e59f30bc e5962184 e5933184 e1520003 0a000001
[   97.617536] 8258  e1a00006 ebefbcd3 e5960024 e1a01006 e2800207 ebefc519 e59530dc e1a00005
[   97.625681] 8278  e3530000 058530e0 059f3074 05837440 e5982004 e5951004 ebef9f37 ebf0204f
[   97.633827] 8298  ea000001 e1a0000c eb000990 e594300c e5933014 e3530000 ba000005 eb000a46
[   97.641973] 82b8  e3500000 b59f3038 b5935434 b285af62 baffff68 e5942000 e5943004 e3120002
[   97.650118] 82d8  e2433001 e5843004 0a000003 eaffff55 e3a03000 e5853000 eaffff85 e24bd024
[   97.658264] 82f8  e89dadf0 c05ff6f0 c044c5b8 c05f2900 c060e724 e1a0c00d e92dd878 e24cb004
[   97.666410] 
[   97.666413] SP: 0xdf89dd48:
[   97.670656] dd48  00205d39 00000000 df89dde4 df89dd60 c00578fc c04484d4 ffffffff df89ddb4
[   97.678802] dd68  bf02a670 df87b058 df89ddd4 df89dd80 c002fa6c c002f2c4 00000042 00000002
[   97.686947] dd88  00000000 00000000 db9ced80 bf02a668 bf02a670 df87b058 df87b050 dfa991c0
[   97.695093] dda8  dfa991c4 df89ddd4 df89dcd0 df89ddc8 c0448298 c0033dcc 60000013 ffffffff
[   97.703239] ddc8  df89dde4 df89ddd8 c02dc960 c0033db8 df89ddfc df89dde8 bf01e6c8 c02dc938
[   97.711384] dde8  ce7e2800 db9cd940 df89de0c df89de00 bf020194 bf01e6ac df89de24 df89de10
[   97.719530] de08  bf016718 bf02018c ce7e2800 db9cd880 df89de3c df89de28 bf01687c bf0166d0
[   97.727676] de28  00000002 bf02a65c df89de5c df89de40 bf0203c8 bf016838 00000002 bf02787c
[   97.735822] 
[   97.735825] IP: 0xdf89dc50:
[   97.740068] dc50  00000000 00000000 df89dd80 00000000 00000817 00000000 df89dc9c df89dc78
[   97.748214] dc70  c00368cc c003430c df89dd80 df88ae00 df89dd80 00000001 00000000 00000000
[   97.756359] dc90  df89dcd4 df89dca0 c0036acc c003686c df17601c df88ae00 df89dccc 00000817
[   97.764505] dcb0  c05f247c 00000000 df89dd80 df87b050 20000113 dfa991c4 df89dd7c df89dcd8
[   97.772651] dcd0  c002f2f4 c00368f8 df89c000 00000042 0000002d c05ffcdc 60000013 0000000f
[   97.780797] dcf0  df89dd14 df89dd00 c0448508 c0448030 00000002 00000000 df89dd9c df89dd18
[   97.788942] dd10  c00578fc c04484d4 c05ffd68 00000002 2df3f42b 0000000c afa3d24b 00000016
[   97.797088] dd30  60000013 60000013 df89dd5c 2020205b 342e3739 32303633 00205d39 00000000


WIFI模块使用的是SDIO接口,经过认真分析后,觉得应该从MMC驱动入手,毕竟是在MMC驱动出的问题。可关键是,查找了很久,也没发现什么可疑的。

最后无奈,采用最原始的方法,就是加LOG,一步一步的跟。

终于,还是被我找到原因了。

在SDIO驱动的sdio_reset_comm函数中,每次唤醒时,都会调用mmc_send_io_op_cond函数,现在出错时,就是这个函数返回失败了。

那么再研究下这个函数,发现它有通过mmc_wait_for_cmd函数来发命令给模块,而且传递的参数中,有MMC_CMD_RETRIES值,设置了3次。

那么,会不会是这个值太短了呢?

以我的经验,有的时候模块在唤醒的过程中,由于模块硬件本身没有准备好,还在进行模块本身的初始化,而这时候与模块进行通信有可能会导致通信失败。

那么,何不把MMC_CMD_RETRIES这个值改个极限值试试?即改一个极端的大一点的值。

我把它改成300,以及把当前函数下的mmc_delay(10)改成mmc_delay(100),再测试。

奇迹出现了,唤醒后,它居然没有跑飞。

我欣喜若狂,赶紧测试多几次,发现还真没有跑飞的情况出现。

那么,这个问题就这么解决了?

以我的经验,不能马上下结论,需要多测看看会不会导致别的问题出现。

于是我再多测,发现还会有另外一个问题,即dhd_dev_reset: dhd_bus_devreset: -35

但这个问题不是因为我修改跑飞的情况出现的,而是之前就出现的。

但是现在已经没有多少时间查找了,于是我做了如下修改:

1、修改MMC驱动,休眠唤醒初始化模块次数增加。

2、深度休眠时,把WIFI的POWER及RESET脚置低,使模块断电。唤醒时再恢复。
3、在WIFI打开的情况下,在WIFI的设置界面,按“MENU”键,选择高级->Wi-Fi休眠策略->屏幕关闭时休眠时,android层修改为按POER键休眠时,卸载wifi驱动,唤醒时再加载。
4、在WIFI打开的情况下,当选择“充电时永不休眠”时,充电情况下,休眠时,锁住电源不让系统进入深度休眠(虽然进入深度休眠按照方法1已经改好,但测试时发现唤醒后会有10%的概率产生驱动出错的问题)。非充电情况下休眠时按照方法2操作。
5、在WIFI打开的情况下,当选择“永不休眠”时,休眠时锁住电源不让系统进入深度休眠。
按如上方法修改后,WIFI未测到出现休眠唤醒问题。

此问题得到圆满解决。


原创粉丝点击