本帖最后由 旋律 于 -3-27 09:15 编辑
一、关于BT driver的移植:
1. Enablebluetootch in BoadConfig.mk
BOARD_HAVE_BLUETOOTH := true
2.实现BT电源管理rfkill驱动。
Kernel/driver/bluetooth/bluetooth-power.c 高通的这个文件基本上不用动。
在kernel\arch\arm\mach_msm7x27.c: static int bluetooth_power(int on)中
实现:上电:把bt_reset pin 和bt_reg_on pin 拉低
mdelay(10);
把bt_resetpin 和bt_reg_on pin 拉高
mdelay(150)
下电:把bt_reset pin 和bt_reg_on pin 拉低
3. RebuildAndroid image and reboot
命令行测试:
echo 0 >/sys/class/rfkill/rfkill0/state //BT下电
echo 1 >/sys/class/rfkill/rfkill0/state //BT上电
brcm_patchram_plus-d --patchram /etc/firmware/BCM4329B1_002.002.023.0061.0062.hcd/dev/ttyHS0
hciattach -s115200 /dev/ttyHS0 any
没任何错误提示是可以用以下测试
hciconfig hci0up
hcitool scan
4.实现BT睡眠唤醒机制
Kernel\drivers\bluetooth\bluesleep.c一般来说这个文件改动比较少,但可能逻辑上会有些问题。需要小的改动。
在kernel\arch\arm\mach_xxx/board_xxx.c:bluesleep_resources中定义gpio_host_wake(BT唤醒host脚)、gpio_ext_wake(host唤醒BT脚)、host_wake(BT唤醒host的中断号)。
注:各个平台的board_xxx.c文件名字不同,请客户确认
5.系统集成
1)在init.qcom.rc中确认有下面的内容:
service hciattach/system/bin/sh /system/etc/init.qcom.bt.sh
user bluetooth
group qcom_oncrpc bluetooth net_bt_admin
disabled
oneshot
2)修改init.qcom.bt.sh
确认有:
BLUETOOTH_SLEEP_PATH=/proc/bluetooth/sleep/proto
echo 1 >$BLUETOOTH_SLEEP_PATH
/system/bin/hciattach-n /dev/ttyHS0 any 3000000 flow & 改为:
./brcm_patchram_plus--enable_lpm –enable_hci --patchram /system/etc/wifi/BCM4329BT.hcd --baudrate3000000 /dev/ttyHS0 &
注掉:高通下载firmware的命令。
6.重新编译system。此时BT应该能运行了。
二、BT的休眠唤醒配置
BT的休眠在driver/bluetooth/bluesleep.c中,首先驱动的名字叫“bluesleep”与arch/arm/mach-msm/board-msm7x30.c相匹配就执行platform_driver_probe(&bluesleep_driver, bluesleep_probe)然后调用static int __init bluesleep_probe(struct platform_device *pdev),这里会配置两个引脚HOST_WAKE_BT & BT_WAKE_HOST
bsi = kzalloc(sizeof(struct bluesleep_info), GFP_KERNEL);
if (!bsi)
return -ENOMEM;
res = platform_get_resource_byname(pdev, IORESOURCE_IO,
"gpio_host_wake");
if (!res) {
BT_ERR("couldn´t find host_wake gpio\n");
ret = -ENODEV;
goto free_bsi;
}
bsi->host_wake = res->start;
//[zhangmin-111230] change the configuration of BT sleep gpio from bt_power to here {
gpio_tlmm_config(GPIO_CFG(bsi->host_wake, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),GPIO_CFG_ENABLE);
//[zhangmin-111230] }
ret = gpio_request(bsi->host_wake, "bt_host_wake");
if (ret)
goto free_bsi;
ret = gpio_direction_input(bsi->host_wake);
bsi->host_wake_irq = platform_get_irq_byname(pdev, "host_wake");
如上代码所示,主要将HOST_WAKE_BT设置为输出脚,BT_WAKE_HOST 设置为输入脚并也设置为中断脚,等待BT芯片的唤醒。
然后再bluesleep_init函数中建立BT目录/proc/bluetooth/sleep/读btwake中HOST_WAKE_BT的状态。读出的状态值为0或1。
或在BT目录/proc/bluetooth/sleep/写btwake中HOST_WAKE_BT的状态。写出状态值为0或1。
Part 1.有时候会出现打开蓝牙打不开的现象。
答:在/system/bluetooth/bluedroid/bluetooth.c中的注册socket时间增加时间。具体做法是在函数int bt_enable()中
for (attempt = 1000; attempt > 0;attempt--) {
hci_sock = create_hci_sock();
if (hci_sock < 0) goto out;
if (!ioctl(hci_sock, HCIDEVUP, HCI_DEV_ID)) {
break;
}
close(hci_sock);
usleep(10000);// 10 ms retry delay
}
修改红色标记的延时时间,即可解决偶尔开蓝牙出现打不开的现象。
Part 2.打开蓝牙时间过长,会要16秒时间。
答:这个跟开启蓝牙加载patchram有很大的关系,由以前的两部分加载,现在变成一部分加载
改之前:
/system/bin/brcm_patchram_plus.dat -d --enable_lpm --patchram /etc/BCM4330.hcd /dev/ttyHS0
/system/bin/brcm_patchram_plus.dat -d -baudrate 3000000 /dev/ttyHS0
改之后:
brcm_patchram_plus.dat--enable_lpm --enable_hci --patchram /etc/BCM4330.hcd /dev/ttyHS0 --baudrate 3000000 &
修改过后能稳定加载BT。
还可以修改波特率来加快加载patchram的速度。具体操作如下
在函数void proc_patchram()中添加指定的波特率:
if (use_baudrate_for_download) {
cfsetospeed(&termios, B115200);
cfsetispeed(&termios, B115200);
tcsetattr(uart_fd, TCSANOW, &termios);
}
指定加载patchram的波特率为115200.
并且在主函数main()里要在两次执行函数proc_reset()中间追加一次执行函数proc_baudrate(),这样就可以确保波特率已经设置好了。
BCM4330 WIFI 调试记录
Part 1
问:打开wifi,连接wifi热点,提示连接成功,但headbar上不显示wifi图标,back退出wifi设置,再进入,提示wifi已断开。
答:首先现象复现,当现象复现时进入adb shell,然后输入ifconfig 查看是否有wlan0 端口,然后在adb shell 中ping 192.168.1.101(嵌入式设备的IP),如果能Ping通则说明底层wifi设备与AP是连接通的。所以把问题转向上层。上层在frameworks/base/services/java/com/android/server/ConnectivityService.java文件中查看private void handleDisconnect(NetworkInfo info)函数的实现,问题可能出现在这里。
Part 2
问:出现新热点,需要重启WIFI才可以扫描到。
问:20s内无法连接到WIFI热点。
问:已连接的热点关闭,不会自动连接下一个热点。
答:这些问题都是供应商芯片的firmware没有配置好,所以直接找FAE换掉。
Part 3
问:调试中如果遇到dhd_sdio_probe fail 。
问:发现sdio register timeout 。
答:因为我们用到的WIFI数据通道是SDIO接口,所以要在log信息中查看sdcard是否有加载。没加载的话就看看WIFI芯片的上电(如WIFI_REG_ON这个PIN脚)。
Part 4
问:如果在wifi的设置里面选中wifi选项出现ERRO(或错误)的提示。
答:首先在adb shell中lsmod查看.ko文件是否已经加载。如没加载cat /proc/kmsg查看是否是版本匹配的问题。如遇版本匹配则在kernel/scripts/setlocalversion中将echo “+”中去掉。如果顺利加载了驱动,则要看看MAC地址是否有,并且是否合理。
Part 5
问:发现在WIFI设置选项中有已经选上了wifi并且勾应打上了,过一会出现wifi的勾自动消失。
答:这种情况在adb shell中用ifconfig查看Wlan的接口用的是否是wlan0,有可能是eth0。如果是eth0则在hardware/libhardware_legacy/wifi/wifi.c中的#define WIFI_DRIVER_MODULE_ARG"firmware_path=/system/etc/firmware/wlan/sdio.bin nvram_path=/data/simcom/nvram.txt iface_name=wlan0" 中查看iface_name=wlan0是否已经加上。
Part 6
问:有的路由器不能扫描的到。
答:查看wlan的设置的channel是否在1-14这个频段,因为如果wlan设置成USA模式则channel的范围在1-11之间,channel 12,13,14就不会收索的到。所以要在nvram.txt中修改成ccode=ALL,并且在gqcom_cfg.ini中把APCntryCode=ALL。这样应该就可以扫描到所有的channel了。当然如果上层还是没有收索到的话,在Settings.java中也要做相应的修改。
常用的命令:wl channels_in_country
wl chanlist
wl channels
wl country
Part 7
问:【预置条件】:wifi 已连接 wifi sleep policy模式为When screen turns off
【操作步骤】:wifi连接网络,静置屏幕熄灭大约5分钟,再次点亮屏幕
【测试结果】:wifi一直处在scanning状态,无法连接网络,关闭再打开恢复正常
【预期结果】:点亮屏幕后,wifi自动连接成功
答:调试分析记录:
1.在frameworks/base/services/java/com/android/server/WifiService.java中修改LCD灭屏后关掉WIFI的时间长短,由以前的2分钟修改为现在的1秒钟。
结果是短时间休眠后唤醒可以顺利连上AP,但经过长时间休眠(如15分钟)后唤醒机器还是无法连接AP。
2.检查Kernel中POWER_ON使能脚,看是否有其它地方被占用过,结果是屏蔽所有其它用到过该脚的代码还是无用。
3.检查CP侧代码,将CP侧POWER_ON引脚由以前的某种特殊功能设置成普通的Output模式,然后AP就可以自由的控制其高低电平了。
修改后的结果还是以无效告终。
4.检查external/wpa_supplicant_6/wpa_supplicant/文件夹下面的代码,检查WEXT驱动代码。结果还是失败。
5.最后在机器休眠15分钟后,用底层命令行来scan、连接等动作的操作,结果根本无法扫描到AP。故把问题集中在驱动底层。经过修改dhd.ko、sdio.bin文件
现在此Bug终于得解。
6.也有问题不出现在驱动dhd.ko文件中,可能出现在mmc驱动中的sdio通道。在函数mmc_pm_notify中当出现PM_POST_SUSPEND或PM_POST_HIBERNATION的情况时就有可能移除掉了sdio通道,所以函数mmc_detect_change(host, 0)要加一个判断,当sdio作为wifi通道时就不能移除。移除后的后果就是此Bug。
Android BCM4330 FM驱动调试
FM Porting
1 修改init.xxx.rc 增加服务,并把btld push到/system/bin下
service btld /system/bin/logwrapper /system/bin/btld
user root
group bluetooth net_bt_admin
disabled
oneshot
2 合并system\bluetooth\bluedroid下的代码
主要是bluetooth enable及fm enable部份的代码
3 合并frameworks下的代码
BT和Fm及电源管理部份,主要提供给system service
4 编译packages\apps\FmRadio
编译得到FmRadio.apk,直接intall到android机子上使用.
一、底层关于FM驱动的Lib库,首先要想好在底层我们要准备好提供上层的JNI接口。
如下几个接口:
1.fm_power_on(); 打开FM;
2.fm_power_off(); 关掉FM;
3.fm_search_freq(int frq, char up); FM自动搜台,并跳到下一个台的位置;
4.fm_get_freq(); FM得到当前电台的频率;
5.fm_set_mute(); 设置FM静音;
6.fm_set_volue(int value);设置FM的音量大小;
这些函数实现后,编译成动态库(生成.so文件)。
二、在framework/base/core/jni目录下实现一个.cpp文件把lib库调用,实现FM的一些工作,这个jni就会直接给mangerserver,最上面的apk应用会调用Manger层,而manger和mangerserver之间的通信是通过IPC机制实现的。