剛調完rtl8821cs的wifi功能,項目需要打通藍牙配網功能。
調試過程中遇到各種問題中間幾乎放棄,倒騰了幾天最后還是打通了,順便記錄下過程。
通信接口:SDIO @WiFi、Uart @BT;
工作頻段:2.4G/5.8G +BT4.2;
rtl8821cs是一個藍牙wifi二合一模塊,wifi走的是sdio接口,支持2.4G,5G.
bt走的是uart接口 支持bluez blue-alsa開源協議。
一、內核配置編譯
我的內核版本是kernel-4.4.55
配置如下
make menuconfig <*> Networking Support--> <*> Bluetooth subsystem support ---> Bluetooth device drivers --->
rtl8821cs 是uart接口的藍牙
內核需要先配置如下兩個配置項,如果是usb的接口則相應的配置usb的驅動支持即可。
在這里直接配置編譯進內核,也可以配置成ko模塊方便調試。
[*] UART (H4) protocol support
[*] Realtek Three-wire UART (H5) protocol support
------------------------------------------------------------------------------------------------------------------------------------+ | | | < > RTK HCI USB driver | | | | < > HCI USB driver | | | | < > HCI SDIO driver | | | | <*> HCI UART driver | | | | [*] UART (H4) protocol support | | | | [ ] BCSP protocol support | | | | [ ] Atheros AR300x serial support | | | | [ ] HCILL protocol support | | | | [*] Realtek Three-wire UART (H5) protocol support | | | | [ ] Three-wire UART (H5) protocol support | | | | [ ] Intel protocol support | | | | [ ] Broadcom protocol support | | | | [ ] Qualcomm Atheros protocol support | | | | < > HCI BCM203x USB driver | | | | < > HCI BPA10x USB driver | | | | < > HCI BlueFRITZ! USB driver | | | | < > HCI VHCI (Virtual HCI device) driver | | | | < > Broadcom Bluetooth Low Power Manager Support | | | | < > Broadcom Bluetooth Low Power Manager Support for AXP | | | | < > Broadcom Bluetooth Low Power Manager Support for remote control | | | | <*> Realtek Bluetooth Low Power Manager Support | | | | < > Marvell Bluetooth driver support
相關驅動代碼在如下目錄,
linux-4.4/drivers/bluetooth
二、藍牙服務依賴包
1、dbus-1.10.4
2、bluez-5.38
3、bluez-alsa-20180913
4、glib-2.50.1
uart接口需要hciattach工具,bluez里面已經自帶了,但是rtk的需要專門的工具rtk_hciattach 才行,
故還需要如下依賴包
5、rtk_hciattach
同時還需要對應的fireware版本。
配置好后編譯打包燒錄,開始調試。
====================調試=============================
1、首先應該插入或者已經啟動wifi驅動,保證模塊已經上電。
2、先啟動dbus服務,待會bluetoothd 起來需要羊刀dbus。
/etc/init.d/dbus start
啟動后用ps查看dbus服務進程,
/usr/sbin/dbus-daemon --system
並且可以在/var/run/dbus/查看到通信端口
root@airfly:/# ll /var/run/dbus drwxr-xr-x 2 root root 60 Jan 2 14:31 . drwxr-xr-x 7 root root 240 Jan 2 14:33 .. srwxrwxrwx 1 root root 0 Jan 2 14:31 system_bus_socket
3、 使用rfkill 解除bluetooth的block
echo 0 > /sys/class/rfkill/rfkill0/state echo 1 > /sys/class/rfkill/rfkill0/state
4、如果藍牙驅動是ko模塊,這時可以插入藍牙驅動。
5、使用rtk_hciattach綁定uart端口
usb接口的藍牙可以不用這一步。
rtk_hciattach -n -s 115200 /dev/ttyS1 rtk_h5 &
注意這個過程需要加載固件才行,如果固件不存在、不匹配或者錯誤就會失敗。
root@airfly:/# rtk_hciattach -n -s 115200 /dev/ttyS1 rtk_h5 & root@airfly:/# Realtek Bluetooth init uart with init speed:115200, type:HCI UART H5 Realtek Bluetooth :Realtek hciattach version 3.1.0099684.20181218-163903 Realtek Bluetooth :Use epoll Realtek Bluetooth :[SYNC] Get SYNC Resp Pkt Realtek Bluetooth :[CONFIG] Get SYNC pkt Realtek Bluetooth :[CONFIG] Get CONFG pkt Realtek Bluetooth :[CONFIG] Get CONFG resp pkt Realtek Bluetooth :dic is 1, cfg field 0x14 Realtek Bluetooth :H5 init finished Realtek Bluetooth :Realtek H5 IC Realtek Bluetooth :Receive cmd complete event of command: 1001 Realtek Bluetooth :HCI Version 0x08 Realtek Bluetooth :HCI Revision 0x000c Realtek Bluetooth :LMP Subversion 0x8821 Realtek Bluetooth :Receive cmd complete event of command: fc6d Realtek Bluetooth :Read ROM version 01 Realtek Bluetooth :LMP Subversion 0x8821 Realtek Bluetooth :EVersion 1 Realtek Bluetooth :IC: RTL8821CS Realtek Bluetooth :Firmware/config: rtl8821cs_fw, rtl8821cs_config Realtek Bluetooth :Couldnt access customer BT MAC file /opt/bdaddr Realtek Bluetooth :Couldnt open extra config /opt/rtk_btconfig.txt, No such file or directory Realtek Bluetooth :Original Cfg len 25 Realtek Bluetooth :Config baudrate: 04928002 Realtek Bluetooth :uart flow ctrl: 0 Realtek Bluetooth :55 ab 23 87 13 00 0c 00 10 02 80 92 04 50 c5 ea Realtek Bluetooth :19 e1 1b fd af 5b 01 a4 0b Realtek Bluetooth :Cfg length 25 Realtek Bluetooth :Vendor baud from Config file: 04928002 Realtek Bluetooth :Load FW /lib/firmware/rtlbt/rtl8821cs_fw OK, size 40448 Realtek Bluetooth :rtb_get_fw_project_id: opcode 0, len 1, data 10 Realtek Bluetooth :FW version 0xaa7b2a21, Patch num 2 Realtek Bluetooth :Chip id 0x0001 Realtek Bluetooth :Chip id 0x0002 Realtek Bluetooth :Patch length 0x6078 Realtek Bluetooth :Start offset 0x00003d40 Realtek Bluetooth :Svn version: 20445 Realtek Bluetooth :Coexistence: BTCOEX_20180125-2828 Realtek Bluetooth :FW exists, Config file exists Realtek Bluetooth :Total len 24721 for fwc Realtek Bluetooth :baudrate in change speed command: 0x02 0x80 0x92 0x04 Realtek Bluetooth :Receive cmd complete event of command: fc17 Realtek Bluetooth :Received cc of vendor change baud Realtek Bluetooth :Final speed 1500000 Realtek Bluetooth :end_idx: 98, lp_len: 25, additional pkts: 1 Realtek Bluetooth :Start downloading... Realtek Bluetooth :Last packet 227 Realtek Bluetooth :Send last pkt Realtek Bluetooth :Disable host hw flow control Realtek Bluetooth :h5_hci_reset: Issue hci reset cmd Realtek Bluetooth :Receive cmd complete event of command: 0c03 Realtek Bluetooth :Received cc of hci reset cmd Realtek Bluetooth :Init Process finished Realtek Bluetooth post process Device setup complete
此時hci0藍牙端口已經生成,如果是usb接口的不用hciattach就有端口,使用hciconfig工具可以查看端口及狀態
當前應該還是DOWN狀態
root@airfly:/# hciconfig hci0: Type: BR/EDR Bus: UART BD Address: 48:98:CA:AD:3C:AB ACL MTU: 1021:8 SCO MTU: 255:12 DOWN RX bytes:1152 acl:0 sco:0 events:33 errors:0 TX bytes:814 acl:0 sco:0 commands:33 errors:0
6、啟動hci0,狀態更新為UP RUNNING
root@airfly:/# hciconfig hci0 up root@airfly:/# hciconfig hci0: Type: BR/EDR Bus: UART BD Address: 48:98:CA:AD:3C:AB ACL MTU: 1021:8 SCO MTU: 255:12 UP RUNNING RX bytes:2304 acl:0 sco:0 events:66 errors:0 TX bytes:1492 acl:0 sco:0 commands:67 errors:0
7、啟動bluetoothd 服務
root@airfly:/# bluetoothd -n & root@airfly:/# bluetoothd[5559]: Bluetooth daemon 5.38 bluetoothd[5559]: Starting SDP server bluetoothd[5559]: Bluetooth management interface 1.10 initialized bluetoothd[5559]: Not enough free handles to register service bluetoothd[5559]: Error adding Link Loss service bluetoothd[5559]: Not enough free handles to register service bluetoothd[5559]: Not enough free handles to register service bluetoothd[5559]: Not enough free handles to register service bluetoothd[5559]: Current Time Service could not be registered bluetoothd[5559]: gatt-time-server: Input/output error (5) bluetoothd[5559]: Not enough free handles to register service bluetoothd[5559]: Not enough free handles to register service bluetoothd[5559]: Sap driver initialization failed. bluetoothd[5559]: sap-server: Operation not permitted (1)
如果dbus服務沒有啟動,bluetoothd啟動會失敗報錯
root@airfly:/# bluetoothd -n bluetoothd[18793]: Bluetooth daemon 5.38 D-Bus setup failed: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory bluetoothd[18793]: Unable to get on D-Bus
bluetoothd啟動需要加載一些配置文件在/etc/bluetooth下面。
root@airfly:/# ll /etc/bluetooth/*.conf -rw-r--r-- 1 root root 97 Jun 11 2020 /etc/bluetooth/hcidump.conf -rw-r--r-- 1 root root 397 Jun 11 2020 /etc/bluetooth/input.conf -rw-r--r-- 1 root root 3872 Jun 11 2020 /etc/bluetooth/main.conf -rw-r--r-- 1 root root 120 Jun 11 2020 /etc/bluetooth/network.conf -rw-r--r-- 1 root root 258 Jun 11 2020 /etc/bluetooth/proximity.conf
其中main.conf里面有幾個關鍵配置,藍牙名稱,支持的藍牙協議類型,掃描發現及匹配的超時設置等。
[General] # Default adaper name # Defaults to 'BlueZ X.YZ' Name = AIRFLY_H3 # Default device class. Only the major and minor device class bits are # considered. Defaults to '0x000000'. Class = 0x000428 # How long to stay in discoverable mode before going back to non-discoverable # The value is in seconds. Default is 180, i.e. 3 minutes. # 0 = disable timer, i.e. stay discoverable forever DiscoverableTimeout = 0 # How long to stay in pairable mode before going back to non-discoverable # The value is in seconds. Default is 0. # 0 = disable timer, i.e. stay pairable forever PairableTimeout = 0 # Automatic connection for bonded devices driven by platform/user events. # If a platform plugin uses this mechanism, automatic connections will be # enabled during the interval defined below. Initially, this feature # intends to be used to establish connections to ATT channels. Default is 60. #AutoConnectTimeout = 60
8、啟動blue-alsa daemo
建立一個audio sink支持藍牙“”媒體音頻“協議。
root@airfly:/# bluealsa -p a2dp-sink & root@airfly:/# bluetoothd[4788]: Endpoint registered: sender=:1.1 path=/A2DP/SBC/Sink/1
9、使能掃描可發現
root@airfly:/# hciconfig hci0 piscan root@airfly:/# hciconfig hci0: Type: BR/EDR Bus: UART BD Address: 48:98:CA:AD:3C:AB ACL MTU: 1021:8 SCO MTU: 255:12 UP RUNNING PSCAN ISCAN RX bytes:2635 acl:0 sco:0 events:81 errors:0 TX bytes:2773 acl:0 sco:0 commands:82 errors:0
hciconfig的功能還是很強大,具體使用命令查看--help幫助。
root@airfly:/# hciconfig --help hciconfig - HCI device configuration utility Usage: hciconfig hciconfig [-a] hciX [command ...] Commands: up Open and initialize HCI device down Close HCI device reset Reset HCI device rstat Reset statistic counters auth Enable Authentication noauth Disable Authentication encrypt Enable Encryption noencrypt Disable Encryption piscan Enable Page and Inquiry scan noscan Disable scan iscan Enable Inquiry scan pscan Enable Page scan ptype [type] Get/Set default packet type lm [mode] Get/Set default link mode lp [policy] Get/Set default link policy name [name] Get/Set local name class [class] Get/Set class of device voice [voice] Get/Set voice setting iac [iac] Get/Set inquiry access code inqtpl [level] Get/Set inquiry transmit power level inqmode [mode] Get/Set inquiry mode inqdata [data] Get/Set inquiry data inqtype [type] Get/Set inquiry scan type inqparms [win:int] Get/Set inquiry scan window and interval pageparms [win:int] Get/Set page scan window and interval pageto [to] Get/Set page timeout afhmode [mode] Get/Set AFH mode sspmode [mode] Get/Set Simple Pairing Mode aclmtu <mtu:pkt> Set ACL MTU and number of packets scomtu <mtu:pkt> Set SCO MTU and number of packets delkey <bdaddr> Delete link key from the device oobdata Get local OOB data commands Display supported commands features Display device features version Display version information revision Display revision information block <bdaddr> Add a device to the blacklist unblock <bdaddr> Remove a device from the blacklist lerandaddr <bdaddr> Set LE Random Address leadv [type] Enable LE advertising 0 - Connectable undirected advertising (default) 3 - Non connectable undirected advertising noleadv Disable LE advertising lestates Display the supported LE states
至此,藍牙服務已經建立,如果一切正常,用手機藍牙可以掃描匹配了。
10、連接播放音頻
當有設備連接播放音頻的時候,可以用bluealsa-aplay 播放接收到的媒體音頻(通話音頻是另外的協議)。
root@airfly:/# bluetoothd[4788]: Endpoint registered: sender=:1.1 path=/A2DP/SBC/Sink/2 bluetoothd[4788]: /org/bluez/hci0/dev_54_92_09_F7_CE_92/fd0: fd(17) ready bluetoothd[4788]: Can't open input device: No such file or directory (2) bluetoothd[4788]: AVRCP: failed to init uinput for 54:92:09:F7:CE:92 root@airfly:/# bluealsa-aplay 54:92:09:F7:CE:92 &
另外================
還有一個好用的藍牙調試工具
bluetoothctl
和網絡服務類似,網絡服務的服務端是wpa_supplicant,對應的有一個客戶端wpa_clit,可以用來手動調試,連接網絡等。
同樣藍牙服務的服務端是bluetood ,對應的也有一個藍牙界的瑞士軍刀bluetoothcl客戶端,通過命令來調試。
啟動bluetootctl,會自動連接到bluetoothd,進入命令界面自動顯示當前的Controller信息,
包括地址,名稱(main.conf配置的Name字段)
root@airfly:/# bluetoothctl [NEW] Controller 48:98:CA:AD:3C:AB AIRFLY_H3 [default] [bluetooth]#
輸入show命令可以查看到更信息的信息
[bluetooth]# show Controller 48:98:CA:AD:3C:AB Name: AIRFLY_H3 Alias: AIRFLY_H3 Class: 0x040428 Powered: yes Discoverable: yes Pairable: yes UUID: Audio Sink (0000110b-0000-1000-8000-00805f9b34fb) UUID: A/V Remote Control (0000110e-0000-1000-8000-00805f9b34fb) UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb) UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb) Modalias: usb:v1D6Bp0246d0526 Discovering: no [bluetooth]#
這里可以看到當前Controller的詳細信息
Name:名稱 main.conf配置
Alias:別名 可以通過hciconfig hci0 name alias_name設置
Class:支持的藍牙服務類型,注意這里顯示的是0x040428和main.conf配置的0x000428不一致了,是因為我們啟動了
bluealsa -p a2dp-sink
支持了
UUID: Audio Sink (0000110b-0000-1000-8000-00805f9b34fb)
服務 。
Discoverable:是否可以被掃描發現,如果打開了就是yes 如果沒打開就是no
Pairable: 是否接受匹配 yes /no
更多命令支持查看help
[bluetooth]# help Available commands: list List available controllers show [ctrl] Controller information select <ctrl> Select default controller devices List available devices paired-devices List paired devices power <on/off> Set controller power pairable <on/off> Set controller pairable mode discoverable <on/off> Set controller discoverable mode agent <on/off/capability> Enable/disable agent with given capability default-agent Set agent as the default one set-scan-filter-uuids [uuid1 uuid2 ...] Set scan filter uuids set-scan-filter-rssi [rssi] Set scan filter rssi, and clears pathloss set-scan-filter-pathloss [pathloss] Set scan filter pathloss, and clears rssi set-scan-filter-transport [transport] Set scan filter transport set-scan-filter-clear Clears discovery filter. scan <on/off> Scan for devices info [dev] Device information pair [dev] Pair with device trust [dev] Trust device untrust [dev] Untrust device block [dev] Block device unblock [dev] Unblock device remove <dev> Remove device connect <dev> Connect device disconnect [dev] Disconnect device list-attributes [dev] List attributes select-attribute <attribute> Select attribute attribute-info [attribute] Select attribute read Read attribute value write <data=[xx xx ...]> Write attribute value notify <on/off> Notify attribute value register-profile <UUID ...> Register profile to connect unregister-profile Unregister profile version Display version quit Quit program
我們可以進行打開關閉掃描發現,掃描藍牙設備,匹配藍牙設備,連接藍牙設備,移除藍牙設備等操作。
scan on scan off pair 54:92:09:F7:CE:92 connect 54:92:09:F7:CE:92 disconnect 54:92:09:F7:CE:92 remove 54:92:09:F7:CE:92
===================以下是踩坑爬坑過程=============================
1、bluetoothd啟動后,無法發現藍牙設備,設置了discoverable on也無效。
2、使用scan pair connect可以掃描匹配連其他藍牙設備,並且可以播放音頻。
3、已經連接且保持了第一個設備后,Controller可以被其他設備掃描到,可以匹配、連接、播放音樂、斷開連接等操作。
4、如果第一個連接的設備斷開了,后面連接的所有設備自動被斷開,Controller又變得掃描不可見,無法被連接,也無法連接別人,需要重啟機器才可以。
就這個問題倒騰了一個禮拜,內核驅動換了一遍,bluetoothd倒騰了一遍,最后更換了rtl8821cs的固件才突然好了。
rtl8821cs_fw
rtl8821cs_congig
殺千刀的模塊固件有問題
========================================================