微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > 射频无线通信设计 > CC2541的回调函数的定义和调用过程

CC2541的回调函数的定义和调用过程

时间:10-02 整理:3721RD 点击:

CC2541的回调函数的定义和调用过程


转载,897503845@qq.com
一、回调函数简介
TI的BLE协议栈使用到大量的回调函数,函数名末尾带“CB”的通常都是回调函数,它是指“call back”,在状态有改变时会调用此函数。本篇以SimpleBLECentral工程中simpleBLECentralEventCB函数,来简要说明回调函数的定义和调用过程。
二、解析代码
1、定义一个“成员为函数指针”的结构体
1)定义一个函数指针
[cpp] view plain copy
/**
* Central Event Callback Function
*/  
typedef void (*pfnGapCentralRoleEventCB_t)  
(  
  gapCentralRoleEvent_t *pEvent         //!< Pointer to event structure.  
);  
它的参数是一个gapCentralRoleEvent_t类型的消息指针*pEvent。
其中,gapCentralRoleEvent_t的类型如下
[cpp] view plain copy
/**
* Central Event Structure
*/  
typedef union  
{  
  gapEventHdr_t             gap;                //!< GAP_MSG_EVENT and status.  
  gapDeviceInitDoneEvent_t  initDone;           //!< GAP initialization done.  
  gapDeviceInfoEvent_t      deviceInfo;         //!< Discovery device information event structure.  
  gapDevDiscEvent_t         discCmpl;           //!< Discovery complete event structure.  
  gapEstLinkReqEvent_t      linkCmpl;           //!< Link complete event structure.  
  gapLinkUpdateEvent_t      linkUpdate;         //!< Link update event structure.  
  gapTerminateLinkEvent_t   linkTerminate;      //!< Link terminated event structure.  
} gapCentralRoleEvent_t;  
2)定义一个结构体
[cpp] view plain copy
/**
* Central Callback Structure
*/  
typedef struct  
{  
  pfnGapCentralRoleRssiCB_t   rssiCB;   //!< RSSI callback.  
  pfnGapCentralRoleEventCB_t  eventCB;  //!< Event callback.  
} gapCentralRoleCB_t;  
gapCentralRoleCB_t结构体有两个成员,一个是pfnGapCentralRoleRssiCB_t类型的成员,一个是pfnGapCentralRoleEventCB_t类型的成员。
2、写一个回调函数,并完成注册
1)定义一个函数simpleBLECentralEventCB
[cpp] view plain copy
/*********************************************************************
* @fn      simpleBLECentralEventCB
*
* @brief   Central event callback function.
*
* @param   pEvent - pointer to event structure
*
* @Return  none
*/  
static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent )  
{  
  switch ( pEvent->gap.opcode )  
  {  
    case GAP_DEVICE_INIT_DONE_EVENT:   
      {  
        LCD_WRITE_STRING( "BLE Central", HAL_LCD_LINE_1 );  
        LCD_WRITE_STRING( bdAddr2Str( pEvent->initDone.devAddr ),  HAL_LCD_LINE_2 );  
      }  
      break;  
    case GAP_DEVICE_INFO_EVENT:  
      {  
        // if filtering device discovery results based on service UUID  
        if ( DEFAULT_DEV_DISC_BY_SVC_UUID == TRUE )  
        {  
          if ( simpleBLEFindSvcUuid( SIMPLEPROFILE_SERV_UUID,  
                                     pEvent->deviceInfo.pEvtData,  
                                     pEvent->deviceInfo.dataLen ) )  
          {  
            simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );  
          }  
        }  
      }  
      break;  
    case GAP_DEVICE_DISCOVERY_EVENT:  
      {  
        // discovery complete  
        simpleBLEScanning = FALSE;  
        // if not filtering device discovery results based on service UUID  
        if ( DEFAULT_DEV_DISC_BY_SVC_UUID == FALSE )  
        {  
          // Copy results  
          simpleBLEScanRes = pEvent->discCmpl.numDevs;  
          osal_memcpy( simpleBLEDevList, pEvent->discCmpl.pDevList,  
                       (sizeof( gapDevRec_t ) * pEvent->discCmpl.numDevs) );  
        }  
        LCD_WRITE_STRING_VALUE( "Devices Found", simpleBLEScanRes,  
                                10, HAL_LCD_LINE_1 );  
        if ( simpleBLEScanRes > 0 )  
        {  
          LCD_WRITE_STRING( "<- To Select", HAL_LCD_LINE_2 );  
        }  
        // initialize scan index to last device  
        simpleBLEScanIdx = simpleBLEScanRes;  
      }  
      break;  
    case GAP_LINK_ESTABLISHED_EVENT:  
      {  
        if ( pEvent->gap.hdr.status == SUCCESS )  
        {            
          simpleBLEState = BLE_STATE_CONNECTED;  
          simpleBLEConnHandle = pEvent->linkCmpl.connectionHandle;  
          simpleBLEProcedureInProgress = TRUE;      
          // If service discovery not performed initiate service discovery  
          if ( simpleBLECharHdl == 0 )  
          {  
            osal_start_timerEx( simpleBLETaskId, START_DISCOVERY_EVT, DEFAULT_SVC_DISCOVERY_DELAY );  
          }  
          LCD_WRITE_STRING( "Connected", HAL_LCD_LINE_1 );  
          LCD_WRITE_STRING( bdAddr2Str( pEvent->linkCmpl.devAddr ), HAL_LCD_LINE_2 );     
        }  
        else  
        {  
          simpleBLEState = BLE_STATE_IDLE;  
          simpleBLEConnHandle = GAP_CONNHANDLE_INIT;  
          simpleBLERssi = FALSE;  
          simpleBLEDiscState = BLE_DISC_STATE_IDLE;  
          LCD_WRITE_STRING( "Connect Failed", HAL_LCD_LINE_1 );  
          LCD_WRITE_STRING_VALUE( "Reason:", pEvent->gap.hdr.status, 10, HAL_LCD_LINE_2 );  
        }  
      }  
      break;  
    case GAP_LINK_TERMINATED_EVENT:  
      {  
        simpleBLEState = BLE_STATE_IDLE;  
        simpleBLEConnHandle = GAP_CONNHANDLE_INIT;  
        simpleBLERssi = FALSE;  
        simpleBLEDiscState = BLE_DISC_STATE_IDLE;  
        simpleBLECharHdl = 0;  
        simpleBLEProcedureInProgress = FALSE;  
        LCD_WRITE_STRING( "Disconnected", HAL_LCD_LINE_1 );  
        LCD_WRITE_STRING_VALUE( "Reason:", pEvent->linkTerminate.reason,  
                                10, HAL_LCD_LINE_2 );  
      }  
      break;  
    case GAP_LINK_PARAM_UPDATE_EVENT:  
      {  
        LCD_WRITE_STRING( "Param Update", HAL_LCD_LINE_1 );  
      }  
      break;  
    default:  
      break;  
  }  
}  
2)声明函数
[cpp] view plain copy
static void simpleBLECentralEventCB( gapCentralRoleEvent_t *pEvent );  
3)使simpleBLECentralEventCB成为回调函数
[cpp] view plain copy
// GAP Role Callbacks  
static const gapCentralRoleCB_t simpleBLERoleCB =  
{  
  simpleBLECentralRssiCB,       // RSSI callback  
  simpleBLECentralEventCB       // Event callback  
};  
3、调用回调函数
1)定义一个新的函数指针变量pGapCentralRoleCB(central.c)
[cpp] view plain copy
// App callbacks  
static gapCentralRoleCB_t *pGapCentralRoleCB;  
2)将pGapCentralRoleCB指向回调函数simpleBLECentralEventCB,也就是注册回调函数。
[cpp] view plain copy
/**
* @brief   Start the device in Central role.  This function is typically
*          called once during system startup.
*
* Public function defined in central.h.
*/  
bStatus_t GAPCentralRole_StartDevice( gapCentralRoleCB_t *pAppCallbacks )  
{  
  if ( pAppCallbacks )  
  {  
    pGapCentralRoleCB = pAppCallbacks;  
  }  
  return GAP_DeviceInit( gapCentralRoleTaskId, GAP_PROFILE_CENTRAL,  
                         gapCentralRoleMaxScanRes, gapCentralRoleIRK,  
                         gapCentralRoleSRK, &gapCentralRoleSignCounter );  
}  
3)调用回调函数
[cpp] view plain copy
// Pass event to app  
if ( pGapCentralRoleCB && pGapCentralRoleCB->eventCB )  
{  
  pGapCentralRoleCB->eventCB( (gapCentralRoleEvent_t *) pMsg );  
}  
注:实际上此时simpleBLECentralEventCB在第二步结束时,即可直接通过操作结构体来调用这个回调函数了。
但是之所以要将结构体中的simpleBLECentralEventCB函数首地址再传给simpleBLECentralEventCB(即第三点的1、2两个步骤),我认为是出于底层的profiles——central分层的考虑。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top