蓝牙协议栈架构梳理

2020-06-30  本文已影响0人  靖哥哥编程

目录

芯片架构方案

协议栈框架分析

数据传输过程

协议栈各层详解

L2CAP层详解

SMP层详解

ATT层详解

GATT层详解



架构1:host+controller双芯片标准架构

蓝牙双芯片架构.jpg

架构2:单芯片整体方案

host和controller之间直接通过API来交互。像Nordic的蓝牙协议栈Softdevice

单芯片方案.jpg

架构3:自定义双芯片架构

它需要一颗功能非常强大的MCU来做主应用,而蓝牙SoC只是整个系统的一部分,这种情况下,大部分蓝牙协议栈功能或者整个蓝牙协议栈功能都是跑在蓝牙SoC中

自定义双芯片架构.jpg
链接:https://blog.csdn.net/iini01/article/details/79943908


协议栈框架分析

在深入BLE协议栈各个组成部分之前,我们先看一下BLE协议栈整体架构

BLE协议栈架构.jpg

如何通过无线发送一个数据包

假设有设备A和设备B,设备A要把自己目前的电量状态83%(十六进制表示为0x53)发给设备B,该怎么做呢?作为一个开发者,他希望越简单越好,对他而言,他希望调用一个简单的API就能完成这件事,比如send(0x53),实际上我们的BLE协议栈就是这样设计的,开发者只需调用send(0x53)就可以把数据发送出去了,其余的事情BLE协议栈帮你搞定。很多人会想,BLE协议栈是不是直接在物理层就把0x53发出去,就如下图所示:

图五

这种方式初看起来挺美的,但由于很多细节没有考虑到,实际是不可行的。首先,它没有考虑用哪一个射频信道来进行传输,在不更改API的情况下,我们只能对协议栈进行分层,为此引入LL层,开发者还是调用send(0x53),send(0x53)再调用send_LL(0x53,2402M)(注:2402M为信道频率)。这里还有一个问题,设备B怎么知道这个数据包是发给自己的还是其他人的,为此BLE引入access address****概念,用来指明接收者身份,其中,0x8E89BED6这个access address比较特殊,它表示要发给周边所有设备,即广播。如果你要一对一的进行通信(BLE协议将其称为连接),即设备A的数据包只能设备B接收,同样设备B的数据包只能设备A接收,那么就必须生成一个独特的随机access address以标识设备A和设备B两者之间的连接。

广播方式

我们先来看一下简单的广播情况,这种情况下,我们把设备A叫advertiser(广播者),设备B叫scanner或者observer(扫描者)。广播状态下设备A的LL层API将变成send_LL(0x53,2402M, 0x8E89BED6)。由于设备B可以同时接收到很多设备的广播,因此数据包还必须包含设备A的device address(0xE1022AAB753B)以确认该广播包来自设备A,为此send_LL参数需要变成(0x53,2402M, 0x8E89BED6, 0xE1022AAB753B)。LL层还要检查数据的完整性,即数据在传输过程中有没有发生窜改,为此引入CRC24对数据包进行检验 (假设为0xB2C78E) 。同时为了调制解调电路工作更高效,每一个数据包的最前面会加上1个字节的preamble(前导帧),preamble一般为0x55或者0xAA。这样,整个空中包就变成(注:空中包用小端模式表示!):

广播数据包发送

上面这个数据包还有如下问题:

  1. 没有对数据包进行分类组织,设备B无法找到自己想要的数据0x53。为此我们需要在access address之后加入两个字段:LL header和长度字节。LL header用来表示数据包的LL类型,长度字节用来指明payload的长度
  2. 设备B什么时候开启射频窗口以接收空中数据包?如上图case1所示,当设备A的数据包在空中传输的时候,设备B把接收窗口关闭,此时通信将失败;同样对case2来说,当设备A没有在空中发送数据包时,设备B把接收窗口打开,此时通信也将失败。只有case3的情况,通信才能成功,即设备A的数据包在空中传输时,设备B正好打开射频接收窗口,此时通信才能成功,换句话说,LL****层还必须定义通信时序
  3. 当设备B拿到数据0x53后,该如何解析这个数据呢?它到底表示湿度还是电量,还是别的意思?这个就是GAP层要做的工作,GAP层引入了LTV(Length-Type-Value)结构来定义数据,比如020105,02-长度,01-类型(强制字段,表示广播flag,广播包必须包含该字段),05-值。由于广播包最大只能为31个字节,它能定义的数据类型极其有限,像这里说的电量,GAP就没有定义,因此要通过广播方式把电量数据发出去,只能使用供应商自定义数据类型0xFF,即04FF590053,其中04表示长度,FF表示数据类型(自定义数据),0x0059是供应商ID(自定义数据中的强制字段),0x53就是我们的数据(设备双方约定0x53就是表示电量,而不是其他意思)。

最终空中传输的数据包将变成:

image

有了PHY,LL和GAP,就可以发送广播包了,但广播包携带的信息极其有限,而且还有如下几大限制:

  1. 无法进行一对一双向通信 (广播是一对多通信,而且是单方向的通信)
  2. 由于不支持组包和拆包,因此无法传输大数据
  3. 通信不可靠及效率低下。广播信道不能太多,否则将导致扫描端效率低下。为此,BLE只使用37(2402MHz) /38(2426MHz) /39(2480MHz)三个信道进行广播和扫描,因此广播不支持跳频。由于广播是一对多的,所以广播也无法支持ACK。这些都使广播通信变得不可靠。
  4. 扫描端功耗高。由于扫描端不知道设备端何时广播,也不知道设备端选用哪个频道进行广播,扫描端只能拉长扫描窗口时间,并同时对37/38/39三个通道进行扫描,这样功耗就会比较高。

而连接则可以很好解决上述问题,下面我们就来看看连接是如何将0x53发送出去的。

连接方式

到底什么叫连接(connection)?像有线UART,很容易理解,就是用线(Rx和Tx等)把设备A和设备B相连,即为连接。用“线”把两个设备相连,实际是让2个设备有共同的通信媒介,并让两者时钟同步起来。蓝牙连接有何尝不是这个道理,所谓设备****A****和设备B****建立蓝牙连接,就是指设备A****和设备B****两者一对一“同步”成功,其具体包含以下几方面:

image

如上图所示,一旦设备A和设备B连接成功(此种情况下,我们把设备A称为Master或者Central,把设备B称为Slave或者Peripheral),设备A将周期性以CI(connection interval)为间隔向设备B发送数据包,而设备B也周期性地以CI为间隔打开射频接收窗口以接收设备A的数据包。同时按照蓝牙spec要求,设备B收到设备A数据包150us****后,设备B切换到发送状态,把自己的数据发给设备A;设备A则切换到接收状态,接收设备B发过来的数据。由此可见,连接状态下,设备A和设备B的射频发送和接收窗口都是周期性地有计划地开和关,而且开的时间非常短,从而大大降低系统功耗并大大提高系统效率。

现在我们看看连接状态下是如何把数据0x53发送出去的,从中大家可以体会到蓝牙协议栈分层的妙处。

广播数据

上面只是对BLE协议栈实现原理做了一个简单概述,即便如此,由于都是关于BLE协议栈底层的东西,很多开发者还是会觉得比较枯燥和晦涩,而且对很多开发者来说,他们也不关心BLE协议栈是如何实现的,他们更关心的是BLE协议栈的使用,即怎么开发一个BLE应用。BLE应用是实打实的东西,不能像上面讲述协议栈一样泛泛而谈,必须结合具体的蓝牙芯片和蓝牙协议栈来讲解,为此后面将以Nordic芯片及协议栈作为范例,来具体讲解如何开发BLE应用,以及如何通过代码去理解BLE协议中定义的一些概念和术语。

链接:https://www.cnblogs.com/iini/p/8969828.html


L2CAP层详解

L2CAP层即逻辑链路控制与适配层


L2CAP架构图

其主要功能是
L2CAP主要功能:
1.协议信道复用(protocol/channel multiplexing)
2.分段与重组(segmentation and reassembly SAR)
3.每个信道流控(per-channel flow control)
4.差错控制(error control)

链接:https://blog.csdn.net/ylangeia/article/details/87188031?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase


SMP(secure manager protocol)层详解

链接:https://blog.csdn.net/cai472861/article/details/105406242


ATT层详解

ATT层:
1.定义了属性实体的概念,包括UUID、句柄和属性值等;
2.也规定了属性的读、写、通知等操作方法和细节,这些与属性操作相关的内容称为属性协议。
3.ATT层规定了ATT_MTU值,如果属性值很长,超过了ATT_MTU限制,将使用特殊的读写方法进行操作。

链接:https://www.cnblogs.com/yongdaimi/p/11983220.html
https://www.cnblogs.com/hzl6255/p/4141505.html


GATT层详解

GATT(Generic Attribute Profile),描述了一种使用ATT的服务框架
该框架定义了服务(Server)和服务属性(characteristic)的过程(Procedure)及格式
Procedure定义了characteristic的发现、读、写、通知(Notifing)、指示(Indicating)及配置characteristic的广播
GATT中主要的11项特征:

  1. Server Configuration
  2. Primary Service Discovery
  3. Relationship Discovery
  4. Characteristic Discovery
  5. Characteristic Descriptor Discovery
  6. Reading a Characteristic Value
  7. Writing a Characteristic Value
  8. Notification of a Characteristic Value
  9. Indication of a Characteristic Value
  10. Reading a Characteristic Descriptor
  11. Writing a Characteristic Descriptor
链接:https://www.cnblogs.com/hzl6255/p/4158363.html


项目中开发包括配对绑定,BLE地址分析相关的博客文档

https://blog.csdn.net/UFOfuck/article/details/102708853
http://www.wowotech.net/bluetooth/ble_address_type.html

上一篇 下一篇

猜你喜欢

热点阅读