1. 程式人生 > >關於ZStack-CC2530-2.3.0-1.4.0中simpleApp例子的 終端節點如何向協調器傳送資料,以及資料的接收

關於ZStack-CC2530-2.3.0-1.4.0中simpleApp例子的 終端節點如何向協調器傳送資料,以及資料的接收

上一篇文章寫到終端節點嚮應用層傳送繫結確認,即zb_BindConfirm函式,我們可以看下原始碼。

void zb_BindConfirm( uint16 commandId, uint8 status )
{
  (void)commandId;

  if ( ( status == ZB_SUCCESS )&& ( myAppState == APP_START ) )//條件成立
  {
    myAppState =APP_BOUND;//將應用狀態修改為 繫結狀態

    //Startreporting sensor values
   myApp_StartReporting();//開始傳輸函式
  }
  else
  {
    // Continueto discover a collector
   osal_start_timerEx( sapi_TaskID, MY_FIND_COLLECTOR_EVT,myBindRetryDelay );
  }

檢視傳輸函式原始碼:

void myApp_StartReporting( void )
{
  osal_start_timerEx( sapi_TaskID,MY_REPORT_TEMP_EVT, myTempReportPeriod );//傳輸溫度事件
  osal_start_timerEx( sapi_TaskID,MY_REPORT_BATT_EVT, myBatteryCheckPeriod );//傳輸電壓事件
  HalLedSet( HAL_LED_1, HAL_LED_MODE_ON);//點亮LED_1;

}

我們看終端節點sapi層如何處理這兩個時間,首先找到SAPI_ProcessEvent函式中的:

 if ( events & ( ZB_USER_EVENTS) )
  {
    // Userevents are passed to the application
#if ( SAPI_CB_FUNC )
   zb_HandleOsalEvent( events );//事件處理函式
#endif

    // Do notreturn here, return 0 later
  }

進入到函式中去:

void zb_HandleOsalEvent( uint16 event )
{
  uint8 pData[2];

  if ( event & MY_START_EVT)
  {
   zb_StartRequest();
  }
  if ( event & MY_REPORT_TEMP_EVT)
  {
    // Read andreport temperature value
    pData[0] =TEMP_REPORT;//要傳送的資料的型別
    pData[1]=  myApp_ReadTemperature();//利用此函式接收讀取的溫度值
   zb_SendDataRequest( 0xFFFE, SENSOR_REPORT_CMD_ID, 2, pData, 0,AF_ACK_REQUEST, 0 );//傳送資料
   osal_start_timerEx( sapi_TaskID, MY_REPORT_TEMP_EVT,myTempReportPeriod );
  }

  if ( event &MY_REPORT_BATT_EVT )
  {
    // Readbattery value
    // Ifbattery level low, report battery value
    pData[0] =BATTERY_REPORT;//要傳送的資料的型別
    pData[1]=  myApp_ReadBattery();//利用此函式接收讀取的溫度值
   zb_SendDataRequest( 0xFFFE, SENSOR_REPORT_CMD_ID, 2, pData, 0,AF_ACK_REQUEST, 0 );//傳送資料
   osal_start_timerEx( sapi_TaskID, MY_REPORT_BATT_EVT,myBatteryCheckPeriod );
  }

  if ( event &MY_FIND_COLLECTOR_EVT )
  {
    // Find andbind to a collector device
   zb_BindDevice( TRUE, SENSOR_REPORT_CMD_ID, (uint8 *)NULL );
  }

}

好,然後我們看下協調器是怎麼接收資料的,首先切換工作空間為協調器模式,檢視sapi.c檔案,檢視SAPI_ProcessEvent函式,找到:

case AF_INCOMING_MSG_CMD:
         pMSGpkt = (afIncomingMSGPacket_t *) pMsg;
         SAPI_ReceiveDataIndication(pMSGpkt->srcAddr.addr.shortAddr,pMSGpkt->clusterId,
                                   pMSGpkt->cmd.DataLength,pMSGpkt->cmd.Data);//協調器在此函式中進行資料的接收工作。
         break;

檢視此函式:

void SAPI_ReceiveDataIndication( uint16 source, uint16 command,uint16 len, uint8 *pData  )
{
#if defined ( MT_SAPI_CB_FUNC )
 
  if ( SAPICB_CHECK( SPI_CB_SAPI_RCV_DATA_IND ))
  {
   zb_MTCallbackReceiveDataIndication( source, command, len,pData  );
  }
  else
#endif  //MT_SAPI_CB_FUNC
  {
#if ( SAPI_CB_FUNC )//編譯通過
   zb_ReceiveDataIndication( source, command, len,pData  );
#endif
  }
}

檢視原始碼:

oid zb_FindDeviceConfirm( uint8 searchType, uint8 *searchKey,uint8 *result )
{
}

CONST uint8 strDevice[] = "Device:0x";
CONST uint8 strTemp[] = "Temp: ";
CONST uint8 strBattery[] = "Battery: ";
void zb_ReceiveDataIndication( uint16 source, uint16 command,uint16 len, uint8 *pData  )
{
  uint8 buf[32];
  uint8 *pBuf;
  uint8 tmpLen;
  uint8 sensorReading;

  if (command ==SENSOR_REPORT_CMD_ID)//條件成立
  {
    // Receivedreport from a sensor
   sensorReading = pData[1];

    // Iftool available, write to serial port

    tmpLen =(uint8)osal_strlen( (char*)strDevice );
    pBuf =osal_memcpy( buf, strDevice, tmpLen );
    _ltoa(source, pBuf, 16 );
    pBuf +=4;
    *pBuf++ = '';

    if (pData[0] == BATTERY_REPORT )//如果是電壓傳送,執行下面函式
    {
     tmpLen = (uint8)osal_strlen( (char*)strBattery );
     pBuf = osal_memcpy( pBuf, strBattery, tmpLen );

     *pBuf++ = (sensorReading / 10 ) +'0';    //convent msb to ascii
     *pBuf++ ='.';                           // decimal point ( battery reading is in units of 0.1 V
     *pBuf++ = (sensorReading % 10 ) +'0';    //convert lsb to ascii
     *pBuf++ = ' ';
     *pBuf++ = 'V';
    }
   else//如果是溫度傳送,執行下面函式
    {
     tmpLen = (uint8)osal_strlen( (char*)strTemp );
     pBuf = osal_memcpy( pBuf, strTemp, tmpLen );

     *pBuf++ = (sensorReading / 10 ) +'0';    //convent msb to ascii
     *pBuf++ = (sensorReading % 10 ) +'0';    //convert lsb to ascii
     *pBuf++ = ' ';
     *pBuf++ = 'C';
    }

    *pBuf++ ='\r';
    *pBuf++ ='\n';
    *pBuf ='\0';

#if defined( MT_TASK)//若定義了MT_TASK ,則執行下面函式即串列埠函式,傳送到PC機上顯示。
    debug_str((uint8 *)buf );
#endif

    // canalso write directly to uart

  }
}

到此為止,終端節點向協調器傳送資料,協調器接收資料併發送到串列埠 

完成。。。