下面进行一个简单地BLE协议栈基础实验:数据传输试验。其实就是BLE协议栈安装后的主从通信实验,实现两个BLE节点的通信,主机向BLE从机发送一个字节,然后把写入的字节读回来,以测试主从之间的通信。
SimpleBLECentral主机编程:
在低功耗蓝牙中有四种设备类型:Central主机、、Peripheral 从机、Observer 观察者、Broadcaster 广播者。通常Central 和Peripheral 一起使用。然后Observer和Broadcaster 一起使用。
我们首先从最简单的主机SimpleBLECentral 和从机SimpleBLEPeripheral 开始。打开SimpleBLECentral 工程。打开SimpleBLECentral.c文件。
#define GAPCENTRALROLE_MAX_SCAN_RES 0x404 //!< Maximum number of discover scan results to receive. Default is 0 = unlimited.
// Maximum number of scan responses
#define DEFAULT_MAX_SCAN_RES 8
// Setup Central Profile
{
uint8 scanRes = DEFAULT_MAX_SCAN_RES;
GAPCentralRole_SetParameter ( GAPCENTRALROLE_MAX_SCAN_RES, sizeof( uint8 ), &scanRes );
}
GAPCentralRole_SetParameter 函数,设置GAPCENTRALROLE_MAX_SCAN_RES(最大的扫描回应)为8 个(uint8 scanRes = DEFAULT_MAX_SCAN_RES;),也就是说如果广播的从机超过了9个,我们的central 也只能扫描到先RSP(回应) 的从机, 因此, 说明我们的主机最大能扫描到8个从机。
// Initialize GATT Client
VOID GATT_InitClient();
GATT_InitClient函数,初始化GATT Client,GATT由Service和Client之分,Service作为服务端、GATT Client提供了read/write接口,Central作为Client、对于一般情况下,Peripheral作为Service,所以主机Central会调用GATT_WriteCharValue或者GATT_ReadCharValue和Service端的Peripheral从机通信,而Peripheral 需要通过notify 的方式,也就是调用GATT_Notification 发起和主机的通信。
// Task ID for internal task/event processing
static uint8 simpleBLETaskId;
// Register to receive incoming ATT Indications/Notifications
GATT_RegisterForInd( simpleBLETaskId );
GATT_RegisterForInd 函数, 注册当前任务为GATT 的notify 和indicate 的接收端。也就是说当从机Peripheral 通过GATT_Notification 发来数据时,当前的任务函数会接收到消息,如果不注册,则无法接收。
// Task ID for internal task/event processing
static uint8 simpleBLETaskId;
// Register for all key events - This app will handle all key events
RegisterForKeys( simpleBLETaskId );
注册按键服务,当开发板上的五向按键或者S1 按键被按下时,会发送按键消息,只有注册了按键服务的任务id 才会接收到该消息。
#define START_DEVICE_EVT 0x0001
// Task ID for internal task/event processing
static uint8 simpleBLETaskId;
// Setup a delayed profile startup
osal_set_event( simpleBLETaskId, START_DEVICE_EVT );
该函数会启动一个事件,这里是START_DEVICE_EVT,也就是任务函数的开始运行的地方,由此,会正式转入系统的运行, 当系统运行后, 将最先执行328 行的uint16 SimpleBLECentral_ProcessEvent( uint8 task_id, uint16events ) 函数。
simpleBLECentral.c 中的任务处理函数:
uint16 SimpleBLECentral_ProcessEvent( uint8 task_id, uint16 events )
{
VOID task_id; // OSAL required parameter that isn't used in this function
if ( events & SYS_EVENT_MSG )
{
uint8 *pMsg;
if ( (pMsg = osal_msg_receive( simpleBLETaskId )) != NULL )
{
simpleBLECentral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
// Release the OSAL message
VOID osal_msg_deallocate( pMsg );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if ( events & START_DEVICE_EVT )
{
// Start the Device
VOID GAPCentralRole_StartDevice( (gapCentralRoleCB_t *) &simpleBLERoleCB );
// Register with bond manager after starting device
GAPBondMgr_Register( (gapBondCBs_t *) &simpleBLEBondCB );
return ( events ^ START_DEVICE_EVT );
}
if ( events & START_DISCOVERY_EVT )
{
simpleBLECentralStartDiscovery( );
return ( events ^ START_DISCOVERY_EVT );
}
// Discard unknown events
return 0;
}
// GAP Role Callbacks
static const gapCentralRoleCB_t simpleBLERoleCB =
{
simpleBLECentralRssiCB, // RSSI callback
simpleBLECentralEventCB // Event callback
};
所谓回调函数,是会被其他系统自动调用的一个函数,我们可以在这个函数里接收系统传递过来的参数。