蓝牙51822学习笔记二
目前手里面有几个项目用的是nrf51822这款蓝牙芯片。由于我从未接触过蓝牙协议,所以在很多地方磕磕绊绊的,所以最近准备系统学习一下该芯片。并做一下笔记放在我的博客里面。系统学习资料来源于B站青峰电子。视频名称为蓝牙nrf51822视频教程资料 编程开发 协议栈开发 青峰电子例程。
蓝牙协议简要图
应用层
SIG官方网站已经发布了GATT规范列表,包括警告通知、血压测量、心率、电池等等。
在ble_services中有已经进行通用定义的一些服务。如ble_bas是电池服务等。
控制层
1,主机控制器(HCI)
也称设备管理器,是基带中的一个功能模块,控制一般的蓝牙设备行为。负责所有与数据无关的蓝牙系统操作,例如询问附件蓝牙设备是否存在,连接蓝牙设备或者让本地的蓝牙设备可以被其他设备发现和连接。
为了实现响应的功能,设备管理器要求通过基带的资源控制器访问传输媒介。同时,设备管理器还通过HCI命令提供本地设备行为的控制功能。
2,链路层(LL)
负责链路管理、链路控制。包括负责创建、维护和释放逻辑电路以及更新设备之间的物理链路的相关参数。
3,物理层
负责接收从物理信道传输和接收信息数据包。若基带和物理层之间,一条控制路允许基带模块控制物理层的时隙和频率载波。同时,物理层模块向物理信道和基带发送和接收符合格式要求的数据流。
特别注意:官方对应控制程序采用的是封装函数格式,也就是说源程序没有开源。而是通过SoftDeviceAPI函数是经过封装后,无法查看源函数,该类型函数名带有sd_前缀
主机主协议层:
通用访问规范(GAP)
GAP是应用层能够直接访问BLE蓝牙协议栈的最底层,他包括管理广播和连接时间的有关参数。GAP模块代表了所有蓝牙设备的共用基础功能,如传输,协议或者应用规范锁使用的模式和访问过程。GAP的服务包括设备发现,连接方式,安全,认证,关联模型和服务发现等
角色
为了创建和维持一个BLE连接,引入角色概念。一个BLE设备不是集中设备器角色就是外围设备角色。这是根据谁发起连接而决定的。集中器设备时连接的发起者,外围设备时被连接者。
蓝牙核心规范还定义了观察者角色和广播者角色。观察者角色监听空中的事件,广播者角色只是广播信息而不接收信息。观察者角色和广播角色都只广播而不建立连接。
在一个连接的另一端的设备称为对等设备
广播
集中器能够与外围设备建立连接。外围设备必须处于广播状态。每经过一个事件间隔发送一次广播数据包。时间间隔称之为广播间隔。范围时20ms~10.24s
集中器发送一个连接请求发起连接之前,必须接收到一个广播数据包,外围设备发送一个广播数据包之后一小段时间内只监听连接请求。
一个广播数据包最多能携带31字节数据。通常包含用户可读的名字、关于设备发送数据包的有关信息。用于表示此设备是否可被发现的标志等类似的标志。
当集中器接收到广播数据包后,他可能发送请求更多数据包,称为扫描回应,如果设置成主动扫描,外围设备将会发送一个扫描回应作为对集中器请求的回应,扫描回应最多可携带31字节数据。
广播,包括扫描请求和扫描回应,出现在原理WLAN使用的2.4G频段之外的3个频率上,以防被WiFi干扰。
扫描
扫描是集中器监听广播数据包和发送扫描请求的过程,他有两个定时参数需要特别注意:扫描窗口和扫描间隔。
对于每一个扫描间隔,集中器扫描的时间等于一个扫描窗口,这就意味这扫描窗口等于扫描间隔,那么集中器将处于连续扫描之中。扫描床基于和扫描间隔之比称为扫描占空比。
发起
如果集中器想建立一个连接,当扫描监听到广播数据包注资后他将采用相同的过程:当要发起连接时,集中器接收到一个广播数据包之后将会发送一个连接请求。
连接
集中器和外围设备第一次交换数据定义为连接状态。在一个连接状态中,集中器将会在一个特定定义的间隔从外围设备请求数据。这个间隔称为来凝结间隔。由集中器决定并应用于连接。但是外围设备可以发送连接参数更新请求给集中器。根据蓝牙核心规范,连接间隔必须在7.5ms和4s之间。
如果外围设备在一个时间帧内没有回应集中器的数据包,称为连接监管超时,连接被认为丢失。
可以通过在每一个连接间隔中传输多个数据包以获得更高的数据吞吐量,每一个传输数据包最多可以携带20个字节的数据。但是如果电流消耗时钟重点,同时外围设备也没有数据要发送,它可以选择忽略一定数量的连接间隔。这个忽略连接间隔的数目称之为从机延时
在一个连接中,除了广播信道,设备间在频带的所有信道中进行通讯。但是对于应用层不需要关心。
通用属性配置文件(GATT)
GATT层是传输真正数据所在的层。包括了一个数据传输和存储框架以及基本操作。GATT定义了两类角色:服务器端、客户端。GATT角色无需和GAP角色绑定,但是可能由更高层的规范进行指定。
角色
BLE还定义了另外两种角色:GATT服务器和GATT客户端。完全独立于GAP的角色。提供数据的设备称为服务器,访问数据的称之为客户端。
一个设备可以同时作为服务器和客户端。
GATT规范层次
一个GATT服务器通过一个称为属性表的表格组织数据,这些数据就是用于真正发送的数据。
属性
一个属性包含句柄、UUID。句柄是属性在GATT表中的索引,在一个设备中每一个属性的句柄都是唯一的。UUID包含属性表中的数据类型的信息,他是理解属性表中的值的每一个字节的意义的关键信息。在一个GATT表中可能由许多属性,这些属性可能有相同的UUID。
特性
一个特性至少包含两个属性:一个属性用于声明,存放特性的值。
所有通过GATT服务传输的数据必须映射成一系列的特性,可以把特性中的这些数据堪称是一个个捆绑起来的数据,每个特性就是一个自我包容而独立的数据点。
描述符
任何在特性中的属性不是定义为属性值就是描述符。描述符是一个额外的属性以提供耕读特性的信息。它提供一个人类可识别的特性描述的实例。
CCCD,客户端特性配置描述符。这个描述符是给任何支持通知或者指示功能的特性额外增加的。CCCD中写入1是通知使能,写入2是指示使能,写入0是禁止这两个功能。
服务
一个服务可能包含一个或多个特性,这些特性是逻辑上相关的集合体。
GATT服务一般包含几块具有相关的功能,比如特定传感器的读取和设置,人机接口的输入输出。组织具有相关特性到服务中既实用又有效,它使得逻辑上和用户数据上的边界变得清晰。也有助于不同应用程序间代码的重用。
GATT基于SIG官方而设计,SIG建议根据他们的规范设计自己的profile。
profile(数据配置文件)
一个profile文件可以包含一个或者多个服务,一个profile文件包含需要的服务的信息或者为对等设备如何让交互的配置文件的选项信息。设备的GAP和GATT的角色都可能在数据交换过程中改变,因此,这个我呢见应该包含广播的种类,所使用的连接间隔、所需要的安全等级信息。
需要注意的是一个profile中的属性表不能包含另一个属性表
代码讲解
协议栈初始化
ble_stack_init()
初始化时钟
SOFTDEVICE_HANDLER_INIT()
协议栈使能
sd_ble_enable
设置回调
ble_evt_dispatch()
派发函数,是所有需要派发任务的集合。
sys_evt_dispatch
系统派发函数,做系统硬件的,内存、广播等
GAP初始化
gap_params_init
设置设备名称
sd_ble_gap_device_name_set
其他
gap_conn_params.conn_sup_timeout //连接时间间隔
广播
advertising_init
服务初始化
services_init
连接参数更新初始化
conn_params_init
开始广播
ble_advertising_start
主循环
电源管理函数,进入休眠
power_manage
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!