android 蓝牙 驱动,转个蓝牙修改帖--Android BCM4330 蓝牙BT驱动调试记录

本帖最后由 旋律2014 于 2014-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机制实现的。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值