首先結合項目從整體上去把握這部分:
藍牙模塊中一個比較核心的文件是bluetooth.c, 在我們上電的時候, 會調用這個文件中bt_enable()這個函數, 在這個函數里面先調用set_bluetooth_power()上電,然后調用property_set("ctl.start", "hciattach"), 去啟動hciattach這個服務,從而運行brcm_patchram_plus這個進程。這個服務會加載我們firmware等一些工作。這部分工作做完后, 我們會調用property_set("ctl.start","bluetoothd"),這個服務是啟動我們的bluz進程。如果以上成功的話,藍牙芯片將會開始工作。
藍牙需要正常工作,簡而言之,需要做三部分工作:
i) 給芯片上電。
ii) hciattach服務啟動,從而加載固件,設置波特率等一系列的操作。(硬)
iii 啟動bluetooth的協議,從而讓藍牙去正常工作。 (軟)
其次來分析下具體的工作流程:
a) BT管腳介紹
BT_REG_ON 和BT_RESET打開藍牙時拉高, 關閉藍牙時候拉低。 平時不需要控制。一般放在RF-KILL里面,可以在命令行里面操作。
UART可以一直配置為UART(TX/RX/RTS/CTS), 也可以只在使用藍牙的時候配置為UART.
I)相互對應: TX和RX,RTS和CTS, RTS和CTS用來做硬件流控
II)把自己的RTS(對方的CTS)拉高,對方就不能發數據
III)檢測到自己的CTS為高(對方的RTS),就不能給對方發數據
IV)BT上電后(未做初始化),BT_RTS應為低
V)主機串口未打開后應該為低
睡眠控制腳: HOST_WAKE 和BT_WAKE
i) 對於AP來說, 一個是GPO, 一個是中斷。
ii) 在BT使用前配置好, 在bluesleep.c中控制。
iii) 如果不使用lpm(低功耗模式), 可以不管這些, 在新板回來驗證bt功能時候, 往往不需要低功耗模式。
a) 硬件驗證
首先應該做下面的事情:
i)配置好UART的管腳
ii)配置好BT_REG_ON/BT_RESET的管腳, 並改好RFKILL代碼
iii)BT_WAKE和HOAT_WAKE可以先不配
其次驗證流程
下電:通過RFKILL拉低BT_REG_ON和BT_RESET讓BT進入缺省狀態
上電:同樣通過RFKILL拉高BT_REG_ON和BT_REST讓芯片處於上電狀態
通過brcm_patchram_plus初始化BT芯片
Hciconfig uart0 up
Hcitool scan搜索設備,如果能夠搜索到設備,則說明藍牙芯片ok.
b) Brcm_patchram_plus的作用
像我們上面提到的那樣, 在啟動hciattach服務的時候, 會啟動這個brcm_patchram_plus這個進程。這個進程是有brcm_patchram_plus.c這個文件編譯而成。
它的作用是初始化藍牙芯片, 進行基本參數的配置: lpm、PCM等參數
參數解釋(brcm_patchram_plus)列出
-d: 顯示調試信息
-enable_hci: 啟動hci協議
-enable_lpm: 啟動lpm模式
-baudrate: 指定工作時的波特率
-patchram: 指定hcd文件
- bd_addr: 加載藍牙地址
- /dev/ttyxxx: 指定串口
brcm_patchram_plus -d –bd_addrxx:xx:xx:xx:xx:xx --enable_hci --enable_lpm --baudrate3000000 --patchram /etc/bcm4330.hcd /dev/ttyHS0
進行硬件驗證時可以簡化:
brcm_patchram_plus-d --enable_hci /dev/ttyHS0
c) LowPower Mode
lpm的具體參數設定在brcm_patchram_plu.c代碼中
unsignedchar hci_write_sleep_mode[] = { 0x01, 0x27, 0xfc,
0x0c,//command length
0x01,// Sleep_Mode UART
0x01,// Host Idle Threshold, roughly 1*300ms
0x01,// Host Controller Idle Threshold
0x01,// BT_WAKE_Active_Mode, 0-active low, 1-active hgih
0x01,// HOST_WAKE_Active_Mode, 0- active low, 1-active hgih
0x01,// Allow_Host_Sleep_During_SCO
0x01,// Combine_Sleep_Mode_And_LPM
0x00,// Enable_Tristate_Control_Of_UART_Tx_Line
0x00,// Active_Connection_Handling_On_Suspend
0x00,// Resume_Timeout
0x00,// Enable_BREAK_To_Host
0x00//Pulsed_HOST_WAKE
};
BT芯片的lpm需要與HOST的bluesleep同時工作
在我們測試藍牙睡眠的時候, 手動往/proc/bcm/asleep/proto寫1, 就可以啟動睡眠模式。
i)正常代碼:
BlueZ:啟動BT時,(BlueZ在bluetooth.c的bt_enable里面)
改動init.qcom.rc文件來打開/關閉BT芯片的lpm
servicehciattach /system/bin/brcm_patchram_plus --enable_hci --enable_lpm --baudrate 3000000 --patchram/etc/firmware/bcm4329.hcd /dev/ttyHS0
ii)AP通過BT_WAKE來控制BT
拉高BT_WAKE: BT不能睡眠,或者必須醒來
拉低BT_WAKE:BT可以睡眠,睡不睡BT自己決定
HOST每次發數據前都要拉高BT_WAKE
BT如果睡眠,會拉高BT_RTS來阻止HOST發數據
iii)Bluesleep.c概述
bluesleep_init: 創建結點,bluesleep_probe: 申請GPIO/INT/WAKE_LOCK資源 ,啟動定時器監控主機發送數據(超時即可拉低BT_WAKE),打開中斷來監控HOST_WAKE的狀態 ,bluesleep_outgoing_data: 拉高BT_WAKE喚醒BT ,bluesleep_hostwake_isr: 中斷處理函數,進行wake任務調度。
對於新的項目, 我們首先確保HOST_WAKE和BT_WAKE的INT和GPIO能正確的申請到 ,其次確保bluesleep被編譯,如下三個結點被創建
/proc/bcm/asleep/proto、/proc/bcm/asleep/hostwake、/proc/bcm/asleep/btwake
三、項目中藍牙一些bug分析。
i)在傳送多個文件過程中, 傳輸幾個文件后, 傳輸的進度條停止不動。並且內核一直在打印h4_recv: Unknown HCI packet type
答: 我們申請Host_wake中斷類型為高電平。當第一次打開藍牙時, Host_wake =1時,此時產生中斷。然后就輪番改變中斷類型。當我們傳輸文件過程中,會來好多次中斷,從而會響應多次中斷處理函數,這個函數會進行反復打開和關閉串口的工作。這就是問題之所在。當bt給 HOST傳數據的時候,反復打開、關閉串口,從而會造成一段時間內串口是不工作的。因此會導致bt中的buf溢出。這就是數據的幀檢測位出問題的原因:rfcomm_recv_frame:bad checksum in packet。
我們的做法是:在傳輸文件過程中,不要讓HOST去關閉串口。直到我們文件傳輸結束,再用內核定時器去關閉串口。
ii)在傳輸過程中, 在UI上面點擊搜索藍牙設備, 沒有任何反應,或彈出藍牙進程無響應。
答:這樣的問題, 一般是處理睡眠代碼的流程有問題。在點擊搜索藍牙設備將界面的時候,HOST沒有喚醒藍牙設備。
iii) 在待機的情況下, 其他手機給測試機傳輸文件, 測試機沒有任何反應。
答:經過分析才發現是這樣的情況:當其他手機給我們測試機傳文件的時候,中斷也來了響應,然而剛來了響應后,系統又重新進入suspend狀態。
我們的做法:在剛接受文件的時候, 可以嘗試着給HOST加wakelock,不要讓HOST睡眠。這樣可以很好地解決問題。不過不要忘記在最后也加上unwakelock下哦。
iv)藍牙在某些特定的情況下打不開。概率非常非常低。重啟完手機后,藍牙可以正常打開。
答:一般都是由於藍牙在patchram_plus加載firmware沒有成功,從而造成的。有可能是進程阻塞引起的。在加載固件的時候,嘗試着在再次加載固件。
v)某些型號(如kewei)車載藍牙連上手機待機電流為11MA,分析下原因。
答:手機藍牙連接上耳機或carkit后,即使在沒有打電話及聽音樂的狀態下,物理鏈路還是會保持的,也就是藍牙的射頻仍然在工作(這是協議規定的,否則會發生來電時無法用耳機或carkit接聽等問題),而不同的耳機或carkit查詢鏈接存在的時間間隔有所不同(主要由雙方在鏈路建立時協商決定),因此在待機電流上則表現為不同的產品不一樣,如圖1是手機與kewei連接上后的OTA(空中數據包分析儀),OTA表明系統的POLL和NULL交互非常頻繁(kewei作為主,主動發起POLL),這是導致手機待機電流上升的主要因素。圖2 是和skyworth建立鏈接后的OTA,其交互頻率要比kewei低10倍,因此表現在待機電流上會小些。
相關文檔 下載: http://download.csdn.net/detail/angelbosj/4484676
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
