# 概述 # GAP 分层负责设备建立连接的相关功能,包括设备发现、数据链路建立、终止、初始化安全管理和设备配置,参见下图 1 。 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gap/Images/GAPSTATE.png) 图1. GAP 分层的建立连接的示意图 在 `Standby` 状态,双方设备都处于未连接状态。`Advertiser` 尝试广播数据,`Scanner` 接收到广播数据后尝试进行扫描请求,并且得到扫描回复。此时 `Scanner` 产生连接意图,转变成 `Initiator` 发送连接请求,成功连接后发送广播的 `Advertiser` 作为 `Salve` ,进行连接请求的 `Initiator` 成为 `Master`。 - Standby:复位后设备处于初始空闲状态。 - Advertiser:设备正在通过特定数据进行广告,让任何 Initiator 设备知道它是可一个连接设备(此广告数据负载可以包含设备地址和一些其他数据,如设备名称)。 - Scanner:扫描设备收到广告后,向广告客户发送扫描请求。广播者响应扫描响应。这个过程称为设备发现。当然扫描设备已经知道广告设备可以发起与其的建立连接。 - Initiator:启动时,启动器必须指定要连接的对等设备地址。如果接收到与对等设备地址匹配的广告,则发起设备发送连接请求,该请求包含与广告设备连接所需的连接参数。 - Master/Slave:当连接形成时,广播的发起者作为 Slave ,Initiator 建立者作为 Master。 ## 抓包理解以上连接过程 ## * Advertiser 进行广播 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gap/Images/ADV_IND.png) * Scanner 进行连接请求并且获得回复 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gap/Images/ADV_SCAN_REQ.png) ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gap/Images/ADV_SCAN_RSP.png) * 连接请求 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gap/Images/ADV_CONNECT_REQ.png) ## 连接参数 ## 连接参数是 Initiator 通过连接请求建立连接时的配置参数。 ** Connect Interval ** 蓝牙采用跳频通信,连接的两个设备在某个固定时间切换到某个固定信道进行通信,链路层控制着信道切换。 建立连接后的通信数据被统一定义为 `Connection event` 。如果没有应用数据发送或者接收,那么链路层也会继续交换数据维护着这个链接。连接间隔是指以 `1.25ms` 为单位,两次 `Connection event` 的时间总和。其值可以从 6-3200 ,也就是 7.5ms 到 4.0s 。 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gap/Images/connectevent.png) 图2. 连接间隔 不同的应用需要不同的连接间隔,主要是从功耗进行考虑。 ** Slave Latency ** Slave Latency 可以在没有数据发送的时候选择跳过 connect event 。一个连接事件的发生都是 Master 发送一个通知,设备回复响应然后发送数据。没有数据时假设设置了 Slave Latency = 3 ,那么当 Master 发送通知的时候,Slave可以 3 次不响应,一直保持在深度休眠状态。这样就不会产生 Connect event 事件,从而更加省电。 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gap/Images/slaveLatency.png) 图3. Slave Latency 的功能示意图 ** Supervision Time-out ** Supervision Time-out 就是两次成功的 connect event 之间的最长事件。如果超出时间没有发生 connect event ,则双方设备终止连接,并进入到未连接状态。该参数可以设置在 100ms 到 32S 之间,需要注意的是超时监控时间必须大于有效连接间隔。 什么是有效连接间隔,其实就是两次成功的 connect event 之间的时间。假设 Slave Latency = 0,connect interval = 5ms 。设置的超时监控总不可能比 5ms 还小,这样就永远都处于超时状态。可以通过下面公式计算超时监控的时间。 Supervision Time-out > (Connection Interval) * (1 + [Slave Latency]) ## 连接参数设置策略 ## ### 连接参数更新 ### 连接参数都是主机进行控制,从机并不能直接修改连接参数。但是当主机设置了一组不合适的连接参数,比如主机要求 5ms 进行一次 connect event ,但是从机是一个温度计,这样的参数对于从机来说并不合适。所以从机可以发送一个请求,通知主机修改连接参数,主机可以选择是否修改当前参数配置。 这个过程发生在建立连接之后,所以连接参数的更新可以发生在任意时刻。 ```C #define DEFAULT_ENABLE_UPDATE_REQUEST GAPROLE_LINK_PARAM_UPDATE_INITIATE_BOTH_PARAMS #define DEFAULT_DESIRED_MIN_CONN_INTERVAL 80 #define DEFAULT_DESIRED_MAX_CONN_INTERVAL 800 #define DEFAULT_DESIRED_SLAVE_LATENCY 0 #define DEFAULT_DESIRED_CONN_TIMEOUT 1000 #define DEFAULT_CONN_PAUSE_PERIPHERAL 6 ``` simple_peripheral 工程中可以在 simple_peripheral.c 文件里面找到上面宏定义,这组宏就是设置连接参数。 其中 DEFAULT_CONN_PAUSE_PERIPHERAL 设置一个更新时间(秒为单位),这里设置的 6 秒。即建立连接之后 6 秒外围设备就会发出更新参数请求,通过 GAPRole_SendUpdateParam()或 GAPCentralRole_UpdateLink()命令异步发送。 也可以更改 DEFAULT_ENABLE_UPDATE_REQUEST 宏来禁用参数更新,例如 #define DEFAULT_ENABLE_UPDATE_REQUEST GAPROLE_LINK_PARAM_UPDATE_WAIT_REMOTE_PARAMS ### 连接参数优化 ### 连接参数直接决定设备的功耗,所以在产品的设计过程中这些参数一定要经过仔细考量,下面给出了连接参数设置的基本策略。 减少连接间隔如下: - 增加两个设备的功耗 - 增加双向吞吐量 - 减少任一方向发送数据的时间 增加连接间隔如下: - 降低两个设备的功耗 - 降低双向吞吐量 - 增加任一方向发送数据的时间 减少从机延迟(或将其设置为零)如下: - 增加外围设备的功耗 - 减少外围设备接收从中央设备发送数据的时间 增加从机延迟如下: - 在外围设备没有数据发送到中央设备的期间,可减少外设的功耗 - 增加外围设备接收从中央设备发送数据的时间 ## 连接终止 ## 连接终止的方式有两种,一种是前面提到的超时监控,比如设备距离过远的时候,就会发送主机一直收不到从机的响应,一旦超时就会发送连接终止。另一种就是主机或从机可以直接进行连接终止,任何一方发送连接终止的命令,双方就必须终止连接。 ## GAP 抽象层 ## 如下图 4 所示,应用层的绝大部分 GAP 相关时间都放在了 GAPRoleTask 进行处理。一部分可以直接调用 GAP 接口,例如广播和连接设置。 ![](http://www.leconiot.com/md_res/cc2640r2f/ble_stack_app/stack/gap/Images/GAPAbstraction.jpeg) 图4. GAP 抽象层 对于 GAP 事件、数据处理尽可能放在 GAPRoleTask ,对于一些配置参数可以直接调用 GAP 接口。 ## 配置广播参数 ## GAP 层几乎所有功能函数都封装在库文件中,API 封装在 `gap.h` 头文件,绝大部分功能已经在 GAPRoleTask 通过 GAP 函数直接调用方式处理。对于广播设置、连接配置等参数设置可以通过 GAP_SetParamValue()和 GAP_GetParamValue()函数修改。 以下是 simple_peripheral_init()中 GAP 层的配置: ````C //设置广告间隔 { uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL ; GAP_SetParamValue (TGAP_LIM_DISC_ADV_INT_MIN , advInt ); GAP_SetParamValue (TGAP_LIM_DISC_ADV_INT_MAX , advInt ); GAP_SetParamValue (TGAP_GEN_DISC_ADV_INT_MIN , advInt ); GAP_SetParamValue (TGAP_GEN_DISC_ADV_INT_MAX , advInt ); } ```` 上述代码设置了一般广播(General Advertisement)和限制广播(Limited Advertisement)。限制广播的意义是广播启动之后在一定时间内进行广播,一般情况下采用 Genneral advertisement 。代码中两种广播的时间间隔都进行了设置。 ## 加入我们 ## 文章所有代码、工具、文档开源。加入我们[**QQ群 591679055**](http://shang.qq.com/wpa/qunwpa?idkey=d94f12d37c3b37892af4b757c6dc34bea140f3f3128a8d68e556a3d728148e85)获取更多支持,共同研究CC2640R2F&BLE5.0。

CC2640R2F&BLE5.0-乐控畅联 © Copyright 2017, 成都乐控畅联科技有限公司.