码迷,mamicode.com
首页 > 其他好文 > 详细

蓝牙4.0浅析

时间:2016-04-25 22:20:23      阅读:554      评论:0      收藏:0      [点我收藏+]

标签:

接触蓝牙4.0一个多月,主要学习了怎样搜索从节点,选择从节点,建立连接,主节点与从节点之间的相互通信,还有一主多从通信。

 

1 BLE协议栈

BLE协议栈包含两部分:主机和控制器。控制器部分包括:物理层PHY、链路层LL、主机控制接口层HCI。主机部分包括:逻辑链路控制及自适应协议层L2CAP、安全管理层SM、属性协议层ATT、通用访问配置文件层GAP、通用属性配置文件层GATT。

 

PHY是1Mbps自适应调频的GFSK射频,工作于免许可证的2.4GHz ISM(工业、科学和医疗)频段。

LL用于控制设备的射频状态,设备将会处于五种状态之一:等待、广告、扫描、初始化、连接。发起连接的设备成为主机,接受连接请求的设备称为从机。

HCI为主机和控制器之间提供标准通信接口。这一层可以使软件API或硬件接口,如:UART、SPI、USB。

L2CAP为上层提供数据封装服务,允许逻辑上点对点数据通信。

SM定义了配对和密钥分配方式,并为协议栈其它层与另一个设备之间的安全连接和数据交换提供服务。

ATT允许设备向另一个设备展示一块特定的数据,称之为属性。在ATT环境中,展示属性的设备成为服务器,与之配对的设备成为客户端。主机与从机和设备的ATT角色是相互独立的

GAP定义了使用ATT的服务框架。

GATT规定了配置文件(profile)的结构。在BLE中,所有被profile或服务用到的数据块都成为特性,两个建立连接的的设备之间的所有数据通信都是通过GATT子程序处理。GATT服务器上的特性值,及其内容和配置信息存储于属性表中。

 

 

2 BLE协议栈执行流程

mian()

{

  对板载硬件以及协议栈进行的初始化;

  osal_start_system(); //整个蓝牙4.0BLE协议栈真正的运行起来

  return 0;

}

 

osal_start_system() 不断查看事件表,如果有事件发生就调用相应的事件处理函数。

 

 

3 OSAL操作系统抽象层

OSAL负责调度各个任务的运行,如果有事件发生了,则会调用相应的事件处理函数进行处理。是一种基于事件驱动的轮询式操作系统。

 

建立一个事件表,保存各个任务对应的事件,建立另一个函数表,保存各个任务事件处理函数的地址,然后将这两张表建立某种对应关系,当某一事件发生时则查找函数表找到对应的事件处理函数。

tasksCnt:保存任务的总个数。

tasksEvents:这是一个指针,指向了事件表的首地址。

tasksArr:这是一个数组,该数组的每一项都是一个函数指针,指向了事件处理函数。

 

事件&消息:事件和数据封装成一个消息,将消息发送到消息队列,然后在事件处理函数中就可以使用osal_msg_receive,从消息队列中得到该消息。

pMsg = osal_msg_receive ( simpleBLETaskId );

 

3 应用程序初始化

(1)OSAL调用Init函数,各种初始化,然后设置一个操作系统虚拟层的SBP_START_DEVICE_EVT事件—>进入ProcessEvent函数。

(2)启动设备,设置应用的GAP功能,启动绑定管理。

       可以设置产生第一次周期事件的定时时间(从节点):

 1 osal_start_timerEx ( simpleBLEPeripheral_TaskID , SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD ); 

       可以添加自动搜索(主节点):

 1 if ( !simpleBLEScanning & simpleBLEScanRes == 0 )
 2     {
 3       simpleBLEScanning = TRUE;
 4       simpleBLEScanRes = 0;
 5       GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE,
 6                                               DEFAULT_DISCOVERY_ACTIVE_SCAN,
 7                                      DEFAULT_DISCOVERY_WHITE_LIST );   
 8       HalUARTWrite(0,"scanning\n", 9 ); 
 9     }
10     else
11     {
12       HalUARTWrite(0,"no scan\n", 8 ); 
13     }

初始化完成后,设备(从机)处于可发现状态。

 

4 SimpleBLECentral_ProcessEvent 事件处理函数

使用osal_msg_receive函数从消息队列上接收一个消息,然后使用switch-case 判断事件类型(系统消息任务、启动设备任务、周期事件任务、连接状态广告事件),调用事件处理函数。

异或^:将处理完的事件清除,仅留下未处理的事件。

与&:判断是否有匹配的事件。

或|:??

 

(1)SYS_EVENT_MSG 系统消息任务

       调用simpleBLECentral_ProcessOSALMsg

(2)START_DEVICE_EVT 启动设备任务

(3)SBP_PERIODIC_EVT 周期事件任务

 

5 simpleBLECentral_ProcessOSALMsg 消息事件处理函数

(1)KEY_CHANGE

  调用simpleBLECentral_HandleKeys

(2)GATT_MSG_EVENT

  调用simpleBLECentralProcessGATTMsg

(3)SERIAL_MSG

  调用simpleBLEPeripheral_HandleSerial

 

6 simpleBLECentralProcessGATTMsg 

其中可以接收从节点主动传来的数据notification

1 if ( ( pMsg->method == ATT_HANDLE_VALUE_NOTI ) )   //通知
2   {
3     if( pMsg->msg.handleValueNoti.handle == 0x002E)   //CHAR4的通知 
4     {
5       
6         HalUARTWrite(0,&pMsg->msg.handleValueNoti.value[0],pMsg->msg.handleValueNoti.value[0] ); //将接收到的数据打印到串口上
7       }
8     }

uint16 HalUARTWrite(uint8 port, uint8 *buf, uint16 len)

 

7 simpleBLECentralEventCB

(1)GAP_DEVICE_INIT_DONE_EVENT 设备初始化完成

  可以显示设备名称和地址

 1 LCD_WRITE_STRING( "BLE Central", HAL_LCD_LINE_1 );2 LCD_WRITE_STRING( bdAddr2Str( pEvent->initDone.devAddr ), HAL_LCD_LINE_2 ); 

 

(2)GAP_DEVICE_DISCOVERY_EVENT 设备发现完成

  可以显示选择信息

1  LCD_WRITE_STRING_VALUE( "Devices Found", simpleBLEScanRes,
2                                 10, HAL_LCD_LINE_1 );
3         if ( simpleBLEScanRes > 0 )
4         {
5           LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 );  
6             
7         }

 

(3)GAP_LINK_ESTABLISHED_EVENT 建立连接完成

  可以在这里改一主多从

 

蓝牙4.0浅析

标签:

原文地址:http://www.cnblogs.com/fullest-life/p/5411658.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!