赞
踩
之前讲系统OSAL浅谈了部分层,这次深入了解一下,BLE多个层之间的关系和沟通方式。
- BLE 链路建立流程
– 为什么每次连接蓝牙时间很长
– 为什么有最大广播间隔,最小广播间隔
– BLE 怎么省电的!!!- GAPRole 蓝牙设备角色建立
- GAP Bond Manager 连接管理
- GATT 通用属性配置
– 什么是特征和属性
– 什么是服务和协议
通用访问协议 GAP 主要是做五件事
设备发现;链接建立;链路终止;启动安全功能;设备配置
↓ 在应用层的初始化我们可以看到 使用 GAP_SetParamValue
可以设置,还有 GAP_GetParamValue()
可以读取
{//如果要确定一个广播间隔值就将 最大 最小值设为同一个值
uint16 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 ); //普通可发现模式下设置每次广播的间隔
}
为什么每次连接蓝牙都时间很长?
蓝牙 从机 会在 3 个广播信道中依次广播,而蓝牙 主机 也在3个信道中依次扫描,要两个设备在同一个时间同一个信道扫描到对方并建立连接事件,很多时候需要十几个甚至几十个广播周期。
为什么有最大广播间隔值,最小值广播间隔值?
在广播事件中,LL 层每次广播之前会有会有一个伪随机值的广播延时,防止因为设备之间的时钟不同、上电时间不同,巧合的错开,这种随机广播可以消除这种巧合。
**!BLE省电的关键!,就主要是他不是一直连接的状态,**他会记忆连接状态且进入长时间的休眠!休眠期间芯片可以只达到1.1μA的电流!
参数一般在 GAPRole
任务中处理,主要是连接间隔和从机延迟。
如果不设置连接间隔,LL 层将一直维持连接。可以设置以1.25ms/单位的 6(7.5ms) ~ 3200(4s)。最大值必须小于16s的有效连接间隔
如果连接间隔大,则降低功耗,但增加双方发送的时间、减少数据传输速率。反之
从机在无数据的时候不再响应主机连接事件,并且关闭射频天线。可以设置0~499个连接事件
如果从机延迟增大,则降低功耗,但增加主机向从机发送的时间,反之
可以设置为以10ms/单位的 10(100ms)~3200(32s)。
当然以上数据双方都是可以在连接后更改的,由 L2CAP层 处理
↓ 初始化部分代码
{ uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST; uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL; uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL; uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY; uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT; uint8 initial_advertising_enable = TRUE; // Set the GAP Role Parameters //设置 打开关闭广播 GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable ); //设置 有限广播模式,广播关闭的时间 GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime ); //设置 扫描回复的数据 包括设备名,设备连接间隔,设备发射功率等 GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData ); //设置 广播的数据 包括设备的发现模式,服务UUID GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData ); //设置 从机的连接属性可以更新使能 GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request ); //设置 最小连接间隔事件 GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval ); //设置 最大连接间隔事件 GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval ); //设置 从机延迟 GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency ); //设置 超时断开 GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout ); }
定义蓝牙设备角色建立
因为连接关系配置 GAPRole 占 GAP 比重大,TI把 GAPRole 单独为一个任务,其实 GAPRole 也是 GAP 配置的一部分,将 BLE 底层协议传递给 GAP 和 应用层
GAPRole连接关系配置有哪些连接关系?
广播者:只广播,不能连接
观察者:只扫描,不能连接
外设:可以连接一个链路的广播者
中心:可以连接多个链路的观察者
SBP_START_DEVICE_EVT
→ 命令 GAP 层设置配置 → 完成 GAPRole 设置GAP_MSG_EVENT
→ GAPRole接收 → 通知 应用层CB →GAPRole 清空 MsgGAP 连接管理。在连接时负责数据和连接安全的,定义经过身份认证后,哪些是可以读的,哪些是可以写的。
一般通过无线发送密钥;使用密钥加密连接;绑定储存密钥;重连使用SNV闪存中的密钥
一般使用 MITM 保护需要创建密码 且需要输入
SBP_START_DEVICE_EVT
→ 命令 GAP 层设置配置 → 完成 GAPBondMgr 设置SYS_EVENT_MSG
→ GAPBondMgr 接收 → 触发 应用层 CB → GAPBondMgr 清除 Msg{ uint16 passkey = 0; // passkey "000000" uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ; uint8 mitm = FALSE; uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY; uint8 bonding = TRUE; // 设置 在MITM模式下 默认密码 GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey ); // 设置 配对的模式 GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode ); // 设置 MITM保护是否开启 GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm ); // 设置 IO 能力 GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap ); // 设置 是否请求绑定 默认绑定 GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding ); }
GATT层 从 应用层 收集信息给 ATT层,ATT层 提供信息给 GATT层 再给 应用层。
通用属性配置。在 GATT 中规定,两个设备连接的时候,他们有两个角色:可以同时充当客户端 服务器
什么是特征和属性?
设备之间传输的信息就是属性
特征是安排怎么存储怎么使用属性的描述
一个特征由多个属性构成:特征值、特征声明、特征配置、描述
句柄、类型、权限属性解释其他属性
什么是服务和协议?
多个特征组合在一起是服务,一个到多个服务组合在一起是协议
强制 GAP 服务、强制 GATT 服务:都是底层 BLE 的一部分。每个 BLE 设备都必须声明的。
设备信息、TI示例服务 simpleGATTProfile
是应用层可以定义的。
↓ 在协议里面,是由 句柄 类似指针,UUID 特征值,内部包含的属性的值。
↓ 看应用层程序对于协议的表
static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] = { { // 服务协议 { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* 特征类型 */ // UUID的长度 声明为主服务 GATT_PERMIT_READ, /* 特征的权限 */ // 这里是只读 0, /* 句柄移动值 */ (uint8 *)&simpleProfileService /* 特征的值 */ // 属性的值 当前声明主服务的UUID }, { // 服务 声明特征char1 { ATT_BT_UUID_SIZE, characterUUID }, // UUID长度 声明为声明特征 GATT_PERMIT_READ, // 当前特征为只读 0, &simpleProfileChar1Props // 声明特征char1的权限 可读可写 }, { // Char1的值 { ATT_BT_UUID_SIZE, simpleProfilechar1UUID }, // UUID长度 声明为特征值 GATT_PERMIT_READ | GATT_PERMIT_WRITE, // 当前特征为可读可写 0, &simpleProfileChar1 // char1的值 }, { // char1的描述 { ATT_BT_UUID_SIZE, charUserDescUUID }, // UUID长度 声明为用户描述 GATT_PERMIT_READ, // 当前特征为只读 0, simpleProfileChar1UserDesp // "Characteristic 1" }, ... }
可以看出 原子元素为属性 → 特征 → 服务 → 协议
初始化 → 应用层使用 GATT_WriteCharValue() → GATT 层 → ATT 层 → BLE底层 → 接受到服务端回复 → 触发系统消息 SYS_EVENT_MSG
→ 应用层取值
下一次我将利用两套蓝牙设备 完成几个蓝牙特性的实验
公众号已经推进了进度,正在测试蓝牙设备的电池管理模块。
可以关注一波哈
马上回来
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。