宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

蓝牙基本概念

Piconet

在蓝牙设备没有跟其他蓝牙设备连线的时候,它自己属于一个piconet。当有连线后,piconet里有两种角色:master 和 slave。发起连线的一方是master,被连接的一方是slave。slave会以master的时钟为参照,以625us为时间单位,与master进行数据收发。每一个piconet里,一个master最多有7个slave。

蓝牙协议框架梳理-编程部落

PHY Mode

LE:LE采用频分多址(FDMA)和时分多址(TDMA),在FDMA中使用了40个(40)物理信道,相隔2 MHz。37,38,39用作主要广播,而另外37个通道用作数据渠道或者次要广播通道。

Basic Rate: 最基本的一种模式,采用GFSK,传输速率是 1Mb/s。

蓝牙协议框架梳理-编程部落

Enhanced Data rate: 增强模式,传输速率是 2Mb/s (π/4-DQPSK)或 3Mb/s(8DPSK),这种模式有两种编码。

BT clock

Clock是蓝牙通信最最基础的一个概念,clock定义了通信的时空范围,定义了这个Piconet时空的坐标系,只有在同一个坐标系里,网络内的各个角色才能相互了解对方的时间线,才知道什么时候发包,什么时候收包。BT clock是个28bit的计数器,每tick一次是312.5us,所以总共有 (2^28 -1)个tick,算一下大约是(2^28-1)*312.5us/10^6/3600 = 23.3个小时后clock会翻转。

针对Clock有几个重要概念:

CLK0, 312.5us,是一个tickCLK1, 625us, 是一个slotCLK2, 1.25ms, 是一个frame(做一次TX 和 RX)CLK12, 1.28s.Clock的精确度要求为 +/-250ppm 和 +/-20ppm

蓝牙tx,rx会按时隙为节拍通信,数据以625us一个时隙作为最小单元,有些数据包会超过一个时隙,最多可持续5个时隙。

蓝牙协议框架梳理-编程部落

对于一个连接中的两个设备中,对于主设备,slave_offset应为零,因为CLK与其自身的本地时钟CLKN相同。每个从机应在其CLKN上添加一个适当的slave_offset,以使CLK对应于主机的CLKN,使得主从时钟保持同步尽管设备中的所有CLKN均以相同的标称速率运行,但相互漂移会导致CLK不准确。因此,必须定期更新从机中的偏移,以使CLK大约等于主机的CLKN

蓝牙协议框架梳理-编程部落

Physical Channel(信道)

Spec总共有定义如下5种channel

Basic piconet physical channel

Adapted piconet physical channel

Page scan physical channel

Inquiry scan physical channel

Synchronization scan physical channel

以Basic piconet physical channel为例,在建立连线后,Slave会以Mater的clock为准。Master和Slave以一个slot为单位进行Tx和Rx,Master在clock为偶数时发包,Slave在clock为偶数时收包,如下图所示

蓝牙协议框架梳理-编程部落

蓝牙核心框架

核心架构

蓝牙协议框架梳理-编程部落

蓝牙核心框架信息量非常大,把蓝牙的构架和数据传输方向描述的非常清楚,绿色框图部分是Radio, 蓝牙射频,基带和链路管理放在该部分完成,红色部分称为Host端,俗称蓝牙协议。

Radio分为经典蓝牙,低功耗蓝牙和AMP。我们主要看LE Controller,顺带提一下BR/EDR。

Controller和Host直接的数据传输有几种方式:C/E,SCO,ACL,ISO。

• Synchronous Connection-Oriented (SCO) logical transport

• Extended Synchronous Connection-Oriented (eSCO) logical transport

• Asynchronous Connection-Oriented (ACL) logical transport

• Active Slave Broadcast (ASB) logical transport

• Connectionless Slave Broadcast (CSB) logical transport.

简单来说,C/E是HOST和Controller通信方式,Command用于下发指令,Event是Host用于接收controller上报指令,SCO和eSCO是经典蓝牙下用于音频传输,ACL为异步数据传输(没有严格同步时间要求的数据传输方式),ISO是蓝牙5.2的最新规范的大数据传输通道,分为基于连接的数据流传输和基于广播的数据流传输。上图中灰色的箭头表示控制指令的传输路径,黑体箭头表示数据流向。

Synchronous Connection Oriented (SCO)

Circuit switched typically used for voice

Symmetric, synchronous service

Slot reservation at fixed intervals

Point-to-point

Asynchronous Connectionless Link (ACL)

Packet switched

Symmetric or asymmetric, asynchronous servicePolling mechanism between master and slave(s)

Point-to-point and point-to-multipoint

以设置LE设备广播为例,LE 设备上电后,host发送reset command重启蓝牙设备,发送广播参数command,配置广播内容,使能广播command,完成蓝牙设备的广播设置command。

(```)
########################################################
## Legacy Adv Command
########################################################
#reset
Send_HCI_Reset
Wait_HCI_Command_Complete_Reset_Event 5000, any, HCI_Reset, 0x00

# set Adv parameter
Send_HCI_LE_Set_Advertising_Parameters 800, 800, 0x00, 0x00, 0x00, "01:02:03:04:05:06", "0x07", "0x00"
Wait_HCI_Command_Complete_LE_Set_Advertising_Parameters_Event 5000, any, HCI_LE_Set_Advertising_Parameters,

# set Adv data Payload
Send_HCI_LE_Set_Advertising_Data 0x10, "00:01:02:03:04:05:06:07:08:09:0A:0B:0C:0D:0E:0F"
Wait_HCI_Command_Complete_LE_Set_Advertising_Data_Event 5000, any, HCI_LE_Set_Advertising_Data,

# set Scan rsp data Payload
Send_HCI_LE_Set_Scan_Response_Data 0x10, "00:01:02:03:04:05:06:07:08:09:0A:0B:0C:0D:0E:0F"
Wait_HCI_Command_Complete_LE_Set_Scan_Response_Data_Event 5000, any, HCI_LE_Set_Scan_Response_Data,

# enable adv
Send_HCI_LE_Set_Advertise_Enable 0x01
Wait_HCI_Command_Complete_LE_Set_Advertise_Enable_Event 5000, any, HCI_LE_Set_Advertise_Enable,
(```)

蓝牙Host和controller层通过HCI Command/Event交互数据,在早期的BR/EDR蓝牙中,controller和host会分开两颗芯片,在蓝牙4.x以后,芯片原厂已经把两颗芯片集成到一颗soc中,hci层只有在蓝牙测试时候会单独用到,工程中,往往已经看不到hci层(已经打包在lib里),这一章有了一个层级间数据传输的感性认识,下面了解蓝牙协议的全貌。

蓝牙协议架构

蓝牙协议框架梳理-编程部落

从OSI(Open System Interconnection)模型的角度看,蓝牙是一个比较简单的协议,它仅仅提供了物理层(Physical Layer)和数据链路层(Data Link Layer )两个OSI层次,细化可分为如图所示的物理层(Physical Layer)、逻辑层(Logical Layer)、L2CAP Layer。

物理层,负责提供数据传输的物理通道(通常称为信道)。通常情况下,一个通信系统中存在几种不同类型的信道,如控制信道、数据信道、语音信道等等。

逻辑层,在物理层的基础上,提供两个或多个设备之间、和物理无关的逻辑传输通道(也称作逻辑链路)。

L2CAP层,L2CAP是逻辑链路控制和适配协议(Logical Link Control and Adaptation Protocol)的缩写,负责管理逻辑层提供的逻辑链路。基于该协议,不同Application可共享同一个逻辑链路。类似TCP/IP中端口(port)的概念。

在l2cap之上还可以有profile层,理解蓝牙协议的profile,基于L2CAP提供的channel,实现各种各样的应用功能。Profile是蓝牙协议的特有概念,为了实现不同平台下的不同设备的互联互通,蓝牙协议不止规定了核心规范(称作Bluetooth core),也为各种不同的应用场景,定义了各种Application规范。

数据和指令的传输通过C/E,SCO,ACL,ISO几个通道穿梭在不同层协议,既保证了蓝牙协议层级间的独立,又完成了蓝牙数据的交互。

蓝牙层级间的数据交互

蓝牙协议框架梳理-编程部落

蓝牙协议层级间的指令数据传输需要靠通道相互连接,操作系统消息传递机制以及callback函承担了实现层级间的数据通信和交互的桥梁。

我们以TI CC2541(真的很老了)的软件架构来讲述数据传输方式,工程内有多个线程同时工作:LL,HAL,HCI,L2CAP,GAP,SM,GATT,GAPROLE,GAPBondMgr,GATTServApp,SimpleBLEPeripheral。线程之间采用send/callback方式交互数据。

(```)
void osalInitTasks( void )
{
 uint8 taskID = 0;

 tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
 osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));

 /* LL Task */
 LL_Init( taskID++ );

 /* Hal Task */
 Hal_Init( taskID++ );

 /* HCI Task */
 HCI_Init( taskID++ );

#if defined ( OSAL_CBTIMER_NUM_TASKS )
 /* Callback Timer Tasks */
 osal_CbTimerInit( taskID );
 taskID += OSAL_CBTIMER_NUM_TASKS;
#endif

 /* L2CAP Task */
 L2CAP_Init( taskID++ );

 /* GAP Task */
 GAP_Init( taskID++ );

 /* SM Task */
 SM_Init( taskID++ );

 /* GATT Task */
 GATT_Init( taskID++ );

 /* Profiles */
 GAPRole_Init( taskID++ );
 GAPBondMgr_Init( taskID++ );

 GATTServApp_Init( taskID++ );

 /* Application */
 SimpleBLEPeripheral_Init( taskID );
}
(```)

 蓝牙协议框架梳理-编程部落

HOST端层级之间数据交互通道

蓝牙协议框架梳理-编程部落

HCI下层和controller的部分逻辑和上层host一样,只是在hci层做了一层数据传输的task,HCI_task作为host和controller的衔接,进行发送,解析指令,传输数据。

HCI command packet format:  cmd

Packet Type + Command opcode + lengh + command payload

| 1 octet   |   2   |   1  |   n   |

HCI data packet format:  eco acl

Packet Type +   Conn Handle  + lengh +  data payload

| 1 octet    |    2     |   2    |    n    |

总结

弄清楚了基本概念,弄清楚了框架和数据流向和软件实施方法,就基本对蓝牙协议有了一个宏观认识,对于理解软件代码有一定帮助。

转载微信公众号:无线技术联盟