__initdata 的奇怪影响

__initdata 的奇怪影响

作者: 宋立新

Email[email protected]

 

恍然大悟后,当然也就不奇怪了。 不过当时 __initdata 修饰符确实给我们带来很大的困惑。

 

事情的经过是这样的。

 

通常我们设置mfp寄存器是在系统的启动阶段统一设置的, 所以 lc6830.c 中会有一个数组:

static mfp_cfg_t saar_mfp_cfg[] __initdata = {
RF_IF5_GPIO,
DF_INT_RnB_ND_INT_RnB,

};

 

系统初始化时,会调用:

pxa3xx_mfp_config(ARRAY_AND_SIZE(saar_mfp_cfg));

 

从而完成 mfp 寄存器的设置。

 

这里简单介绍一下 mfp 寄存器。

英文为: multi-function pin register

Marvell AP 集成度很高, 为了以最小的 PIN 脚数量支持最多的功能, pxa935 上的绝大多数 pin 脚可以内部路由到 6 种不同的功能上。 路由到那个功能就通过 mfp 寄存器的第3位设置。

 

Mfp 还可以用于设置某个 PIN 脚在系统待机时的状态, 是输出高电平, 输出低电平,还是处于输入状态, 等等。

 

我们的蓝牙模块有几种工作模式:

在不使用蓝牙时,如果系统进入待机状态,则希望该模块处于最低功耗状态,此时,控制其power GPIO 应该输出低, 以切换其电源。

 

而正在使用蓝牙功能时,如果系统进入待机状态,则希望该模块处于较低功耗状态,此时,控制其power GPIO 应该输出高, 以保持正常的功能, 比如,能够唤醒 AP

 

于是,模仿上面的数组,我们定义了如下数组:

 

322 static mfp_cfg_t __initdata wlan_bt_powerdown_high_mfp_cfg[] = {
323         GPIO174_BT_WIFI_POWER_GPIO_ON,
324 };
325 static mfp_cfg_t __initdata wlan_bt_powerdown_low_mfp_cfg[] = {
326         GPIO174_BT_WIFI_POWER_GPIO,
327 };

 

其中对 GPIO174 对应的 PIN 脚进行了相反的定义。 这样, 在打开蓝牙模块时,我们会调用:

pxa3xx_mfp_config(ARRAY_AND_SIZE(wlan_bt_powerdown_high_mfp_cfg));

而在关闭蓝牙模块时:

pxa3xx_mfp_config(ARRAY_AND_SIZE(wlan_bt_powerdown_low_mfp_cfg));

 

这样,确保该 PIN 脚处于合适的状态。

 

当时,使用工具 /root/bin/ureg_test 去读寄存器, 发现设置没有生效!

 

使用 trace32 跟踪代码, 发现该数组定义的数据结构各字段值不正确, 有时为0,有时为一些异常值!

 

苦思冥想, 终于发现定义数据结构时,直接模仿了 saar_mfp_cfg 的定义, saar_mfp_cfg 只在开机时使用, 我们的数据却要在开机后使用!

 

__initdata 修饰符去掉后, 发现一切正常了!

 

说明: 所有 __init* 修饰的数据,函数都用于说明它们只在系统开机阶段使用,其占用的空间会在系统完成启动后释放。 此时, 它们不再有效。

 

 

你可能感兴趣的:(数据结构,工作,email,工具,BT)