蓝牙基础知识

蓝牙4.0:

       包含经典蓝牙和ble

ble单模:

        ble

ble双模:

        经典蓝牙和ble

ble协议栈:

 

控制器层,host层,app

 

 

控制器

 

HCI

HCI层为接口层,向上为主机提供软件应用程序接口(API),对外为外部硬件控制接口,可以通过串口、SPI、USB来实现设备控制

 

 

Link Layer

L层为RF控制器,控制设备处于准备(standby)、广播、监听/扫描(scan)、初始化、连接,这五种状态中一种。五种状态切换描述为:未连接时,设备广播信息,另外一个设备一直监听或按需扫描,两个设备连接初始化,设备连接上了。发起聊天的设备为主设备,接受聊天的设备为从设备,同一次聊天只能有一个意见领袖,即主设备和从设备不能切换。

 

 

PHY

物理层: RF规格

2.4G ISM band

GFSK调制

40个频道,2M频间隔

3个广播37,38,39),37数据通道

 

由于BLE属于无线通信,则其通信介质是一定频率范围下的频带资源(Frequency Band);BLE的市场定位是个体和民用,因此使用免费的ISM频段(频率范围是2.400-2.4835 GHz);为了同时支持多个设备,将整个频带分为40份,每份的带宽为2MHz,称作RF Channel 。

 

 

 

主设备管理多个连接从设备,从设备只能连接一个主设备

 

 

做为一个BLE设备,有六种可能的状态:
– 待机状态Standby):设备没有传输和发送数据,并
且没有连接到任何设备
– 广播状态Advertiser):周期性广播状态
– 扫描状态Scanner):主动地寻找正在广播的设备
– 发起连接状态Initiator):主动向某个设备发起连接
– 主设备Master):作为主设备连接到其他设备
– 从设备Slave):作为从设备连接到其主设备

 

 

host层

 

GAP:

 

连接参数设置,设备命令设置,安全模式设置

 

角色:广播者,观察者,主设备,从设备

 

 

 

BLE:广播事件
广播包的发送是单向的,不需要任何连接。
设备发送广播包进入广播状态
– 广播包可以包含特定的数据定义,最大31个字节
– 广播包可以直接指向某个特定的设备,也可以不指定
– 广播中可以声明是可被连接的设备,或者是不可连接的设备
在一个广播事件中,广播包会分别在三个广播通道中被发送一次 37, 38, 39)

 

 

 

BLE广播间隔

广播间隔,是两次广播事件之间的最小时间间隔,一般取值范围在 20ms~10.24s 之间。链路层会在每次广播时间期间产生一个随机广播延时时间(0ms~10ms),这个延时被加在广播时间中,这样来避免多设备之间的数据碰撞。

 

单位时间是0.625ms

 

 

 

 

 

广播

 

低功耗蓝牙设备通过广播信道发现其他设备,一个设备进行广播,而另一个设备进行扫描。

广播相关的参数大致有以下几种:

 

1.Advertising interval

2.Advertising_Type

3.Own_Address_Type

4.Direct_Address_Type

5.Direct_Address

6.Advertising_Channel_Map

7.Advertising_Filter_Policy

8.Advertising Data

9.ScanReponse Data

 

 

 

 

Advertising interval  (广播间隔)

 

设备每次广播时,会在3个广播信道上发送相同的报文。这些报文被称为一个广播事件。除了定向报文以外,其他广播事件均可以选择“20ms ~ 10.28s”不等的间隔。通常,一个广播中的设备会每一秒广播一次。两个相邻广播事件之间的时间称为广播间隔。

 

但是,设备周期性的发送广播会有一个问题:由于设备间的时钟会不同程度的漂移,两个设备可能在很长一段时间同时广播而造成干扰。为防止这一情况的发生,除定向广播之外的其他广播类型,发送时间均会被扰动。实现该扰动的方式为,在上一次广播事件后加入“0 ~ 10ms”的随机延时。这意味着,即使两个设备广播间隔相同,并在相同信道及时间点上发送造成了冲突,但它们发送下一个广播事件时也会有很大可能不再冲突。

所以,两个相邻的广播事件的之间的时间间隔(T_advEvent)为:

 

T_AdvEvent = advInterval + advDelay

 

其中,advInterval 必须是“0.625ms”的整数倍,范围是“20ms ~ 10.24s”之间。对于可扫描非定向广播和不可连接非定向广播这两种广播类型,该值最好不小于100ms,即(160个0.625ms)。advDelay是Link Layer(链接层)分配的一个伪随机数,它的范围为“0 ~ 10ms”。

广播包的截图如下:

 

当然,实际设置过程中没有广播间隔参数,而是设置Advertising_Interval_Min(最小广播间隔)和Advertising_Interval_Max(最大广播间隔)这两个参数来调整广播间隔,它们都是以“0.625ms”为单位,如果要固定广播间隔为某一个值,只需要将这两个参数设置为同一个有效数值即可。

设置广播间隔的方法如下:

 

[cpp] view plain copy print?

  1. //普通可发现模式下修改广播间隔的方法  

  2. GAP_SetParamValueTGAP_GEN_DISC_ADV_INT_MIN, advInt );//单位是0.625ms  

  3. GAP_SetParamValueTGAP_GEN_DISC_ADV_INT_MAX, advInt );//单位是0.625ms  

  4. //有限可发现模式下修改广播间隔的方法  

  5. GAP_SetParamValue TGAP_LIM_DISC_ADV_INT_MIN, advInt );//单位是0.625ms  

  6. GAP_SetParamValue TGAP_LIM_DISC_ADV_INT_MAX, advInt );//单位是0.625ms  

下一篇博文会重点介绍广播发现模式的有关内容。

 

 

 

Advertising_Type  (广播类型)

 

广播的类型一般分为四种,分别是:

 

 

1.可连接的非定向广播(Connectable Undirected Event Type)。这是一种用途最广的广播类型,包括广播数据和扫描响应数据,它表示当前设备可以接受其他任何设备的连接请求。

 

鉴于此种广播类型用的最多,下面我们来讨论一下此类型下广播事件中广播包的发送情况,另外要注意在一个广播事件中,前一个“ADV_IND PDUs”的开始到相邻的下一个“ADV_IND PDUs”的开始处的时间要小于等于 10ms :

第一种情况:仅仅有广播 PDUs 。截图显示如下:

 

第二种情况:在广播事件的中间有“SCAN_REQ”和“SCAN_RSP PDUs”。截图显示如下:

 

第三种情况:在广播事件的结尾有“SCAN_REQ”和“SCAN_RSP PDUs”。截图显示如下:

 

第四种情况:在广播事件的中间接收到“CONNECT_REQ PDU”的情况。截图显示如下:

此情况下,广播事件会关闭,不会继续在下一个信道上广播。

 

2.可连接的定向广播(Connectable Directed Event Type)。定向广播类型是为了尽可能快的建立连接。这种报文包含两个地址:广播者的地址和发起者的地址。发起者收到发给自己的定向广播报文之后,可以立即发送连接请求作为回应。

 

定向广播类型有特殊的时序要求。完整的广播事件必须每3.75ms重复一次。这一要求使得扫描设备只需扫描3.75ms便可以收到定向广播设备的消息。

 

当然,如此快的发送会让报文充斥着广播信道,进而导致该区域内的其他设备无法进行广播。因此,定向广播不可以持续1.28s以上的时间。如果主机没有主动要求停止,或者连接没有建立,控制器都会自动停止广播。一旦到了1.28s,主机便只能使用间隔长得多的可连接非定向广播让其他设备来连接。

 

当使用定向广播时,设备不能被主动扫描。此外,定向广播报文的净荷中也不能带有其他附加数据。该净荷只能包含两个必须的地址。

 

3.不可连接的非定向广播(Non-connectable Undirected Event Type)。仅仅发送广播数据。

 

4.可扫描的非定向广播(Scannable Undirected Event Type)。这种广播不能用于发起连接,但允许其他设备扫描该广播设备。这意味着该设备可以被发现,既可以发送广播数据,也可以响应扫描发送扫描回应数据,但不能建立连接。这是一种适用于广播数据的广播形式,动态数据可以包含于广播数据之中,而静态数据可以包含于扫描响应数据之中。

 

注意:所谓的定向和非定向针对的是广播的对象,如果是针对特定的对象进行广播(在广播包PDU中会包含目标对象的MAC)就是定向广播,反之就是非定向。可连接和不可连接是指是否接受连接请求,如果是不可连接的广播类型,它将不回应连接请求。可扫描广播类型是指回应扫描请求。

 

不同的广播类型对扫描请求和连接请求的不同结果如下图:

 

TI的CC2540和CC2541中广播类型的具体定义在“components/ble/include”目录下的“Gap.h”文件中,如下:

 

[cpp] view plain copy print?

  1. /** @defgroup GAP_ADVERTISEMENT_TYPE_DEFINES GAP Advertising Event Types 

  2.  * for eventType field in gapAdvertisingParams_t 

  3.  * @{ 

  4.  */  

  5. #define GAP_ADTYPE_ADV_IND                0x00  //!< Connectable undirected advertisement  

  6. #define GAP_ADTYPE_ADV_HDC_DIRECT_IND     0x01  //!< Connectable high duty cycle directed advertisement  

  7. #define GAP_ADTYPE_ADV_SCAN_IND           0x02  //!< Scannable undirected advertisement  

  8. #define GAP_ADTYPE_ADV_NONCONN_IND        0x03  //!< Non-Connectable undirected advertisement  

  9. #define GAP_ADTYPE_ADV_LDC_DIRECT_IND     0x04  //!< Connectable low duty cycle directed advertisement  

  10. /** @} End GAP_ADVERTISEMENT_TYPE_DEFINES */  

 

其中“GAP_ADTYPE_ADV_HDC_DIRECT_IND”和“GAP_ADTYPE_ADV_LDC_DIRECT_IND”属于定向可连接广播类型的两种形式。

设置广播类型的方法:

 

[cpp] view plain copy print?

  1. GAPRole_SetParameterGAPROLE_ADV_EVENT_TYPE, sizeof uint8 ), &advType );  

 

 

 

 

 

 

Own_Address_Type  (自身地址类型)

 

 

Public Device Addrss:公有设备地址是设备所特有的并且是不可改变的。类似网络设备的MAC地址,它的长度为48位。由两部分组成:

 

 

Ramdom Device Address:随机设备地址(私有设备地址),它也是48位。组成如下所示:

 

 

 

Direct_Address_Type  (定向地址类型)

 

地址类型同Own_Address_Type,具体内容如上。

 

 

 

 

Direct_Address  (定向地址)

 

定向设备地址如下所示:

 

 

 

Advertising_Channel_Map  (广播信道)

 

广播信道如下所示:

 

 

在一个广播事件中,一个广播包会在每个信道上进行传输。显示如下:

 

 

 

Advertising_Filter_Policy  (广播过滤策略)

 

广播过滤策略,对发来请求包的设备采用的过滤策略。如下所示:

 

 

 

对应上图的内容解释如下:

1.接受任何设备的扫描请求或连接请求。(Value:0x00)

2.仅仅接受白名单中的特定设备的扫描请求,但是接受任何设备的连接请求。(Value:0x01)

3.接受任何设备的扫描请求,但仅仅接受白名单中的特定设备的连接请求。(Value:0x02)

4.仅仅接受白名单中的特定设备的扫描请求和连接请求。(Value:0x03)

5.保留

 

 

 

 

 

Advertising And ScanReponse Data  (广播和扫描回应数据)

 

广播数据和扫描回应数据,它们的长度都不能超过31个字节(0 ~ 31),数据的格式必须满足下图的要求,可以包含多个AD数据段,但是每个AD数据段必须由“Length:Data”组成,其中Length占用1个octet,Data部分占用Length个字节,所以一个AD段的长度为:Length+1。格式图如下所示:

 

设置广播数据和扫描回应数据的方法如下:

 

[cpp] view plain copy print?

  1. GAPRole_SetParameter GAPROLE_ADVERT_DATA,sizeof advertData ), advertData );  

  2. GAPRole_SetParameter GAPROLE_SCAN_RSP_DATA,sizeof  scanRspData ), scanRspData );  

 

广播使能—-打开的方法:

[cpp] view plain copy print?

  1. uint8 adv_enable = TRUE;  

  2. GAPRole_SetParameter GAPROLE_ADVERT_ENABLED, sizeof uint8 ), &adv_enable );  

 

广播使能—-关闭的方法:

 

 

[cpp] view plain copy print?

  1. uint8 adv_enable = FALSE;  

  2. GAPRole_SetParameter GAPROLE_ADVERT_ENABLED, sizeof uint8 ), &adv_enable );  

 

 

 

 

附加知识点:Octet

 

在传统的二进制概念中,1 byte(字节)= 8 bit(位)。大多数因特网标准使用八位组(octet)这个术语而不是使用字节来表示8位的量。该术语起源于“TCP/IP”发展的时期,当时许多早期的工作是在诸如“DEC-10”这样的系统上进行的,然而这些系统的结构采用的字节(byte)长度不是8位(bit),因此出现了octet的单位,即准确定义了

 

 

 

 

 

 

 

 

BLE:扫描事件
每次扫描设备打开Radio接收器去监听广播设备,称为一个扫描事件
扫描事件交替发生在三个特定的广播通道中: 37, 38, 39
扫描频宽比 Duty-Cycle),关于扫描的两个
时间参数:
–扫描间隔:即扫描设备的扫描频度
–扫描窗口:每次扫描事件持续的时间

 

 

 

 

BLE发起连接

除了扫描,设备也可以主动发起连接,发起状态的设备和扫描状态的设备区别在于:当它监听到一个可连接的广播,发起设备就会发送一个连接请求,而扫描设备会发送一个扫描请求。

连接请求包括一套为从设备准备的连接参数,安排连接期间发生的通道和时间。如果广播设备接收了连接,两个设备会进入连接状态,发起方会称为 Master(主机) ,而广播方会称为 Slave(从机)。

 

 

 

 

BLE连接参数

 

  • 通道映射,指示连接使用的频道。

  • 调频增量,一个5~16 之间的随机,参与通道选择的算法。

  • 连接间隔,1.25ms的倍数,在7.5ms~4s之间。

  • 监督超时,10ms 的倍数,100ms~32s 之间, 必须大于 (1+slaveLatency)*ConnInterval

  • 从机潜伏,0~499之间,不能超过(SupervisionTimeout/connInterval)-1

 

 

 

BLE连接事件

所有的通信都发生在两个设备的连接事件期间,连接事件周期的发生,按照连接参数

指定的间隔联系,每个事件发生在某个数据通道(0~36),调频增量参数决定了下次连接时间发生的通道,在每个连接时间期间,Master 先发送,Slave会在 150us之后做出回应,即使一个连接事件发生(或两者),双方都没有数据发送(例外情况是从设备潜伏使能),这允许两个设备都承认对方仍然存在并保持活跃的连接。

 

 

        Slave的潜伏

Slave如果没有数据发送,允许跳过连接时间。连接参数中的 Slave 的潜伏值,是允许设备跳过的最大连接次数,在连接事件中,如果 slave 没有对master 的包做出回应,master将会在后来的连接时间中重复发送,直到 slave 回应。两个有效的连接事件之间的最大时间跨度(假设 slave 跳过了最大数目的连接时间)称为“有效连接间隔”,从设备的潜伏范围是 0~499,但是有效的连接间隔必须小于 32s。

 

 

 

连接参数的设定

短间隔的连接事件:

-两设备都会以高能耗运行

-高数据吞吐量

– 发送等待时间短

长间隔的连接事件:

– 两设备都会以低能耗运行

– 低数据吞吐量

– 发送等待时间长

低或者 0潜伏值:

– 从设备以高能耗运行

– 从设备可以快速的收到来自中心设备的数据

高潜伏值:

– 外围设备在没有数据发送的情况下可以低能耗运行

– 外围设备无法及时收到来自中心设备的数据

– 中心设备能及时收到来自外围设备的数据

 

 

 

1.安卓设备作主设备时,连接参数满足的要求见本篇博文第二节“连接参数介绍”中提到的内容。另外实际开发过程中发现安卓设备作主设备时存在一个问题,就是部分安卓设备连接BLE设备之后,只能进行一次连接参数的修改。

 

2. 苹果系统设备作主设备时,连接参数更新的要求比较苛刻,如下:

 

Interval Max * Slave Latency + 1) ≤ 2 seconds

Interval Min ≥ 20 ms

Interval Min + 20 ms ≤ Interval Max

Slave Latency ≤ 4

connSupervisionTimeout ≤ 6 seconds

Interval Max * Slave Latency + 1) * 3 < connSupervisionTimeout

 

即:

最大连接间隔时间 *(从机延迟 + 1) ≤ 2s

最小连接间隔时间 ≥ 20 ms

最小连接间隔时间 + 20 ms ≤ 最大连接间隔时间

从机延迟 ≤ 4

超时时间 ≤ 6s

最大连接间隔时间 *(从机延迟 + 1)* 3  < 超时时间

 

 

这样算

ios最小20ms

最大400ms

从机延迟  4

超时时间6s

 

 

所以如果你的BLE从设备需要被IOS主设备连接,那你的BLE从设备的默认申请的连接参数一定要满足上述要求,并且连接过程中修改连接参数的时候也要满足上述要求。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注