Tech 蓝牙驱动分析及Bluez使用流程分析
Guide
Revision History
Date Issue Description Author
<01/11/2010> <0.5> First draft  Wylhistory
目录
1.ABSTRACT (4)
2.INTRODUCTION (4)
3.蓝牙驱动介绍 (4)
3.1串口驱动介绍 (5)
3.2初始化 (5)
3.2.1模块上电 (5)
3.2.2PSKEY的设置 (6)
3.3H CIATTACH的工作原理 (7)
3.3.1Hci_uar和bcsp层的加入 (9)
3.3.2hci层的加入 (10)
3.3.3hci_attach的内核处理 (11)
4.数据在驱动的传递流程 (13)
4.1U ART层的数据接收 (13)
4.2H CI_UART的数据接收 (14)
4.3B CSP层的处理 (15)
4.4H CI层及以上的处理 (15)
4.5数据流程的总结 (17)
5.扫描过程的分析 (18)
5.1用户使用例子 (18)
5.2用HCITOOL扫描时的逻辑 (18)
5.2.1上层逻辑 (18)
5.2.2内核层逻辑 (19)
5.3通过DBUS触发的逻辑 (21)
5.3.1上层逻辑之adapter dbus方法的建立 (21)
5.3.2上层扫描方法的调用 (22)
5.3.3Dbus触发的扫描对应于内核层的处理 (25)
5.3.4上层的扫描数据收集 (26)
5.3.5Hci_send_frame的讨论 (28)
6.A2DP的使用过程 (28)
6.1如何使用 (28)
6.2服务的激活 (29)
6.3设备的创建 (30)
6.3.1 (33)
6.3.2 (33)
6.3.3 (33)
6.3.4 (33)
6.4设备的连接 (33)
©Tech, 2010-1-11 Page 2 of 46
6.4.1L2cap的连接 (34)
6.4.2AVDTP_DISCOVER的发送逻辑 (35)
6.4.3AVDTP_GET_CAPABILITIES命令的发送 (36)
6.4.4AVDTP_SET_CONFIGURATION的逻辑 (37)
6.4.5AVDTP_OPEN函数逻辑 (38)
6.4.6AVDTP_START的逻辑 (40)
7.HANDSFREE的使用过程 (42)
7.1使用流程 (42)
7.2H EADSET的连接 (42)
7.3S CO的打开 (45)
7.4数据的流动 (46)
8.总结 (46)
9.未讨论 (46)
©Tech, 2010-1-11 Page 3 of 46
1. Abstract
介绍一下bluez的驱动架构以及上层的使用流程.
2. Introduction
主要分成几个部分:
Bluez驱动整体框架,
数据在驱动的传递流程,
A2dp的上层逻辑,
headset
Handsfree的上层逻辑
主要软硬件配置如下:
内核:2.6.21
硬件:pxa310
蓝牙芯片:CSR BC4
BlueZ:3.22
3. 蓝牙驱动介绍
从整体上来说,我们的蓝牙是一个模块,它需要和CPU通讯以交换信息,所以它需要一个接口,在我们的平台上它用的UART口,当然还有USB接口的,我没做过,所以不讨论;另外一方面蓝牙还要和modem 这边传递数据,比如传递语音,这也要一个接口才行,因为我们的蓝牙芯片只提供了PCM接口,所以或者是modem的输出就是数字接口,或者就需要把modem输出的数字接口经过一定的转化,比如引入一个中间的codec把模拟接口转化成数字接口,再接到我们的蓝牙芯片,我们的板子就是后一种实现方案;而蓝牙驱动要做哪些事呢?在我刚接手的时候,也是一头雾水,蓝牙驱动这说法,太抽象了,因为我们用的是蓝牙模块,并非是独立的芯片,它所该有的功能都有了;从协议层的角度来说radio层,BB层,LC,LM层,HCI层都不需要我们去管,都应该是已经被实现在蓝牙模块里面了,需要我们
关注的本质就是cpu和蓝牙模块之间的接口,以及在这个接口上传递的数据格式,也就是说数据包的格式,数据包的处理,而后者在linux 驱动层里面是已经有完整实现的,只需要在配置的时候选上:
HCI UART driver
BCSP protocol support
就可以了,不过有时候模块供应商会做一些修改,也可以用他们已经修改过的代码;
对于前者,也就是接口的问题,对我来说本质上就是串口的驱动,这个显然linux的代码里面早就已经实现了的,也不需要我去操心,看看下面这个图就明白了:
©Tech, 2010-1-11 Page 4 of 46
©Tech, 2010-1-11 Page 5 of 46
上面写明了internal ROM,也即是说是蓝牙模块内部的事情了,那我也就不管了;
经过这一番分析之后,剩下的事情就是初始化蓝牙模块了,那肯定少不了的上电,然后是模块重启,还缺点什么呢?
蓝牙驱动和别的驱动一样,也要设一些寄存器,差别在于,它的寄存器被称为PSKEY ,也就是说有一步是PSKEY 设置,这步是通过bccmd 来完成的;
好像完了,但是还差一步,这步估计不好想到,仔细想想,假设现在蓝牙模块以及就绪了,数据从蓝牙模块通过串口传递到了主板,但是这些数据是如何传递到蓝牙的协议层的呢?有点奇怪啊?这步是通过hciattach 来完成的;
总结一下,蓝牙驱动的三个步骤:
1, 串口驱动必须要先就绪,这是cpu 和蓝牙模块之间的桥梁,没有这步,后面的都无法进行,包括
PSKEY 的设置,数据的传递都是通过串口的,所以这步是根本;
2, 初始化,包括模块上电,PSKEY 的设置;
3, 通过hciattach 建立串口和蓝牙协议层之间的数据连接通道;
下面分别介绍!
3.1 串口驱动介绍
串口驱动本身很复杂,请参阅附录里面的文档“串口驱动分析”,这里可以简单介绍一下:
从上到下就是:
TTY 层
Uart 层
Uart 对应的Port 层
对蓝牙来说,数据先从串口驱动上来通过ldisc 进入到蓝牙的hci_uart 层,然后交给更上面的协议层了; 这个过程后面会详细介绍;
3.2 初始化
3.2.1 模块上电
在我们的平台上是通过一个GPIO 来控制的,在函数lin2008_poweron_wifibt_board 里面会进