Texas Instruments CC2540/41
Bluetooth® Low Energy
Software Developer’s Guide
v1.3.2
Document Number:SWRU271F
《低功耗蓝牙开发权威指南》
Robin Heydon著,陈灿峰、刘嘉 译
机械工业出版社
2014.6
标签: 读书笔记 BLE
链路层定义了两个设备如何利用无线电传输信息。它包含了报文、广播、数据通道的详细定义,也规定了发现其他设备的流程、广播的数据、连接的建立、连接的管理以及连接中的数据传输。ISM频段的干扰、噪声、深度衰落等无线传输系统的挑战加剧了链路层的复杂度。
就绪态
广播态
扫描态:主动扫描,被动扫描
发起态
连接态:主,从
上电后,链路层进入并保持就绪态,直到接到主机命令。
就绪态是链路层状态机的中心状态,尽管是非活动状态,但是最为重要。
处于广播态的链路层可以发送广播报文,也可以发送扫描响应,用以回应主动扫描的设备。
可被发现或可被连接的设备需要处于广播态。想向一定区域内其他设备广播数据的设备也要处于广播态。
为了成为广播者,必须要有发射机。
广播态的设备停止广播后可进入就绪态。在收到发起者的连接请求后,广播态的设备进入连接态。
处于扫描态的设备能够接收广播信道的报文。扫描态可以简单的侦听哪些设备正在广播。扫描态有两个子状态:被动扫描和主动扫描。
扫描态的设备只能进入就绪态,转换的条件是停止扫描。
被动扫描
设备只能被动的扫描,不能发送任何报文。被动扫描可以在只有接收机的设备中实现。
主动扫描
LL一旦发现了新的广播态设备,都会发送扫描请求,并等待该请求的响应。扫描请求和响应报文都在广播信道中传输。为了使主动扫描更为有效,扫描响应应尽量为静态数据。
为了发起连接,处于发起态的发起者,其接收机用于侦听自己试图连接的设备。如果收到了来自该设备的广播报文,LL会向其发送连接请求并进入连接态,并假设广播者也进入连接态。
如果发起者不再试图,也可以进入就绪态。
从发起态或广播态均可进入连接态。两种情况均源于发起者向广播者发送连接请求报文。
连接态中,两个设备相互传送数据信道报文,这也是唯一一个用到数据信道的状态,其他各个状态均使用广播信道。
连接态的设备只能通过断开链接转换为就绪态,而不能进入其他状态。
主连接态
主连接态只能从发起态进入。
为了成为主设备,必须向对端设备发起连接。
主设备必须定期向从设备发送报文,从设备只有回复这些报文才能发送自己的数据。
从连接态
从连接态只能从广播态进入。
为了成为从设备,必须向对端设备进行广播。
从设备只有在正确接收主设备的报文之后才能发送。收到主设备的一个报文后,从设备可以发送一个自己的报文。如果从设备想要发送更多的数据,则必须等待主设备发送另外的报文再回复。从设备也可以随时忽略主设备以达到节能的目的。这样一来,从设备可以通过“休眠”节省大量的能量。
一个链路层的具体实现可以拥有多个独立的状态机。例如一个设备可以同时成为从设备、广播者和主动扫描者。其中的限制:
不能同时成为主从设备。
如果成为了主设备,便不能同时成为从设备。反之亦然。这意味着主设备不能发送可用于连接的广播报文(否则就可能变成从设备)。不过主设备还是可以发送不可连接的广播报文或是可发现的广播报文。同理,从设备也不能发起连接。通过这个限制,设备在任何时间点上应该做什么具有确定性。
一个设备也不可以同时成为两个主设备的从设备
从设备不能广播可连接的广播报文(如果和设备A连接的从设备B又广播了产生连接,那么这个从设备B又会变成另一个设备的从设备,违背了不能同时成为两个主设备的从设备这一原则)。事实上,同时作为两个主设备的从设备,在经典蓝牙中称为分散式网络(scatternet),是允许的。但在BLE中不支持。
一个不太恰当的类比:主设备就像是封建社会里的丈夫,从设备就像是封建社会里的妻子。一个人不可能同时既是丈夫也是妻子,一个人不可能同时兼具男女两种身份(这里暂时不考虑双性恋人群)。因此一个设备不可能同时成为主从设备。同理,一个妻子不可能拥有多个丈夫,就像一个设备不可以同时成为多个主设备的从设备。但一个主设备可以有多个从设备,类比旧社会的一夫多妻制。
报文是带有标签的数据,由一个设备发送,另一个设备接收。标签指明了数据由谁发送,由谁接收。
报文的基本结构如下:
报文的开始是一小段训练序列,称为前导。之后是接入地址,接收机用它将报文和背景噪声区分开。之后是报头和长度字节。再之后是报文的净荷,以及用于确保净荷正确性的循环冗余校验码。
BLE中,有两类报文:广播报文和数据报文。设备利用广播报文发现、连接其他设备。一旦连接建立之后,则开始使用数据报文。数据报文只能被连接中的两个设备(主、从设备)所理解,而广播报文则可以广播给多个侦听设备或者只发送给某个特定设备。
是广播报文还是数据报文由其传输所在的信道决定。BLE规定了3个广播信道和37个数据信道。如果报文在某个广播信道中传输,则为广播报文,反之则为数据报文。
FSK接收连续相同比特的能力很差。当发送一串如“000000000000”的比特序列,接收机会以为发射机的中心频率向左偏移,进而导致频率失锁,之后的比特“1”会被错过,报文接收失败。为了避免这种情况,BLE使用了“白化器”来随机化发送的数据。
白化器是一个很短的输出“0”、“1”序列的随机数发生器。接收机可以使用相同的随机数发生器来恢复原始的比特。为了在输出序列中保留原始信息,需要对原始数据和白化序列逐位异或。
当数据的各个字节传输时,总是从最低位开始。因此如果发送0x010203会按照3、0、2、0、1、0的字节顺序发送,对应的比特顺序为:
1100 0000 0100 0000 1000 0000
报文最开始的8bits前导是01010101或者10101010序列。接收机用它来了解输入信号的强度范围,从而配置自动增益控制,使得信号刚好处于接收机能够轻松工作的范围之中。同时,接收机还利用前导来确定信号的频率。
接入地址的第一个bit如果是0,则前导使用的是01010101序列;如果接入地址的第一个bit是1,则前导使用的是10101010序列。这保证了任意报文的前9个比特都是交替的。
接入地址有两种类型:广播接入地址、数据接入地址。
广播接入地址在广播数据,或是广播、扫描、发起连接时使用。数据接入地址在连接建立之后的两个设备间使用。
前导序列只有8bits,背景噪声也可能产生类似前导序列的比特流,因此需要检查前导和接入地址,来减少收到伪报文。这个过程称为与接入地址求相关。
对于广播信道,接入地址是固定值:0x8E89BED6,发送顺序为6,D,E,B,9,8,E,8,对应的发送比特流为0110 1011 0111 1101 1001 0001 0111 0001。这意味着前导一定是01010101
对于数据信道,接入地址是一个随机值,不同的连接拥有不同的值。这一随机值也要符合一些规定,主要是为了保证接入地址具有足够好的白化特性。
报头的内容取决于报文是广播报文还是数据报文。
对于广播报文:
报头包含了广播报文的类型和一些标记位,标记位指出了报文使用的是公共地址还是随机地址。广播报文类型共有7种,每种类型都具有不同的净荷格式以及行为:
ADV_IND:通用广播指示
ADV_DIRECT_IND:定向连接指示
ADV_NONCONN_IND:不可连接指示
ADV_SCAN_IND:可扫描指示
SCAN_REQ:主动扫描请求
SCAN_RSP:主动扫描响应
CONNECT_REQ:连接请求
对于数据报文:
包含如下标记位:报文可靠传输使能、低功耗管理、净荷路由(发送给控制器或者是主机)。
对于广播报文,长度域包含6个比特,有效值范围6~37。对于数据报文,长度域包含5个比特,有效值范围0~31。长度域指出的字节数指的是报文中数据的长度。
广播报文除了最多31个字节的数据之外,还要包含6个字节的广播设备地址,所以有效值为6~37,需要6个比特位。
如果数据报文被加密,需要包含4个字节的消息完整性检查域,实际的净荷数据将被减少到最多27个字节。为了简化链路层,未加密的报文净荷也不允许超过27个字节。
净荷是所传输的真实有用的数据,可以是关于设备的广播数据,或者发给一定区域内所有设备的服务数据;可以是主动扫描响应的附加数据,如设备名称、实现服务;可以是建立或保持连接所需要的信息;可以是从一个设备到另一个设备的应用层数据。
最后三个字节的CRC负责对报头、长度域和净荷域进行校验计算。
BLE有40个信道,由于调制指数放宽,BLE信道宽度为2MHz,而不是经典蓝牙的1MHz。这些信道本分为两种:广播信道和数据信道,对应着传输广播报文和数据报文。
广播信道频点的选择原则上为了远离Wi-Fi接入点的严重干扰。
广播信道编号37~39,对应频点2402,2426,2480
数据信道编号0~36
跳频算法用于数据连接中,数据信道一共37个,是一个质数,因此跳频算法:
自适应跳频能够将一个已知的坏信道映射到一个已知的好信道。为了实现这一点,连接中的两个设备需要记录好、坏信道的映射关系。主设备至少需要将两个数据信道标记为好信道。
BLE通过广播信道发现其他设备:
一个设备进行广播,另一个设备进行扫描。共有四种不同类型的广播:通用的、定向的、不可连接的以及可发现的。
设备每次广播时,会在3个广播信道上发送相同的报文。这些报文称为一个广播事件。除了定向广播,其他广播事件的事件间隔20ms~10.28s不等。通常一个广播中的设备每一秒广播一次。广播事件之间的时间称为广播间隔。周期性的广播可能会由于设备间的时钟漂移造成冲突。为了防止这种情况,除了定向广播之外的其他广播事件,发送时间均会被扰动,即在上一次广播事件发生后加入一个0~10ms的随机延时。
扫描用于接收广播事件。扫描时间取决于有多少时间用于扫描以及需要多快发现其他设备。
通用广播是用途最广的广播方式,进行通用广播的设备能够被扫描设备扫描到,或者在接收到连接请求时作为从设备进入一个连接。
通用广播可以在没有连接的情况下发出,换而言之,没有主从设备之分。
有时候,设备间需要快速建立连接,如果从设备想这么做,就要进行广播。定向广播事件就是为了尽可能快的建立连接。这种报文包含两个地址:广播者的地址和发起者的地址。发起设备收到发给自己的定向广播报文后,可以立即发送连接请求作为回应。
定向广播事件要求没3.75ms重复一次,但不能持续1.28s以上的时间。一旦超过1.28s,只能改为使用通用广播。
当使用定向广播时,设备不能被主动扫描。此外,定向广播报文的净荷也不能带有其他附加数据。该净荷只能包含两个必须的地址:广播者的地址和发起者的地址,别无其他。
不想被连接的设备使用不可连接广播事件。
典型应用包括设备只想广播数据,而不想被扫描或者连接。这也是唯一可用于只有发射机而没有接收机的广播类型。不可连接广播设备不会进入连接态,因此它只能根据主机的需求在广播态和就绪态之间切换。
可发现广播不能用于发起连接,但允许其他设备扫描该广播设备。这意味着该设备可以被发现,既可以广播数据,又可以响应扫描,但不能建立连接。这是一种适用于广播数据的广播形式,动态数据可以包含于广播数据之中,而静态数据可以包含于扫描响应数据中。可发现广播不会进入连接态,只能在停止后回到就绪态。
设备可以进行广播,但设备必须在广播中包含一些有用的数据。这意味着可以通过4种广播事件中的3种进行广播:通用广播、不可连接广播以及可发现广播。
进行广播时,需要在广播报文中给数据打上标签。通过使用“长度:类型:数据”这样的格式,无法理解特定数据类型的设备可以根据该数据片段的长度跳过该片段,从而不影响对后续数据片段的解析。
广播数据能够被附近的任何被动或主动扫描设备接收到。广播数据的接收无法被确认,广播设备无法知道是否有设备接收到它的数据,或者是否有设备试图侦听它的数据。因此广播是一种不可靠的操作。
应付比广播更为复杂的数据传输,或者要在设备之间实现可靠的数据传输,这些都依赖于连接。连接使用数据信道,采用自适应跳频增强鲁棒性,同时使用了非常低的占空比,尽可能地降低功率消耗。
设备创建连接的过程:
(1)设备首先广播可连接广播事件,其他设备收到之后即可发起连接。在此过程中,广播者发送的事件类型是通用广播事件或者是定向广播事件。
(2)发起者收到正确的广播报文后,将向广播者发送一个连接请求,其中包括了连接开始时需要的所有信息,包括以下各项:
i.连接中使用的接入地址
ii.CRC初始值
iii.发送窗口大小
iv.发送窗口偏移
v.连接间隔
vi.从设备延迟
vii.监控超时
viii.自适应跳频信道图
ix.跳频算法增量
x.休眠时钟精度
(3)一旦收到或发出连接请求报文,设备即建立了连接,数据交换随之开始。
i.接入地址
连接使用的接入地址由主设备来提供。地址通过随机生成,但需要遵循3.3节的规则。如果主设备有多个从设备,它会为每个从设备选择不同的随机接入地址。
ii.CRC初始值
CRC初始值是主设备提供的随机数。
iii.发送窗口大小
iv.发送窗口偏移
当连接请求数据包发送完成之后,存在一个1.25ms的强制时延。紧接着是一个等待时间(发送窗口偏移值,由连接请求中的发送窗口偏移来定义,必须为1.25ms的整数倍(包括0倍))和一个发送侦听时间(发送窗口大小值)。
也就是说,在扫描者发送连接请求后,扫描者变成了主设备。然后等一个1.25ms的强制时延,之后再等发送窗口偏移值(0或者若干个1.25ms),这个时间留给广播者接收连接请求并进入从设备,也让主设备有时间准备要发送的数据报文。从发送窗口开始,从设备打开接收器,等待来自主设备的数据报文。如果直到发送窗口结束都没有收到数据报文,从设备终止侦听,并会在一个连接的间隔后再次尝试。
对于主设备而言,发送了连接请求只是表明连接已经created,并没有established。同理,从设备收到了连接请求,也是只表明连接created,并没有established。只有收到了数据报文,才能证明连接established。
v.连接间隔
vi.从设备延迟
vii.监控超时
在一个连接当中,主设备会在每个连接事件里向从设备发送数据包。一个连接事件是指主设备和从设备之间相互发送数据包的过程。连接事件的进行始终位于一个频率,每个数据包会在上个数据包发完之后等待150us再发送。
连接间隔决定了主设备和从设备的交互间隔,它是指两个连续的连接事件开始处的时间距离,可以是7.5ms~4s内的任意值,但必须为1.25ms的整数倍。
从设备延迟是连接间隔的倍数,代表从设备在必须侦听之前可以忽略掉多少个连接事件。从设备延迟必须短于监控超时时间。
连接事件被一个个连接间隔分开。从主设备发送数据包开始,每个连接事件可以持续进行,直到主设备或从设备停止响应。在连接事件之外,主从设备之间不发送任何数据包。
viii.自适应跳频信道图
ix.跳频算法增量
自适应跳频信道图是数据信道的位掩码,用来标记信道的好坏。由于共有37个数据信道,信道图的长度为37位。如果某一位被设置为1,则表示信道良好,可用于数据通信;如果某一位被设置为0,则表示信道糟糕,不可用于数据通信。
调频算法增量 hop 是一个5~16之间的一个随机数,详情参见4.1。 hop 不能为0,否则频率永远不会改变;也不能为太小的值,因为大多数干扰会持续若干兆带宽,使用非常小的 hop 不能快速的将传输带离干扰源;同理,太大也不可以,取模后频率差距也会过小。
x.休眠时钟精度
定义了时钟能够保证的精度范围。时钟精度可以帮忙从设备消除连接事件的不确定性。
在一个连接里,设备通过在连接事件中发送数据包来相互通信。数据报文和广播报文不同,前者是单独进行的通信,后者是对所有的侦听设备发送广播。广播报文和数据报文之间的最大差别在于报头的格式和净荷的长度。
数据报文的净荷可以为0~31字节长度不等,净荷长度为0的数据包为一个空包,它不含应用程序的数据,但仍然可以在报文的头部包含一些信息。
无论链路层加密与否,传给控制器的未加密数据包最多只能携带27字节的数据。
数据报文的报头包含以下四个字段:
逻辑链路标识符(LLID)
序列号(SN)
下一个预期序列号(NESN)
更多数据(MD)
LLID用来判断数据报文属于下列哪种类型:
链路层控制报文(11)——用来管理连接
高层报文开始(10)——也可用于一个完整报文
高层报文延续(01)
在数据包中,用一个比特来表示序列号;在发送的第一个数据包中将该位设置为0,接下来当设备发送新的数据包时,该值在1和0之间交替。这使得接收装置可以根据序列号判断接收的数据包的性质,如果序列号和之前的一样,则为重传报文,如果序列号和之前的不同,则为新报文。
数据包的确认需要用到另一个比特,即下一个预期序列号(NESN)。NESN的发送方用其通知对方自己期望接收的数据包的序列号。如果设备成功接收序列号为0的报文,在其确认报文中,应将NESN设为1,否则序列号为0的数据包将被重传。
更多数据位用来通知对端设备自己还有其他数据准备发送。如果收到MD=1的数据包,应该在当前连接事件中继续与对端设备通信。这样一来,只要还有数据要发送,连接事件就会自动扩展;一旦不再有数据发送,连接事件会迅速关闭。
SN和NESN总是处于互锁状态,确保了可靠数据送达。
可以通过NESN进行流量控制,设备一旦没有足够的缓冲区空间来处理消息,可以不更新NESN。这将迫使对端设备重新发送当前消息,从而把对缓存的要求从接收设备转移到发送设备。
如果由于一些位的错误导致CRC校验失败,数据包接收出错,这种情况一旦在同一连接事件里发生两次,设备将立刻停止当前事件,并在下次连接事件中重新同步和尝试传输。
连接时,可以对净荷中的数据进行加密,确保数据的机密性。
BLE中的所有加密和认证都基于同一个加密引擎,称为高级加密系统(AES)。
两个设备一旦连接,便可以收发数据和管理连接。连接管理涉及在LLC发送控制消息,包含下列七个LLC控制规程:
更新连接参数
改变自适应跳频信道图
加密链路
重加密链路
交换功能位
交换版本信息
终止链路
第7节中,连接建立时,这设备通过连接请求数据包发送连接参数。当连接活跃了一段时间,连接参数可能不再适用于当前的服务,需要对连接参数进行一下更新。除了断开连接、接着更换参数重新连接之外,还可以在链路中更新参数。连接参数更新过程如下:
主设备向从设备发送连接更新请求,即LL_CONNECTION_UPDATE_REQ,当中携带了新的参数。这些参数没有协商的余地,从设备或选择接收并使用这些参数,或者断开链路。LL_CONNECTION_UPDATE_REQ中包含的参数:
传输窗口大小
传输窗口偏移量
连接间隔
从设备延迟
监控超时
瞬时(instant)
instant决定了连接更新的开始时刻。接收消息后,从设备会记住这个时刻,届时再切换到新的连接参数。只要数据包的重传次数足够,并在instant之前传输成功,连接更新就不会有问题。如果LL_CONNECTION_UPDATE_REQ没有在instant之前完成传输,链路会丢失。
由于BLE没有时钟,instant时刻依赖于计算连接事件的个数。每一个连接事件都会被计数,连接请求之后的位于首个连接窗口里的连接事件记为0,因此,instant实际上是一个连接事件的计数器。为了让从设备收到数据包,主设备必须为其提供足够的机会。无论从设备延迟是多少,都应该至少保证六次数据发送机会。
任何时刻,好信道和差信道的集合都在不断地变化。主设备通过信道图请求报文LL_CHANNEL_MAP_REQ向从设备发送自适应跳频更新信息,其中含有下面两个参数:
新的信道图
瞬时
信道图是一个37位的字段,7.5章节有解释。瞬时含义同10.1。
要重发信道更新请求必须等待instant之后,这限制了信道图的更新频率。
LL规定不允许从设备改变信道图,也不能向主设备告知自身的信道条件。
只有尚未加密的链路才能启动加密。暂时使用不到加密的通信,之后再补充。
重启加密有助于刷新会话密钥。之后再补充。
版本信息仅用于调试目的,设备的链路层能够自动获取,也可以通过主机请求获得该信息。大多数设备会每隔10个或更多次连接请求一次版本信息,这样嗅探器可以获得该信息,并帮助调试连接。
对端设备利用功能信息来判断本端设备到底能做什么。功能信息公开了设备支持的一些可选功能。主设备通过功能请求报文(LL_FEATURE_REQ)询问该信息,这种操作再每个链接里最多只能执行一次。收到主设备的请求,从设备回复功能响应报文(LL_FEATURE_RSP)。要使用可选的功能,不必进一步交换信息,因为报文中的所有功能都必须是支持的功能。同时,对于不支持的可选功能,从设备能够拒绝该请求。
终止连接断开链路并将主从设备从连接态转换为就绪态。任何一方可以基于任何原因在任何时间终止链路。
要终止链路,设备首先发送一个终止指示报文(LL_TERMINATE_IND),等待链路层对该报文进行确认,然后断开连接。如果一个设备发送了终止指示报文,但没有收到确认,发送设备将视为规程超时,仍然会断开连接。超市的时间与监控超时值相同。
设备已接收到终止指示报文立即发送一个空包来响应该报文,随后断开连接。
连接可能由于以下原因终止:
终止指示报文
监控超时
消息完整性校验(MIC)失效
后两个原因不会发送终止指示报文,链路自动断开,双方主机随即得到通知。
为实现鲁棒性,链路层采用了两个强有力的算法:自适应跳频和强CRC校验。
BLE实现低功耗的方法如下:
使用短报文
物理层使用高比特率
提供低开销
优化响应机制
单信道连接事件
亚速率连接事件
使用离线加密
功率指标:峰值功率;每应用比特功率
BLE为了减少频率温度漂移,数据包的长度被设计的足够小,收发数据所导致的热效应因而被降至最低。
在BLE中,允许的最长数据包为376us,此时硅的发热量对于数据传输频率的影响十分有限,不会超出允许的限度。连接中的最大报文长度仅为328us。使用短报文无需校准无线电,降低了峰值功率。此外发送一个很长的数据包必须要有一个150us的空隙,该空隙使得si可以在数据包之间降温。此时最大的数据传输占空比仅为:
给定的数据量,传输速率越快,无线电效率越高。一个简单的、峰值功耗低、数据传输率高的调制方案僵尸最有效的数据发送方式。
BLE的开销是指一切不含应用程序数据的部分,包含前导、接入地址、报头、长度、CRC字段以及可选的MIC值。
对于未加密的数据包,衡量其效率时采用应用程序数据的大小与传送所需数据包的总大小之比,范围从29%~73%。数据包越大,无线传输的开销越小。对于加密的数据包,其效率要比未加密时更低,因为每个包需要额外增加4个字节的MIC。
BLE的LL不要求立即执行数据包的确认,这是和经典蓝牙的一个根本区别。
BLE发送的每一个数据包都能确认上一个数据包,哪怕是一段时间之前传输的数据包。这意味着设备再也不必立即发送应答,相反设备可以选择等待,直到有数据需要发送(或因为超时等其他原因执行传输)。这种确认机制尤其适用于大数据量的传输。
主设备和从设备之间的所有通信都发生在连接事件当中。连接事件包含一个主设备首先发送的数据包,以及随后从设备和主设备交替发送的一系列数据包。
BLE在一个连接事件之内保持一个频率发送数据和确认,然后在下次连接事件到来时切换至另一个频率。在任意时间点上,BLE使用的频率都是完全确定的。
为了解决低功耗与低延时的矛盾,BLE让从设备忽略大部分连接事件。如果有数据需要发送,从设备可以完成同步并进行数据传输,如此产生的数据延迟变成了主从设备之间的连接事件间隔。此外,从设备还能忽略一定数目的连接事件,称为从设备延迟。
BLE将数据加密和验证码的计算放在了后台,一个数据包在发送之前就已经完成了加密,而此时无线电仍然是关闭状态。数据加密不依赖于序号、下一个期望序号或者更多数据位,因此数据加密可以在数据到达链路层之后被发送之前的任何时间进行。此外,数据可以重发任意多次,即使NESN、MD发生了变化,每次重发是加密和认证代码都不会变,这种方法降低了峰值功耗。
接收到数据后,设备实时计算CRC值并判断数据的正确性。加密的数据可以保存在链路层,直到无线电停止活动并且有剩余的电量时才将其解密。实际上,数据包在被传送到主机之前可以随时完成解密。另外对于重传报文,接收时一旦发现了重复的序列号,就不需要对报文重新解密。这种方法降低了峰值功耗。