关于CC2541蓝牙开发板的学习笔记-3

下面进行一个简单地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;
}
  1. SYS_EVENT_MSG 系统消息事件,当有按键触发,或者BLE 协议栈接收到数据后都会向任务函数发送系统事件,告知用户准备接收。
  2. simpleBLECentral_ProcessOSALMsg 函数,处理OSAL系统消息的函数。
  3. 当处理完当前的消息后,一定要对此消息事件异或操作,告诉系统当前的消息事件处理完了。
  4. START_DEVICE_EVT , 上面刚刚提到的, 在初始化函数的最后,通过osal_set_event 设置了该事件,放到这里来处理,其实是基于模块化和见名之意的用意。
  5. GAPCentralRole_StartDevice,开始启动主机,并且传递了两个回调函数地址,分别是:
// GAP Role Callbacks
static const gapCentralRoleCB_t simpleBLERoleCB =
{
  simpleBLECentralRssiCB,       // RSSI callback
  simpleBLECentralEventCB       // Event callback
};
  1. simpleBLECentralRssiCB 读RSSI 值回调函数。
  2. simpleBLECentralEventCB 主机事件回调函数。

所谓回调函数,是会被其他系统自动调用的一个函数,我们可以在这个函数里接收系统传递过来的参数。

 

你可能感兴趣的:(关于CC2541蓝牙开发板的学习笔记-3)