蓝牙解析(part7):BLE的连接

2023-11-15

转自Wowo大神的http://www.wowotech.net/bluetooth/ble_connection.html


1. 前言

了解蓝牙的人都知道,在经典蓝牙中,保持连接(Connection)是一个相当消耗资源(power和带宽)的过程。特别是当没有数据传输的时候,所消耗的资源完全被浪费了。因而,对很多蓝牙设备来说(特别是功耗敏感的设备),希望在无数可传的时候,能够断开连接。但是,由于跳频(hopping)以及物理通道(Physical Channel)划分的缘故,经典蓝牙连接建立的速度实在难以忍受(要好几秒)。对那些突发的数据传输来说,几秒钟的连接延迟,简直是灾难。

因此,蓝牙SIG制订BLE规范的时候,充分考虑了这方面的需求,极大的简化了连接的建立过程,使连接速度可以达到毫秒级(最快3.75ms就可以搞定)。与此同时,为了节省功耗,也调整了跳频的策略。至此,相比广播通信而言,BLE面向连接的通信,几乎没有额外的代价。

在“蓝牙解析(part5)”中,我们对BLE的广播通信有了比较全面的了解,本文将接着分析和面向连接的通信有关的技术,包括连接的建立和断开、BLE跳频(Hopping)技术、Link Layer的应答、重传、流控、等等。

2. 怎样才算是建立了连接?

开始之前,我们先回答一个问题,对通信的双方而言,怎样才算建立了连接呢?

从字面上理解,建立了连接,就是指:

二者之间,建立了一条专用的通道,它们可以随时随地的通信。

当然,在蓝牙这种资源有限的通信系统中,通道无法独占,退而求其次,分时也Okay。因此,在BLE中建立了连接,是这样定义的:

在约定的时间段内,双方都到一个指定的物理Channel上通信。

其中,“约定好的时间段”,是时分的概念。而“到指定的物理Channel上”,是跳频的概念。后面的分析,将会围绕这两个概念进行。

另外,和“蓝牙解析(part5)”类似,我们也将从Link Layer、HCI、GAP三个层次,分别介绍。

3. Link Layer
3.1 角色的定义

和经典蓝牙一样,协议为处于连接状态的BLE设备,定义了两种Link Layer角色:Master和Slave。Master是连接的发起方(Initiator),可以决定和连接有关的参数(很重要,后面会详细介绍)。Slave是连接的接受方(Advertiser),可以请求(或建议)连接参数,但无法决定。

注1:两个BLE设备之间,只能建立一条连接。

3.2 PDU的定义

和广播通信不同,面向连接的通信使用特定的PDU,称作Data Channel PDU,格式如下(LSB---->MSB):

Header(16 bits) Payload(Variable size) MIC(32 bits)

16bits的Header的格式如下:

LLID(2 bits) NESN (1bit) SN(1 bit) MD(1 bit) RFU(3 bits) Length(8 bits)

Data Channel传输的PDU有两类,一类是数据,称作LL Data PDU,另一类中控制信息,称作LL Control PDU。LLID用于区分PDU的类型,具体可参考后面3.2.1和3.2.2的描述。

NESN(Next Expected Sequence Number)和SN(Sequence Number),用于数据传输过程中的应答(Acknowledgement)和流控(Flow Control),具体可参考后面3.7的介绍。

MD(More Data),用于连接的关闭(或者说保持),具体可参考后面3.5的介绍。

RFU(Reserved for Future Use)。

Length,有效数据的长度(Payload+MIC),只有8-bits,因此Link Layer所能传输的最大数据是255 bytes(有MIC的话是251bytes),如果L2CAP需要传输更多的数据,需要分包之后传输(这也是L2CAP的主要功能之一,具体可参考“蓝牙协议分析(3)_蓝牙低功耗(BLE)协议栈介绍”)。

Payload是有效数据(SDU,L2CAP的PDU),长度由Header中的Length字段觉得,有效范围是0~255。

3.2.1 LL Data PDU

LL Data PDU有两种:

Header中的LLID=01b时,Continuation fragment of an L2CAP message, or an Empty PDU。这种类型的PDU,要么是一个未传输完成L2CAP message(长度超过255,被拆包,此时不是第一个),要么是一个空包(Header中的Length为0)。

Header中的LLID=01b时,Start of an L2CAP message or a complete L2CAP message with no fragmentation。这种类型的PDU,要么是L2CAP message的第一个包,要么是不需要拆包的完整的L2CAP message,无论哪种情况,Header中的Length均不能为0。

3.2.2 LL Control PDU

Header中的LLID=11b时,表示这个数据包是用于控制、管理LL连接的LL control PDU。LL control PDU的payload的格式如下:

Opcode(1 octet) CtrlData(0 ~ 26 octets)

其中Opcode指示控制&管理packet的类型,包括:

LL_CONNECTION_UPDATE_REQ,连接参数的更新; 
LL_CHANNEL_MAP_REQ,Channel map的更新; 
LL_TERMINATE_IND,连接即将被关闭的通知(可以通知被关闭的原因); 
LL_ENC_REQ、LL_ENC_RSP、LL_START_ENC_REQ、LL_START_ENC_RSP,加密有关的请求;等等,具体可参考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”。

3.3 连接的建立

对BLE来说,连接建立的过程很简单,包括:

1)处于connectable状态设备(Advertiser),按照一定的周期广播ADV_IND或者ADV_DIRECT_IND包(可参考“蓝牙协议分析(5)_BLE广播通信相关的技术分析”)。

2)主动连接的设备(Initiator),在收到广播包之后,会回应一个CONNECT_REQ请求,该请求携带了可决定后续“通信时序”的参数,例如双方在哪一个时间点、哪一个Physical Channel收发数据,等等,后面会详细描述。

3)Initiator在发出CONNECT_REQ数据包之后,自动转变为Connection状态,成为Master角色(注意:这是“自动”的,不需要等待另一方的回应)。同样,Advertiser在收到CONNECT_REQ请求之后,也自动转变为Connection状态,成为Slave角色。

4)此后,双方按照CONNECT_REQ参数所给出的约定,定时到切换到某一个Physical Channel上,按照Master->Slave然后Slave->Master的顺序,收发数据,直至连接断开。

master在发出连接请求的时候,需要在CONNECT_REQ PDU的payload中,定义和连接有关的参数。payload的格式如下:

InitA (6 octets) AdvA (6 octets) LL Data (22 octets)

 

其中InitA和AdvA分别是Master和Slave的蓝牙地址,LL data则包含了所有的连接参数,包括:

AA 
(4 octets)
CRCInit 
(3 octets)
WinSize 
(1 octet)
WinOffset 
(2 octets)
Interval 
(2 octets)
Latency 
(2 octets)
Timeout 
(2 octets)
ChM 
(5 octets)
Hop 
(5 bits)
SCA 
(3 bits)

AA,LL Connection的Access Address,在不同设备组合之间,需要唯一,并遵守一些原则,具体可参考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”。

CRCInit,用于CRC计算的一个初始值,由Link Layer随机生成。

WinSize和WinOffset,全称是transmitWindowSize和transmitWindowOffset,用于决定连接双方收发数据的时间窗口(第2章提到的时分的概念)。下面3.4小节会详细介绍。

connInterval,全称是connInterval,连接双方收发数据的周期。由于一个Master可能会和多个Slave建立连接,因此蓝牙的信道资源不能被某一个LL Connection所独占,所以一个收发周期中,可能有多个连接进行收发数据(具体的时间窗口,由transmitWindowOffset决定)。下面3.4小节会详细介绍。

Latency和Timeout,全称是connSlaveLatency和connSupervisionTimeout,和连接超时、自动断开有关,具体可参考3.4小节的描述。

ChM的全称是Channel map,用于标识当前使用和未使用的Physical Channel。Hop的全称是hopIncrement,它和ChM一起决定了数据传输过程中的跳频算法,具体可参考3.6小节的描述。

SCA(sleep clock accuracy),用于定义最差的Master睡眠时钟精度,具体可参考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”,本文不再详细介绍。

3.4 连接建立后的通信过程

3.3小节提到,当Master发出/Slave收到CONNECT_REQ后,就自动进入连接状态,那双方在收发数据的时间窗口怎么确定呢?可参考下面图片1和图片2:

BLE连接时序---Master视角

图片1 BLE连接时序---Master视角

BLE连接时序---Slave视角

图片2 BLE连接时序---Slave视角

1)从Master的视角看,当它发出CONNECT_REQ后,会在1.25 ms + transmitWindowOffset到1.25ms + transmitWindowOffset + transmitWindowSize之间,发送第一个packet(M->S)。同理,Slave在收到CONNECT_REQ之后,也会在相应的时间区间去接收packet(M->S)。

a)transmitWindowOffset可以控制这个LL Connection使用哪一段时间进行通信,从而保证了同一个Master和多个Slave之间的多个连接,可以互不影响的通信(时分)。transmitWindowOffset的取值范围是:0 ms到connInterval(后面会介绍connInterval)。

b)从Master发出CONNECT_REQ,到Slave接收到CONNECT_REQ,是有一定的时间延迟的,因此需要一定的时间窗口(transmitWindowSize),才能保证第一个packet能否正确的发送并被接收。transmitWindowSize必须是1.25ms的倍数,最小值是1.25 ms,最大值是(connInterval - 1.25 ms),但不能超过10ms。

c)正常情况下,所有“M->S”数据包的发送,不能超过transmitWindowSize,以便留出S->M的时间。但第一个packet例外(参考上面图片1)。

2)Master发出第一个packet之后,将以此为起始点(称作anchor point),以connInterval为周期,接着发送后续的packet(M->S),以及接收Slave的packet(S->M),具体可参考上面图片1。

a)这样以connInterval为周期的发送(M->S)、接收(S->M)组合(可能有多个),称作Connection Event。因此BLE面向连接的通信的基础,就是Connection Event。

b)connInterval的大小,决定了数据传输的周期。对一个连接来说,每个周期只能有一次的收发,因此connInterval的选择,直接决定了数据传输的速度。BLE协议规定,connInterval必须是1.25ms的倍数,范围是7.5ms~4s。

3)Slave如果没有收到第一个packet(M->S),则会以1.25 ms + transmitWindowOffset为起点,等待connInterval之后,再次尝试接收,直到接收到为止。Slave接收到packet之后,则以收到该packet的时间点为起始点(anchor point),以connInterval为周期,接着接收后续的packet(M->S),以及发送packet给Master(S->M),具体可参考上面图片2。

注2,关于数据传输的速率: 
由上面的通信过程可知,BLE面向连接的通信速率,是由connInterval以及每个Connection Event中所传输的数据量决定的。 
由上面3.2的描述可知,LL Data PDU的有效负荷不能超过255(251)bytes,不过考虑到一次传输的效率、错误处理等因素,具体的Link Layer不会使用这么大的packet。相应地,为了提高传输速度,一般会在一个Connection Event中,传输多个packet。以iOS为例,它可能会在一个Connection Event中,传输6个packets,每个packet的长度是20bytes。
另外,很多平台为了保证自身作为Master的性能,会限制connInterval的最小值,以iOS为例,最小值是30ms。因此,可估算得到相应的传输速率为20B * 6 / 30ms = 32kbps,是相当缓慢的。

注3:BLE的面向连接通信是使用跳频技术的,即每次Connection Event,都会使用不同Physical Channel收发数据,具体的跳频机制,可参考3.6小节的介绍。

3.5 连接的控制与管理

连接建立之后,Master或者Slave可以借助Link Layer Control Protocol (LLCP),通过LL Control PDU,对连接进行管理控制,包括:

Connection Update Procedure,连接参数(包括connInterval,connSlaveLatency,connSupervisionTimeout)更新的通知。只能由Master发起。

Channel Map Update Procedure,更新Channel map。只能由Master发起。

Encryption Procedure,对连接进行加密,可由master或者slave发起。

Termination Procedure,断开连接。

Connection Parameters Request Procedure,请求更新连接参数(connInterval,connSlaveLatency,connSupervisionTimeout),Slave或者Master都可以发起,和Connection Update Procedure不同是,这是一个协商的过程,不是一定能够成功。

LE Ping Procedure,类似于网络协议中ping操作。

等等。不再详细介绍,具体可参考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”。

3.6 连接超时及断开

BLE连接断开的原因有两种:一种是预期内的、主动断开,此时会走3.4小节提到的Termination Procedure过程;第二种是一些非预期的原因导致的超时断开,如距离超出、遭受严重的干扰、突然断电等。

对于第一种,是协议内的正常流程,没有什么好说的。而对于第二种,则需要一些timeout机制,检测这写异常情况,具体如下。

1)Master和Slave的Link Layer,都会启动一个名称为TLLconnSupervision的timer,每接收到一个有效的数据包时,该timer都会重置。

2)连接建立的过程中,如果TLLconnSupervision超过6 * connInterval(没有接收到第一个数据包),则认为连接建立失败。

3)在连接成功之后,如果TLLconnSupervision超过connSupervisionTimeout,则说明link loss,则执行超时断开。connSupervisionTimeout是一个可配置的参数,范围是100ms~32s,并且不能大于(1 + connSlaveLatency) * connInterval * 2。

4)BLE协议允许slave忽略掉“connSlaveLatency”个Connection Event,在被忽略的这段时间内,Slave不需要收发数据包,也不会增加TLLconnSupervision,从而引发超时断开。connSlaveLatency是一个整数,有效范围应该在0到((connSupervisionTimeout / (connInterval*2)) - 1)之间,并且不能大于500。

注4:connSlaveLatency是一个非常有用的参数,它允许Slave在数据通信不频繁的时候,忽略掉一些Connection Event,进而可以睡得更久,更加省电。

3.7 跳频(Hopping)策略

BLE的跳频策略是非常简单的,即:每一个Connection Event,更换一次Physical Channel,当然,master和slave需要按照相同的约定更换,不然就无法通信。这个约定如下:

BLE跳频策略

图片3 BLE跳频策略

1)首先,使用一个Basic的算法,利用lastUnmappedChannel和hopIncrement,计算出unmappedChannel。

a)lastUnmappedChannel在连接建立之初的值是0,每一次Connection Event计算出新的unmappedChannel之后,会更新lastUnmappedChannel。

b)hopIncrement是由Master在连接建立时随机指定的,范围是5到16(可参考3.3中的Hop)。

c)确定unmappedChannel的算法为:unmappedChannel = (lastUnmappedChannel + hopIncrement) mod 37,本质上就是每隔“hopIncrement”个Channel取一次,相当直白和简单。

2)计算出unmappedChannel之后,查找当前的Channel map,检查unmappedChannel所代表的Channel是否为used channel。如果是,恭喜,找到了。

Channel map也是由master,在连接建立时,或者后来的Channel map update的时候指定的。

3)如果不是,将所有的used Channel以升序的方式见一个表,表的长度是numUsedChannels,用unmappedChannel和numUsedChannels做模运算,得到一个index,从按照该index,从表中取出对应的channel即可。

3.8 应答(Acknowledgement)和流控(Flow Control)

由3.2小节的描述可知,LL Data PDU的Header中,有NESN(Next Expected Sequence Number)和SN(Sequence Number)两个标记,利用它们,可以很轻松的在Link Layer实现应答、重传、流控等机制。

为了实现这些功能,Link Layer会为每个连接创建两个变量,transmitSeqNum和nextExpectedSeqNum(为了和packet的SN/NESN bit区分,我们将它们简称为sn和nesn),并在连接建立的时候,它们都被初始化为0。

sn用于标识本地设备(Link Layer)发送出去的packets。

nesn是对端设备(Link Layer)用来应答本地设备发送的packet,或者请求本地设备重发packet。

Link Layer在收发packet时,会遵循如下的原则(可结合下面图片4理解):

注5:下面图片4是从“BLUETOOTH SPECIFICATION Version 4.2 [Vol 6, Part B]”中截的一张图,不过spec中画的有问题,我用红色字体改正了。另外,这个图片非常有歧义、难以理解,我会在下面解释。

1)无论是Master还是Slave,发送packet的时候,都会将当前的sn和nesn copy到packet的SN和NESN bit中。

2)无论是Master还是Slave,当接收到一个packet的时候,会将该packet的NESN bit和本地的sn比较:如果相同,说明该packet是对端设备发来的NAK packet(请求重发),则需要将旧的packet重新发送出去;如果不同,说明是对端设备发来的ACK packet(数据被正确接收),则需要将本地的sn加1,接着发送新的packet。

a)以上过程可参考下面图片4中的左边部分。

b)本地的sn,代表本地设备已经发送出去的packet,而packet中的NESN bit,代表对端设备期望本地设备发送的packet。如果二者相同,说明对方期望下次发送的packet,和我们已经发送的packet相同,因此是NAK信号,要求重发。如果二者不同,说明对方设备期望发送一个新的packet,也说明我们上次发送的packet已经成功接收,因此可以将本地的sn加1了。

3)无论是Master还是Slave,当接收到一个packet的时候,会将该packet的SN bit和本地的nesn比较:如果相同,则说明是一个新的packet,接收即可,同时将本地的nesn加1;如果不同,则说明是一个旧的packet,什么都不需要处理。

a)以上过程可参考下面图片4中的右边部分。

b)packet中的SN bit,代表对端设备正在发送的packet,而本地设备的nesn,代表本地设备期望对端设备发送的packet。如果二者相同,则说明是一个期望的packet(新的),就可以收下该packet,并将期望值加1(nesn加1)。如果二者不同,说明不是本地设备期望的packet,什么都不做就可以了。

4)上面2)和3)两个步骤,是相互独立的,因此一个NAK packet,也可能携带新的数据,反之亦然。

5)当一个设备无法接收新的packet的时候(例如RX buffer已满),它可以采取不增加nesn的方式,发送NAK packet。对端设备收到该类型的packet之后,会发送旧的packet(图片4左边部分的“TX old data, sn”分支)。该设备收到这样旧的packet的时候,不会做任何处理(图片4右边部分的“Ignore RX data”分支)。这就是Link Layer的流控机制(Flow control)

BLE应答和流控机制

图片4 BLE应答和流控机制

4. HCI

HCI(Host Control Interface)的功能就简单多了,就是要封装Link Layer所提供的功能,包括两类。

1)连接的建立、关闭、参数设置、管理等,这一类是通过HCI command/event(其格式可参考“蓝牙协议分析(5)_BLE广播通信相关的技术分析”中的介绍)完成的,包括:

LE Create Connection Command,建立连接的命令,需要提供连接有关的参数,包括connInterval(Conn_Interval_Min和Conn_Interval_Max)、connSlaveLatency(Conn_Latency)和connSupervisionTimeout(Supervision_Timeout)。

LE Create Connection Cancel Command,取消或者断开连接。

LE Connection Update Command,更新连接参数,包括connInterval(Conn_Interval_Min和Conn_Interval_Max)、connSlaveLatency(Conn_Latency)和connSupervisionTimeout(Supervision_Timeout)。

LE Set Host Channel Classification Command,配置Channel map。

LE Read Channel Map Command,读取Channel map。

等等。

有关这些命令的具体描述,可参考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 2, Part E] Host Controller Interface Functional Specification”。

2)对ACL data的封装和转发,不再详细说明。

6. GAP

GAP(Generic Access Profile)的主要功能,是定义BLE设备所具备的能力,以实现互联互通的功能。

对BEL基于连接的通信来说,GAP定义了4种连接有关的模式(不同的产品形态,可以选择是否支持这些模式,具体可参考“BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] 9.3 CONNECTION MODES AND PROCEDURES”):

Non-connectable mode,不可被连接。

Directed connectable mode,可以被“直连”(在知道对方蓝牙地址的情况下的快速连接)。

Undirected connectable mode,可以被“盲连”(不知道对方蓝牙地址)。

Auto connection establishment procedure,可以被自动连接(不需要host干预)。

相应地,GAP定义了5中和这些模式有关的过程(不同的产品形态,可以选择是否支持这些过程):

General connection establishment procedure,通用的连接建立过程,搜索、发现、连接,都需要Host参与。

Selective connection establishment procedure,有选择的连接建立过程,Host需要告诉Controller,自己只希望于特定的设备建立连接。

Direct Connection Establishment Procedure,直接和某一个已知设备建立连接(对方也知道我们)。

Connection Parameter Update Procedure,连接参数的更新过程。

Terminate Connection Procedure,断开连接。

这些mode和procedure的具体描述,可参考蓝牙spec[1]


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

蓝牙解析(part7):BLE的连接 的相关文章

  • 零基础开发蓝牙设备

    前言 现在几乎每个人的手机都具备蓝牙功能 所以如果你的硬件设备也具备蓝牙通信功能 那么便可以很容易和手机建立通信 从而具备IOT物联网属性 但我们也知道蓝牙Ble 目前已发展到5 2版本 协议极其复杂 并不是所有人都需要去详细了解它 我们更
  • i12蓝牙耳机使用(小米手机)

    一 操作位置 操作点击按键在无用孔位和喇叭位之间 二 听音乐 项目 左耳 右耳 单击 暂停播放 暂停播放 双击 降低音量 提升音量 三击 小米手机打开小爱 小米手机打开小爱 长按 关耳机 关耳机 三 打电话 项目 打入 接听时 单击 接听
  • 蓝牙的知识总结(1)

    1 SoC System on Chip 称为系统级芯片 一个产品 是一个有专用目标的集成电路 其中包含完整系统并有嵌入软件的全部内容 同时它又是一种技术 用以实现从确定系统功能开始 到软 硬件划分 并完成设计的整个过程 从狭义角度讲 它是
  • STM32 BlueNRG-1低功耗介绍,包含CPU堆栈恢复和外设恢复

    概述 在消费类电子产品形态中 通常用锂电池 纽扣电池 干电池等设备供电 需要现有供电情况下能连续使用几个月或者1年 而这些供电电源通常只有20 40mAh左右的电 要达到要求的运行时间 通常要求平均功耗在uA级别 芯片正常工作下的工作级别基
  • Bes 充电盒协议总结

    1 开盖 上升沿信号开机 a 充电脚设成3 0 v 然后延迟160ms b 充电脚设成5v 然后延时100 ms c充电脚设成3 0 v 2 合盖 a 开5v 然后延时3s b 关5v 然后延时45ms c 发送复位pattern 0101
  • 蓝牙PHY6222添加OTA升级功能

    主要步骤 1 代码添加 ota app service 2 keil软件添加ota app代码 3 烧录软件添加ota设置 4 手机ota app升级 准备 奉加微电子官网下载6222的代码SDK V3 0以上 下载官网的PhyPlusKi
  • nRF52832学习记录(九、SAADC)

    nRF52xx 处理器中的ADC为一个逐次逼近的模拟数字转换器 所有nRF52xx 系列处理器的内部 ADC 称为 SAADC 目录 nRF52xx SAADC基础介绍 SAADC采样示例 SAADC EasyDMA 缓冲采样示例 SAAD
  • STM32+HC-05蓝牙模块学习与使用

    HC 05蓝牙串口通信 HC05模块是一款高性能主从一体蓝牙串口模块 是一种集成蓝牙功能的PCBA板 用于短距离无线通信 十分方便 从某宝商家那里可以看到 蓝牙可以使用多种方法使用 这里我使用的是蓝牙主机连接 所以我们这里需要准备的器件 两
  • 蓝牙 BLE 协议学习: 有关概念介绍

    背景 在学校内就用过蓝牙技术参加过比赛 并拿了奖 而蓝牙作为物联网中比较常见的协议 有必要进行深入的学习 此后的文章会以 ble v4 0 进行学习 介绍 蓝牙技术最初由电信巨头爱立信公司于 1994 年创制 当时是作为 RS232 数据线
  • bluez调试笔记

    蓝牙系列 bluez调试笔记 weixin 41069709的博客 CSDN博客 bluezbluez移植https blog csdn net weixin 41069709 article details 125168114 spm 1
  • windows10连接小米耳机Redmi AirDots 2

    1 控制面板 2 添加蓝牙设备 3 搜索 4 下一步 如果链接不上 请删除已有设备从第一步开始重新做
  • 蓝牙解析(part7):BLE的连接

    转自Wowo大神的http www wowotech net bluetooth ble connection html 1 前言 了解蓝牙的人都知道 在经典蓝牙中 保持连接 Connection 是一个相当消耗资源 power和带宽 的过
  • nRF52832学习记录(一、外设初识之 GPIOTE)

    添加GPIO和GPIOTE寄存器表 对于应用的理解对着寄存器查看会比较明了 这个不管是在哪款芯片上都是如此 2021 9 27 这些年蓝牙5 0的应用越来越多 最近也是想着把以前Enocean的低功耗设备有过的产品 用蓝牙做一套匹配的版本
  • Android中BLE连接出现“BluetoothGatt status 133”的解决方法

    http www loverobots cn android ble connection solution bluetoothgatt status 133 html 前 言 最近的工作方向一直在低功耗蓝牙方面 也就是BLE Blueto
  • pulseaudio使用过程中遇到的问题

    W pulseaudio main c This program is not intended to be run as root unless system is specified E pulseaudio core util c H
  • NRF52832学习笔记(1)—— 添加自有service(基于SDK15.3)

    前言 SDK版本15 3 评估板 pca10040 在uart的例程中添加battery service 添加之前 手机连上设备之后扫描到的service如下 一 分配ram空间 softdevice的flash code是确定 但ram是
  • Re: Programming in C with Bluetooth Sockets

    Re Programming in C with Bluetooth Sockets This is the function run by the bluetooth device that will recieve the data c
  • iPhone手机连接蓝牙鼠标和蓝牙键盘

    iPhone手机升级了IOS13之后 无意中发现了一个有趣的功能 iPhone手机可以连接蓝牙鼠标 具体方式如下 首先 要买一个支持蓝牙功能的鼠标 我用的罗技M590 建议再买一个蓝牙键盘 打开手机蓝牙 和蓝牙鼠标建立连接 这一步鼠标的说明
  • 蓝牙协议规范--L2CAP

    L2CAP 分析 记住一点 软件和硬件分开理解 数据经由物理通道交互 上层通道由各层协议打通 L2CAP 全称为逻辑链路控制与适配协议 Logical Link Control and Adaptation Protocol 位于基带层之上
  • android bluetooth UUID蓝牙查询表

    UUID是 Universally Unique Identifier 的简称 通用唯一识别码的意思 对于蓝牙设备 每个服务都有通用 独立 唯一的UUID与之对应 也就是说 在同一时间 同一地点 不可能有两个相同的UUID标识的不同服务 以

随机推荐

  • C++ 数据结构:DS单链表--合并

    题目描述 假定两个单链表是递增有序 定义并实现以下函数 完成两个单链表的合并 继续保持递增有序 int LL merge ListNode La ListNode Lb 输入 第1行先输入n表示有n个数据 接着输入n个数据 第2行先输入m表
  • STM32HAL库微秒延时(μs)

    STM32HAL库微秒延时 s 单片机 STM32F407ZET6 软件版本 STM32CubeMX 4 20 1 单片机固件包 STM32Cube FW F4 V1 15 0 本代码是我于2019年8月参加全国大学生电子设计竞赛前做赛前准
  • IPC-核间通讯

    1 IPC通讯是AUTOSAR体系结构中的核心组成部分 它使得不同的软件组件可以相互通信 协同工作 从而实现整车系统的功能 IPC可以理解为核间通讯 就是一个芯片有多个核 现在想让多核之间通信 达到下面几个目的 数据共享 不同的软件组件之间
  • mysqld: Can‘t read dir of ‘/etc/mysql/conf.d/‘ (Errcode: 13 - Permission denied)

    在安装docker mysql 5 7版本时 出现错误 mysqld Can t read dir of etc mysql conf d Errcode 13 Permission denied mysqld ERROR Fatal er
  • matlab方差分析

    一 单因素方差分析 1 各组数据长度相等 p anoval x x每一列为一个单独的样本值 返回的P是一个概率 p gt 0 05 故接受H0 即数据之间没有显著差异 0 01
  • C# new与malloc

    目录 C new与malloc C new与malloc的区别 C new关键字底层做的操作 C new与malloc new关键字 new关键字在C 中用于实例化对象 并为其分配内存 它是面向对象编程的基本操作之一 使用new关键字可以在
  • kafka报错:creating broker listeners from xxx unable to parse xxx:9092 to a broker endpoint

    1 美图 2 背景 kafka报错 creating broker listeners from xxx unable to parse xxx 9092 to a broker endpoint 具体报错内容如下 这个是你的地址域名写错了
  • sql monitor简介

    Sql monitor 简介 11g 之后的版本 oracle 提供了一种实时 sql 监控工具 即 sql monitor 默认情况下 当 sql 开启并行 或者 sql 的单词执行时间超过 5 秒钟 sql monitor 就会自动触发
  • iOS开发Swift-15-沙盒sandbox,JSON编码和Codable协议,本地数据存储,SQLite增删改查,视图按照数据排序-待办事项App进阶版...

    1 在待办事项App中 寻找沙盒路径 TodosTableVC Delegate import UIKit UITableViewDelegate extension TodosTableVC 当用户点击cell的时候调用 override
  • 只要以查询数据的前三行如何处理

    select m name m numbs from select name count name as numbs from kh hbrc info t where t tpr fl 软件技术 and t xzzhw 软件部 group
  • 动态代理详解

    想要更加透彻的理解动态代理 首先要熟悉下静态代理 一 静态代理 总结来说 目标类和代理类实现了相同的接口 在代理类中依赖了目标类 代理类的方法中调用了目标类的方法 并做了一些增强性的工作 1 实现静态代理 demo 要求 在某个类执行类中的
  • C/C++通过网卡名称获取ipv4地址

    通过网卡名称获取对应的IP地址 1 通过网卡名称获取对应的IP地址 1 通过网卡名称获取对应的IP地址 include
  • 华为机试:字符串加密

    一 题目 描述 有一种技巧可以对数据进行加密 它使用一个单词作为它的密匙 下面是它的工作原理 首先 选择一个单词作为密匙 如TRAILBLAZERS 如果单词中包含有重复的字母 只保留第1个 其余几个丢弃 现在 修改过的那个单词属于字母表的
  • Fedora12 Linux启动过程

    1 加载BIOS BIOS Basic Input Output System 是固化到计算机内主板上一个ROM芯片上的程序 保存CPU相关信息 设备启动顺序信息 硬盘信息 内存信息等等 打开计算机电源第一项工作即加载BIOS 进行POST
  • vim插件2--autocomplpop

    vim插件2 autocomplpop 功能 自动打开弹出菜单 以便于文字或单词补全 使用本插件后 vim会自动打开弹出菜单并显示相应补全项 它在输入字符或插入模式下移动光标时完成 不会阻止继续输入字符 AutoComplPop Autom
  • Spring实践(二)AOP的底层实现机制

    上一篇通过模拟spring的IOC 机制来理解控制反转 依赖注入 本篇同样模拟一下spring的第二大特性AOP Aspect Oriented Programming 本篇将介绍如下内容 1 AOP的应用场景 2 生成一个简单的工程案例
  • Devops理论与基础

    目录 文章目录 目录 1 什么是DevOps 2 什么是CI CD 1 一家软件公司 2 软件开发过程 3 传统应用发布模式 4 持续集成 CI 5 持续部署 CD 6 CI CD带来的好处 7 CI CD管道的阶段 3 DevSecOps
  • 如何寻找数据集?

    如何寻找数据集 除了医疗领域之外 其他领域的数据集有时也很难获取 这就需要我们掌握一些常见的数据集搜集方法和常用资源 最近 Medium 上的一位博主介绍了多个常用的数据集获取来源 1 Awesome Data 这是一个 GitHub 存储
  • git拉取的小程序代码,编译显示[ app.json 文件内容错误] app.json: app.json 未找到 怎么办?

    项目运行到微信开发者工具时 出现如此报错 解决方案 1 项目导入方式不正确 应该导入应该导入unpackage dist dev mp weixin打开项目 而不是直接打开项目文件夹 2 应该注意将项目的AppId 换成有自己开发权限的id
  • 蓝牙解析(part7):BLE的连接

    转自Wowo大神的http www wowotech net bluetooth ble connection html 1 前言 了解蓝牙的人都知道 在经典蓝牙中 保持连接 Connection 是一个相当消耗资源 power和带宽 的过