16.Linux蓝牙从硬件驱动到应用

一、原理图

以RK3399上AP6356S为例

在这里插入图片描述

与蓝牙相关的引脚有

BT_REG_ON:			 蓝牙上下电引脚
BT_PCM_***:			 蓝牙音频数据传输相关线路
UART_***:			 蓝牙串口相关引脚

二、蓝牙的DTS配置

1.串口UART0

从原理图中可以看出串口一共四根线,UART0_RTS、UART0_CTS、UART0_TXD、UART0_RXD

在设备树里pinctl(uart0_xfer)包括UART0_TXD、UART0_RXD

pinctl(uart0_cts)包括UART0_CTS、pinctl(uart0_rts)包括UART0_RTS

	uart0: serial@ff180000 {
		compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
		reg = <0x0 0xff180000 0x0 0x100>;
		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
		clock-names = "baudclk", "apb_pclk";
		interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0>;
		reg-shift = <2>;
		reg-io-width = <4>;
		pinctrl-names = "default";
		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
		status = "disabled";
	};
	
	//这里修改了uart0的默认pinctl去掉了RTS的控制,是为了去蓝牙节点wireless-bluetooth里设置
&uart0 {
	pinctrl-names = "default";
	pinctrl-0 = <&uart0_xfer &uart0_cts>;
	status = "okay";
};

uart0 {
			uart0_xfer: uart0-xfer {
				rockchip,pins =
					<2 16 RK_FUNC_1 &pcfg_pull_up>,
					<2 17 RK_FUNC_1 &pcfg_pull_none>;
			};

			uart0_cts: uart0-cts {
				rockchip,pins =
					<2 18 RK_FUNC_1 &pcfg_pull_none>;
			};

			uart0_rts: uart0-rts {
				rockchip,pins =
					<2 19 RK_FUNC_1 &pcfg_pull_none>;
			};
		};
2.wireless-bluetooth节点
wireless-bluetooth {
		compatible = "bluetooth-platdata";
		clocks = <&rk808 1>;
		clock-names = "ext_clock";
		//wifi-bt-power-toggle;
		
		//uart0的rts引脚
		uart_rts_gpios = <&gpio2 19 GPIO_ACTIVE_LOW>; /* GPIO2_C3 */
		
		
		pinctrl-names = "default", "rts_gpio";
		pinctrl-0 = <&uart0_rts>;
		pinctrl-1 = <&uart0_gpios>;
		
		//BT,reset_gpio 即BT_REG_ON_H
		BT,reset_gpio    = <&gpio0 9 GPIO_ACTIVE_HIGH>; /* GPIO0_B1 */
		BT,wake_gpio     = <&gpio2 26 GPIO_ACTIVE_HIGH>; /* GPIO2_D2 */
		BT,wake_host_irq = <&gpio0 4 GPIO_ACTIVE_HIGH>; /* GPIO0_A4 */
		status = "okay";
	};
	
pinctl{	
	...
	wireless-bluetooth {
		uart0_gpios: uart0-gpios {
			rockchip,pins =
				<2 19 RK_FUNC_GPIO &pcfg_pull_none>;
		};
	};
	...
};

uart0的rts引脚

在这里插入图片描述

BT_REG_ON_H引脚

在这里插入图片描述

三、蓝牙内核配置

在这里插入图片描述

其中上图选中的HCI UART driver的内核宏为CONFIG_BT_HCIUART

四、HCI接口

主机(HOST计算机或者MCU)这里是RK3399与控制器(controller实际蓝牙芯片组)这里是ap6356之间的通信遵循主机控制器接口(HCI),如下图所示,HCI定义了如何交换命令,事件,异步和同步数据包。异步数据包(ACL)用于数据传输,而同步数据包(SCO)用于带有耳机和免提配置文件的语音。

在这里插入图片描述

五、蓝牙驱动

驱动的路径为kernel/drivers/bluetooth

# cat Makefile
...
drivers/bluetooth/Makefile:17:obj-$(CONFIG_BT_HCIUART)	+= hci_uart.o
...

同wifi一样蓝牙功能也需要放固件在文件系统中

其中固件的来源为

external/rkwifibt/firmware/broadcom/AP6356/bt$ ls
BCM4356A2.hcd

其在文件系统中的路径是

root@firefly:/system/etc/firmware# ls | grep BCM4356A2.hcd
BCM4356A2.hcd

六、蓝牙设备的上下电控制

RK有专门的机制rfkill来处理蓝牙的开关

#rfkill0是蓝牙的开关节点
root@firefly:/sys/class/rfkill# cat rfkill0/name
bt_default

#默认蓝牙是开着的
root@firefly:/sys/class/rfkill/rfkill0# cat state
1

#echo 0 > state是关掉蓝牙的电源
root@firefly:/sys/class/rfkill/rfkill0# echo 0 > state

hciconfig会看到hci0没有了
root@firefly:/sys/class/rfkill/rfkill0# echo 0 > state
root@firefly:/sys/class/rfkill/rfkill0# hciconfig
root@firefly:/sys/class/rfkill/rfkill0# echo 1 > state
root@firefly:/sys/class/rfkill/rfkill0# hciconfig
hci0:   Type: Primary  Bus: UART
        BD Address: AC:83:F3:9F:92:BF  ACL MTU: 1021:8  SCO MTU: 64:1
        UP RUNNING
        RX bytes:857 acl:0 sco:0 events:61 errors:0
        TX bytes:4992 acl:0 sco:0 commands:61 errors:0

七、用户空间蓝牙协议BlueZ

# sudo apt-get install bluez

安装bluez后,systemd 会加入服务bluetooth,该服务系统会自启守护进程 bluetoothd

# systemctl status bluetooth
● bluetooth.service - Bluetooth service
   Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2025-03-19 09:27:21 UTC; 23min ago
     Docs: man:bluetoothd(8)
 Main PID: 720 (bluetoothd)
   Status: "Running"
    Tasks: 1 (limit: 4597)
   CGroup: /system.slice/bluetooth.service
           └─720 /usr/lib/bluetooth/bluetoothd

八、bluetoothctl调试

bluetoothctl 是安装bluez后自带的蓝牙调试命令行工具,本节的步骤都是在ubuntu base系统下,所以要解决许多桌面系统不用解决的问题

参考传送门:

Archlinux Bluetooth (简体中文)
https://wiki.archlinux.org/title/Bluetooth_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

1.bluetoothctl 查看帮助
# bluetoothctl

[bluetooth]# help
Menu main:
Available commands:
-------------------
advertise                                         Advertise Options Submenu
scan                                              Scan Options Submenu
gatt                                              Generic Attribute Submenu
list                                              List available controllers
show [ctrl]                                       Controller information
select <ctrl>                                     Select default controller
devices                                           List available devices
paired-devices                                    List paired devices
system-alias <name>                               Set controller alias
reset-alias                                       Reset controller alias
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
advertise <on/off/type>                           Enable/disable advertising with given type
set-alias <alias>                                 Set device alias
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
menu <name>                                       Select submenu
version                                           Display version
quit                                              Quit program
exit                                              Quit program
help                                              Display help about this program
2.去除之前配对过的设备
# bluetoothctl   (这是显示本机的蓝牙地址和配对的地址)
[NEW] Controller 30:7B:C9:59:EF:82 norco [default]
[NEW] Device 28:12:93:4B:69:C7 connect

[bluetooth]# remove 28:12:93:4B:69:C7  (去掉之前配对的设备)
[DEL] Device 28:12:93:4B:69:C7 connect
Device has been removed
3.搜索、配对设备
# bluetoothctl 
[NEW] Controller 30:7B:C9:59:EF:82 norco [default]
[NEW] Device 64:A3:69:9B:20:05 64-A3-69-9B-20-05
Agent registered

初始化设置
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# pairable on
Changing pairable on succeeded
[bluetooth]# discoverable on
Changing discoverable on succeeded
[bluetooth]# agent on
Agent is already registered
[bluetooth]# default-agent 
Default agent request successful

搜索
[bluetooth]# scan on
Discovery started
[CHG] Controller 30:7B:C9:59:EF:82 Discovering: yes
[NEW] Device 28:12:93:4B:69:C7 connect
[NEW] Device 76:8B:BB:C9:D7:C6 76-8B-BB-C9-D7-C6
[CHG] Device 28:12:93:4B:69:C7 LegacyPairing: yes
[CHG] Device 28:12:93:4B:69:C7 LegacyPairing: no
[CHG] Controller 30:7B:C9:59:EF:82 Discoverable: no

配对
[bluetooth]# pair 28:12:93:4B:69:C7
Attempting to pair with 28:12:93:4B:69:C7
[CHG] Device 28:12:93:4B:69:C7 Connected: yes
Request confirmation
[agent] Confirm passkey 547286 (yes/no): yes
[CHG] Device 28:12:93:4B:69:C7 Modalias: bluetooth:v09C6p107Ed1436
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000046a-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001105-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000110a-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001112-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001115-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001116-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000112f-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001132-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000fe35-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 11c8b310-80e4-4276-afc0-f81590b2177f
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 8ce255c0-200a-11e0-ac64-0800200c9a66
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 9664aa26-d76c-43ad-9775-d310f253a408
[CHG] Device 28:12:93:4B:69:C7 ServicesResolved: yes
[CHG] Device 28:12:93:4B:69:C7 Paired: yes
Pairing successful

信任设备
[bluetooth]# trust 28:12:93:4B:69:C7
[CHG] Device 28:12:93:4B:69:C7 Trusted: yes
Changing 28:12:93:4B:69:C7 trust succeeded
4.解决连接不上的问题

参考传送门:

Ubuntu20.04使用摸索(二)——蓝牙耳机连接
https://blog.csdn.net/weixin_48120620/article/details/126229978

树莓派4b板载蓝牙连接其他蓝牙设备时出错的解决方法
https://blog.csdn.net/ZeroSwift/article/details/115151743

连接报错
[bluetooth]# connect 28:12:93:4B:69:C7
Attempting to connect to 28:12:93:4B:69:C7
Failed to connect: org.bluez.Error.Failed
[bluetooth]# quit
Agent unregistered
[DEL] Controller 30:7B:C9:59:EF:82 norco [default]


systemd查看日志
root@norco:/home/norco/bluetooth# systemctl status bluetooth
● bluetooth.service - Bluetooth service
   Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset
   Active: active (running) since Mon 2022-11-07 09:23:45 CST; 40min ago
     Docs: man:bluetoothd(8)
 Main PID: 310 (bluetoothd)
   Status: "Running"
   CGroup: /system.slice/bluetooth.service
           └─310 /usr/lib/bluetooth/bluetoothd

Nov 07 09:23:45 norco systemd[1]: Starting Bluetooth service...
Nov 07 09:23:45 norco bluetoothd[310]: Bluetooth daemon 5.48
Nov 07 09:23:45 norco systemd[1]: Started Bluetooth service.
Nov 07 09:23:45 norco bluetoothd[310]: Starting SDP server
Nov 07 09:23:45 norco bluetoothd[310]: kernel lacks bnep-protocol support
Nov 07 09:23:45 norco bluetoothd[310]: System does not support network plugin
Nov 07 09:23:45 norco bluetoothd[310]: Bluetooth management interface 1.10 initi
Nov 07 10:04:13 norco bluetoothd[310]: a2dp-source profile connect failed for 28

解决办法:

# pulseaudio -k
# pulseaudio --start
# sleep 4
# pulseaudio --start
# sleep 2
# pactl load-module module-bluetooth-discover

上面运行了两遍pulseaudio --start,是为了在脚本中运行的需要

正常运行的日志

root@norco:/home/norco/bluetooth# pulseaudio -k
E: [pulseaudio] main.c: Failed to kill daemon: No such process
root@norco:/home/norco/bluetooth# pulseaudio --start
W: [pulseaudio] main.c: This program is not intended to be run as root (unless --system is s.
root@norco:/home/norco/bluetooth# pactl load-module module-bluetooth-discover
22
5.连接
# bluetoothctl 
[NEW] Controller 30:7B:C9:59:EF:82 norco [default]
[NEW] Device 28:12:93:4B:69:C7 connect
Agent registered
[bluetooth]# connect 28:12:93:4B:69:C7
Attempting to connect to 28:12:93:4B:69:C7
[CHG] Device 28:12:93:4B:69:C7 Connected: yes
Connection successful
[CHG] Device 28:12:93:4B:69:C7 ServicesResolved: yes
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000046a-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001105-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001108-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000110a-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001112-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001115-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001116-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000111f-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000112f-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001132-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 0000fe35-0000-1000-8000-00805f9b34fb
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 11c8b310-80e4-4276-afc0-f81590b2177f
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 8ce255c0-200a-11e0-ac64-0800200c9a66
[CHG] Device 28:12:93:4B:69:C7 UUIDs: 9664aa26-d76c-43ad-9775-d310f253a408
5.文件传输

a.obexd运行

蓝牙文件传输需要obexd守护进程,该应用由apt-get install bluez-obexd 安装

该进程不会由systemd开机自启,使用下面的命令来手动启动

/usr/lib/bluetooth/obexd -a -n -r /home/norco/bluetooth/file &

解决手动启动的报错问题

报错信息如下:

# obexd[2787]: OBEX daemon 5.48
Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
obexd[2787]: manager_init failed

[1]+  Exit 1                  /usr/lib/bluetooth/obexd -a -n -r /home/norco/bluetooth/file

参考传送门:

解决Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
https://blog.csdn.net/vah101/article/details/107448240

# apt-get install dbus-x11 dbus -y
# eval `dbus-launch --sh-syntax`

b.接收文件

# /usr/lib/bluetooth/obexd -a -n -r /home/norco/b
[1] 3694
root@norco:/home/norco/bluetooth# obexd[3694]: OBEX daemon 5.48

root@norco:/home/norco/bluetooth# obexd[3694]: CONNECT(0x0), (null)(0xffffffff)
obexd[3694]: CONNECT(0x0), (null)(0x0)
obexd[3694]: PUT(0x2), (null)(0xffffffff)
obexd[3694]: PUT(0x2), CONTINUE(0x10)
obexd[3694]: DISCONNECT(0x1), (null)(0xffffffff)
obexd[3694]: DISCONNECT(0x1), SUCCESS(0x20)
obexd[3694]: disconnected: Transport got disconnected

c.发送文件

参考传送门:

Ubuntu 蓝牙 Bluetooth 命令行连接发送文件完整流程
https://my.oschina.net/u/1445895/blog/5551890

如果没有安装 bluez-tools 则需要安装

# sudo apt install bluez-tools

使用 bt-obex 发送文件:

# bt-obex -p [remote_mac] [file]
譬如:
# bt-obex -p F0:6B:CA:A2:C4:69 ~/xxx.pdf

接受完成

# bt-obex -p 28:12:93:4B:69:C7  ./bluetooth.sh               
[Transfer#bluetooth.sh] Waiting...
[Transfer#bluetooth.sh] Completed

(bt-obex:4004): GLib-CRITICAL **: 11:01:47.432: g_variant_unref: assertion 'value->ref_countd
5.客户使用视角

应该按照以下顺序执行命令:

a.执行初始化脚本

# bluetooth.sh init
脚本内容如下:
# cat bluetooth.sh 
#!/bin/bash  
  
function usage() 
{
        echo "Usage:"
        echo "bluetooth.sh init      to init bluetooth"
        echo "bluetooth.sh           to show Usage"

}


function init() 
{

        if `ps -aux | grep obexd | grep -qiE  bluetooth`;then
        echo "already inited,you may run the command killall obexd,then reinit"
        else
                pulseaudio -k
                pulseaudio --start
                sleep 4
                pulseaudio --start
                sleep 2
                pactl load-module module-bluetooth-discover

                eval `dbus-launch --sh-syntax`
                /usr/lib/bluetooth/obexd -a -n -r /home/norco/bluetooth/file &
        fi
}

if [ x$1 == xinit ];then
        init
else 
        usage
fi

b.设置、搜索、配对蓝牙

# bluetoothctl

设置蓝牙
[bluetooth]# power on
[bluetooth]# pairable on
[bluetooth]# discoverable on
[bluetooth]# agent on
[bluetooth]# default-agent 

搜索
[bluetooth]# scan on

配对
[bluetooth]# pair 28:12:93:4B:69:C7

退出
[bluetooth]# exit

在这里插入图片描述

c.信任连接设备

设置蓝牙
[bluetooth]# power on

信任设备
[bluetooth]# trust 28:12:93:4B:69:C7

连接
[bluetooth]# connect 28:12:93:4B:69:C7

想重新配对的话,要去掉之前配对的设备
[bluetooth]# remove 28:12:93:4B:69:C7  

退出
[bluetooth]# exit

在这里插入图片描述

d.发送接收文件

在发送文件前应运行以下命令 
# eval `dbus-launch --sh-syntax`

发送文件按照以下命令格式
# bt-obex -p [remote_mac] [file]
# bt-obex -p 28:12:93:4B:69:C7 ./bluetooth.sh

发送和自动接受的效果图,自动接受的文件路径为/home/norco/bluetooth/file

在这里插入图片描述

九、桌面系统蓝牙调试

# sudo apt-get install bluez blueman bluez-obexd

界面调出blueman的步骤

在这里插入图片描述

***ps:***blueman不需要连接就能传输文件,遇到过一个错误,传输空linux文件失败的情况

十、蓝牙串口的使用

涉及到的概念比较多,单拎一篇出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值