ZStack-CC2530-2.5.1a_0FH_關(guān)于協(xié)議棧下afIncomingMSGPacket_t::timestamp的猜測
首先,在協(xié)議棧中應用層的事件處理函數(shù)都是通過?一個指向接收消息結(jié)構(gòu)體的指針*MSGpkt(afIncomingMSGPacket_t?)來傳遞消息的。在該結(jié)構(gòu)體中有一個參數(shù)timestamp,其描述為:
uint32?timestamp;?????????/*?receipt?timestamp?from?MAC?*/
為了探索在無線數(shù)據(jù)包中這個參數(shù)到底是如何來的?我選擇在整個工程文件中搜索該參數(shù)。然后在搜索結(jié)果中看到一個在AF.c文件中的函數(shù):
/********************************************************************* ?*?@fn??????????afBuildMSGIncoming ?* ?*?@brief???????Build?the?message?for?the?app ?* ?*?@param ?* ?*?@return??????pointer?to?next?in?data?buffer ?*/ static?void?afBuildMSGIncoming(?aps_FrameFormat_t?*aff,?endPointDesc_t?*epDesc, ?????????????????zAddrType_t?*SrcAddress,?uint16?SrcPanId,?NLDE_Signal_t?*sig, ?????????????????uint8?nwkSeqNum,?uint8?SecurityUse,?uint32?timestamp?) { ??afIncomingMSGPacket_t?*MSGpkt; ??const?uint8?len?=?sizeof(?afIncomingMSGPacket_t?)?+?aff->asduLength; ??uint8?*asdu?=?aff->asdu; ??MSGpkt?=?(afIncomingMSGPacket_t?*)osal_msg_allocate(?len?); ??if?(?MSGpkt?==?NULL?) ??{ ????return; ??} ??MSGpkt->hdr.event?=?AF_INCOMING_MSG_CMD; ??MSGpkt->groupId?=?aff->GroupID; ??MSGpkt->clusterId?=?aff->ClusterID; ??afCopyAddress(?&MSGpkt->srcAddr,?SrcAddress?); ??MSGpkt->srcAddr.endPoint?=?aff->SrcEndPoint; ??MSGpkt->endPoint?=?epDesc->endPoint; ??MSGpkt->wasBroadcast?=?aff->wasBroadcast; ??MSGpkt->LinkQuality?=?sig->LinkQuality; ??MSGpkt->correlation?=?sig->correlation; ??MSGpkt->rssi?=?sig->rssi; ??MSGpkt->SecurityUse?=?SecurityUse; ??MSGpkt->timestamp?=?timestamp; ??MSGpkt->nwkSeqNum?=?nwkSeqNum; ??MSGpkt->macDestAddr?=?aff->macDestAddr; ??MSGpkt->srcAddr.panId?=?SrcPanId; ??MSGpkt->cmd.TransSeqNumber?=?0; ??MSGpkt->cmd.DataLength?=?aff->asduLength; ??if?(?MSGpkt->cmd.DataLength?) ??{ ????MSGpkt->cmd.Data?=?(uint8?*)(MSGpkt?+?1); ????osal_memcpy(?MSGpkt->cmd.Data,?asdu,?MSGpkt->cmd.DataLength?); ??} ??else ??{ ????MSGpkt->cmd.Data?=?NULL; ??} #if?defined?(?MT_AF_CB_FUNC?) ??//?If?ZDO?or?SAPI?have?registered?for?this?endpoint,?dont?intercept?it?here ??if?(AFCB_CHECK(CB_ID_AF_DATA_IND,?*(epDesc->task_id))) ??{ ????MT_AfIncomingMsg(?(void?*)MSGpkt?); ????//?Release?the?memory. ????osal_msg_deallocate(?(void?*)MSGpkt?); ??} ??else #endif ??{ ????//?Send?message?through?task?message. ????osal_msg_send(?*(epDesc->task_id),?(uint8?*)MSGpkt?); ??} }
其中可以看到這個函數(shù)是一個為應用層事件處理函數(shù)生成消息的函數(shù)(第35行)。那么我再次在工程文件中搜索該函數(shù),希望能夠找到該函數(shù)的調(diào)用位置。然后發(fā)現(xiàn)其在同位于AF.c文件下的afIncomingData函數(shù)中被調(diào)用:
/********************************************************************* ?*?@fn??????????afIncomingData ?* ?*?@brief???????Transfer?a?data?PDU?(ASDU)?from?the?APS?sub-layer?to?the?AF. ?* ?*?@param???????aff??-?pointer?to?APS?frame?format ?*?@param???????SrcAddress??-?Source?address ?*?@param???????SrcPanId??-?Source?PAN?ID ?*?@param???????sig?-?incoming?message's?link?quality ?*?@param???????nwkSeqNum?-?incoming?network?sequence?number?(from?nwk?header?frame) ?*?@param???????SecurityUse?-?Security?enable/disable ?*?@param???????timestamp?-?the?MAC?Timer2?timestamp?at?Rx. ?* ?*?@return??????none ?*/ void?afIncomingData(?aps_FrameFormat_t?*aff,?zAddrType_t?*SrcAddress,?uint16?SrcPanId, ?????????????????????NLDE_Signal_t?*sig,?uint8?nwkSeqNum,?uint8?SecurityUse,?uint32?timestamp?) { ??endPointDesc_t?*epDesc?=?NULL; ??epList_t?*pList?=?epList; #if?!defined?(?APS_NO_GROUPS?) ??uint8?grpEp?=?APS_GROUPS_EP_NOT_FOUND; #endif ??if?(?((aff->FrmCtrl?&?APS_DELIVERYMODE_MASK)?==?APS_FC_DM_GROUP)?) ??{ #if?!defined?(?APS_NO_GROUPS?) ????//?Find?the?first?endpoint?for?this?group ????grpEp?=?aps_FindGroupForEndpoint(?aff->GroupID,?APS_GROUPS_FIND_FIRST?); ????if?(?grpEp?==?APS_GROUPS_EP_NOT_FOUND?) ??????return;???//?No?endpoint?found ????epDesc?=?afFindEndPointDesc(?grpEp?); ????if?(?epDesc?==?NULL?) ??????return;???//?Endpoint?descriptor?not?found ????pList?=?afFindEndPointDescList(?epDesc->endPoint?); #else ????return;?//?Not?supported #endif ??} ??else?if?(?aff->DstEndPoint?==?AF_BROADCAST_ENDPOINT?) ??{ ????//?Set?the?list ????if?(?pList?!=?NULL?) ????{ ??????epDesc?=?pList->epDesc; ????} ??} ??else?if?(?(epDesc?=?afFindEndPointDesc(?aff->DstEndPoint?))?) ??{ ????pList?=?afFindEndPointDescList(?epDesc->endPoint?); ??} ??while?(?epDesc?) ??{ ????uint16?epProfileID?=?0xFFFF;??//?Invalid?Profile?ID ????if?(?pList->pfnDescCB?) ????{ ??????uint16?*pID?=?(uint16?*)(pList->pfnDescCB( ?????????????????????????????????AF_DESCRIPTOR_PROFILE_ID,?epDesc->endPoint?)); ??????if?(?pID?) ??????{ ????????epProfileID?=?*pID; ????????osal_mem_free(?pID?); ??????} ????} ????else?if?(?epDesc->simpleDesc?) ????{ ??????epProfileID?=?epDesc->simpleDesc->AppProfId; ????} ????if?(?(aff->ProfileID?==?epProfileID)?|| ?????????((epDesc->endPoint?==?ZDO_EP)?&&?(aff->ProfileID?==?ZDO_PROFILE_ID))?) ????{ ??????{ ????????//?Save?original?endpoint ????????uint8?endpoint?=?aff->DstEndPoint; ????????//?overwrite?with?descriptor's?endpoint ????????aff->DstEndPoint?=?epDesc->endPoint; ????????afBuildMSGIncoming(?aff,?epDesc,?SrcAddress,?SrcPanId,?sig, ???????????????????????????nwkSeqNum,?SecurityUse,?timestamp?); ????????//?Restore?with?original?endpoint ????????aff->DstEndPoint?=?endpoint; ??????} ????} ????if?(?((aff->FrmCtrl?&?APS_DELIVERYMODE_MASK)?==?APS_FC_DM_GROUP)?) ????{ #if?!defined?(?APS_NO_GROUPS?) ??????//?Find?the?next?endpoint?for?this?group ??????grpEp?=?aps_FindGroupForEndpoint(?aff->GroupID,?grpEp?); ??????if?(?grpEp?==?APS_GROUPS_EP_NOT_FOUND?) ????????return;???//?No?endpoint?found ??????epDesc?=?afFindEndPointDesc(?grpEp?); ??????if?(?epDesc?==?NULL?) ????????return;???//?Endpoint?descriptor?not?found ??????pList?=?afFindEndPointDescList(?epDesc->endPoint?); #else ??????return; #endif ????} ????else?if?(?aff->DstEndPoint?==?AF_BROADCAST_ENDPOINT?) ????{ ??????pList?=?pList->nextDesc; ??????if?(?pList?) ????????epDesc?=?pList->epDesc; ??????else ????????epDesc?=?NULL; ????} ????else ??????epDesc?=?NULL; ??} }
在參數(shù)描述那里顯示timestamp是Rx時的MAC時間(第12行、第84行)。那么,我開始探索afIncomingData函數(shù)在什么位置被調(diào)用,采用同樣的搜索方法,然后發(fā)現(xiàn)其調(diào)用的位置被封裝了,搜索不到。但是根據(jù)這個參數(shù)的表述,我們知道這個參數(shù)是Rx時的MAC時間。所以我在工程文件中找到了一個名叫mac_rx.c的文件,我有一種這個參數(shù)將在這得到其來由的預感。首先,我們看一下這個mac_rx.c文件中包含的.h頭文件mac_rx.h:
MAC_INTERNAL_API?void?macRxInit(void); MAC_INTERNAL_API?void?macRxRadioPowerUpInit(void); MAC_INTERNAL_API?void?macRxTxReset(void); MAC_INTERNAL_API?void?macRxHaltCleanup(void); MAC_INTERNAL_API?void?macRxThresholdIsr(void); MAC_INTERNAL_API?void?macRxFifoOverflowIsr(void); MAC_INTERNAL_API?void?macRxAckTxDoneCallback(void);
對于這個頭文件還是有點不明白,然后再去看mac_rx.c文件,從其中一個函數(shù)的函數(shù)描述,我判斷這個函數(shù)可能就是和我們當前目的相近的函數(shù):
/*================================================================================================= ?*?@fn??????????rxStartIsr ?* ?*?@brief???????First?ISR?state?for?receiving?a?packet?-?compute?packet?length,?allocate ?*??????????????buffer,?initialize?buffer.??Acknowledgements?are?handled?immediately?without ?*??????????????allocating?a?buffer. ?* ?*?@param???????none ?* ?*?@return??????none ?*================================================================================================= ?*/ static?void?rxStartIsr(void) { ??uint8??addrLen; ??uint8??ackWithPending; ??uint8??dstAddrMode; ??uint8??srcAddrMode; ??uint8??mhrLen?=?0; ??MAC_ASSERT(!macRxActive);?/*?receive?on?top?of?receive?*/ ??/*?indicate?rx?is?active?*/ ??macRxActive?=?MAC_RX_ACTIVE_STARTED; ??/* ???*??For?bullet?proof?functionality,?need?to?see?if?the?receiver?was?just?turned?off. ???*??The?logic?to?request?turning?off?the?receiver,?disables?interrupts?and?then?checks ???*??the?value?of?macRxActive.??If?it?is?TRUE,?the?receiver?will?not?be?turned?off. ???* ???*??There?is?a?small?hole?though.??It's?possible?to?attempt?turning?off?the?receiver ???*??in?the?window?from?when?the?receive?interrupt?fires?and?the?point?where?macRxActive ???*??is?set?to?TRUE.??To?plug?this?hole,?the?on/off?status?must?be?tested?*after* ???*??macRxActive?has?been?set.??If?the?receiver?is?off?at?this?point,?there?is?nothing ???*??in?the?RX?fifo?and?the?receive?is?simply?aborted. ???* ???*??Also,?there?are?some?considerations?in?case?a?hard?disable?just?happened.??Usually, ???*??the?receiver?will?just?be?off?at?this?point?after?a?hard?disable.??The?check?described ???*??above?will?account?for?this?case?too.??However,?if?a?hard?disable?were?immediately ???*??followed?by?an?enable,?the?receiver?would?be?on.??To?catch?this?case,?the?receive ???*??FIFO?is?also?tested?to?see?if?it?is?empty.??Recovery?is?identical?to?the?other?cases. ???*/ ??if?(!macRxOnFlag?||?MAC_RADIO_RX_FIFO_IS_EMPTY()) ??{ ????/*?reset?active?flag?*/ ????macRxActive?=?MAC_RX_ACTIVE_NO_ACTIVITY; ????/* ?????*??To?be?absolutely?bulletproof,?must?make?sure?no?transmit?queue'ed?up?during ?????*??the?tiny,?tiny?window?when?macRxActive?was?not?zero. ?????*/ ????rxPostRxUpdates(); ????/*?return?immediately?from?here?*/ ????return; ??} ??/* ???*??If?interrupts?are?held?off?for?too?long?it's?possible?the?previous?"transmit?done" ???*??callback?is?pending.??If?this?is?the?case,?it?needs?to?be?completed?before ???*??continuing?with?the?receive?logic. ???*/ ??MAC_RADIO_FORCE_TX_DONE_IF_PENDING(); ??/* ???*??It's?possible?receive?logic?is?still?waiting?for?confirmation?of?an?ACK?that?went?out ???*??for?the?previous?receive.??This?is?OK?but?the?callback?needs?to?be?canceled?at?this?point. ???*??That?callback?execute?receive?cleanup?logic?that?will?run?at?the?completion ???*??of?*this*?receive.??Also,?it?is?important?the?flag?for?the?outgoing?ACK?to?be?cleared. ???*/ ??MAC_RADIO_CANCEL_ACK_TX_DONE_CALLBACK(); ??macRxOutgoingAckFlag?=?0; ??/* ???*??Make?a?module-local?copy?of?macRxFilter.??This?prevents?the?selected ???*??filter?from?changing?in?the?middle?of?a?receive. ???*/ ??rxFilter?=?macRxFilter; ??/*------------------------------------------------------------------------------- ???*??Read?initial?frame?information?from?FIFO. ???* ???*???This?code?is?not?triggered?until?the?following?are?in?the?RX?FIFO: ???*?????frame?length??????????-?one?byte?containing?length?of?MAC?frame?(excludes?this?field) ???*?????frame?control?field???-?two?bytes?defining?frame?type,?addressing?fields,?control?flags ???*?????sequence?number???????-?one?byte?unique?sequence?identifier ???*?????additional?two?bytes??-?these?bytes?are?available?in?case?the?received?frame?is?an?ACK, ???*?????????????????????????????if?so,?the?frame?can?be?verified?and?responded?to?immediately, ???*?????????????????????????????if?not?an?ACK,?these?bytes?will?be?processed?normally ???*/ ??/*?read?frame?length,?frame?control?field,?and?sequence?number?from?FIFO?*/ ??MAC_RADIO_READ_RX_FIFO(rxBuf,?MAC_PHY_PHR_LEN?+?MAC_FCF_FIELD_LEN?+?MAC_SEQ_NUM_FIELD_LEN); ??/*?bytes?to?read?from?FIFO?equals?frame?length?minus?length?of?MHR?fields?just?read?from?FIFO?*/ ??rxUnreadLen?=?(rxBuf[0]?&?PHY_PACKET_SIZE_MASK)?-?MAC_FCF_FIELD_LEN?-?MAC_SEQ_NUM_FIELD_LEN; ??/* ???*??Workaround?for?chip?bug?#1547.??The?receive?buffer?can?sometimes?be?corrupted?by?hardware. ???*??This?usually?occurs?under?heavy?traffic.??If?a?corrupted?receive?buffer?is?detected ???*??the?entire?receive?buffer?is?flushed. ???* ???*??In?the?case?that?this?workaround?is?not?needed,?an?assert?is?used?to?make?sure?the ???*??receive?length?field?is?not?corrupted.??This?is?important?because?a?corrupted?receive ???*??length?field?is?utterly?fatal?and,?if?not?caught?here,?extremely?hard?to?track?down. ???*/ ??if?(macChipVersion?==?REV_A) ??{ ????if?((rxUnreadLen?>?(MAC_A_MAX_PHY_PACKET_SIZE?-?MAC_FCF_FIELD_LEN?-?MAC_SEQ_NUM_FIELD_LEN))?|| ????????(MAC_FRAME_TYPE(&rxBuf[1])?>?MAC_FRAME_TYPE_MAX_VALID)) ????{ ??????MAC_RADIO_FLUSH_RX_FIFO(); ??????rxDone(); ??????return; ????} ??} ??else ??{ ????/*?radio?supplied?a?corrupted?receive?buffer?length?*/ ????MAC_ASSERT(rxUnreadLen??rxUnreadLen) ??{ ????/*?discard?frame?and?exit?*/ ????rxDiscardFrame(); ????return; ??} ??/*?aux?security?header?plus?payload?length?is?equal?to?unread?bytes?minus ???*?address?length,?minus?the?FCS ???*/ ??rxPayloadLen?=?rxUnreadLen?-?addrLen?-?MAC_FCS_FIELD_LEN; ??/*------------------------------------------------------------------------------- ???*??Allocate?memory?for?the?incoming?frame. ???*/ ??if?(MAC_SEC_ENABLED(&rxBuf[1])) ??{ ????/*?increase?the?allocation?size?of?MAC?header?for?security?*/ ????mhrLen?=?MAC_MHR_LEN; ??} ??pRxBuf?=?(macRx_t?*)?MEM_ALLOC(sizeof(macRx_t)?+?mhrLen?+?rxPayloadLen); ??if?(pRxBuf?==?NULL) ??{ ????/*?Cancel?the?outgoing?TX?ACK?*/ ????MAC_RADIO_CANCEL_TX_ACK(); ????/*?buffer?allocation?failed,?discard?the?frame?and?exit*/ ????rxDiscardFrame(); ????return; ??} ??/*------------------------------------------------------------------------------- ???*??Set?up?to?process?ACK?request.??Do?not?ACK?if?in?promiscuous?mode. ???*/ ??ackWithPending?=?0; ??if?(!rxPromiscuousMode) ??{ ????macRxOutgoingAckFlag?=?MAC_ACK_REQUEST(&rxBuf[1]); ??} ??/*------------------------------------------------------------------------------- ???*??Process?any?ACK?request. ???*/ ??if?(macRxOutgoingAckFlag) ??{ ????halIntState_t??s; ????/* ?????*??This?critical?section?ensures?that?the?callback?ISR?is?initiated?within?time ?????*??to?guarantee?correlation?with?the?strobe. ?????*/ ????HAL_ENTER_CRITICAL_SECTION(s); ????/*?Do?not?ack?data?packet?with?pending?more?data?*/ ????if(?MAC_FRAME_TYPE(&rxBuf[1])?==?MAC_FRAME_TYPE_COMMAND?) ????{ ??????if(?macRxCheckMACPendingCallback()) ??????{ ????????/*?Check?is?any?mac?data?pending?for?end?devices?*/ ????????ackWithPending?=?MAC_RX_FLAG_ACK_PENDING; ??????} ??????else ??????{ ????????if(?macSrcMatchIsEnabled?) ????????{ ??????????/*?When?autopend?is?enabled,?check?if?allpending?is?set?to?true?*/ ??????????if(?MAC_SrcMatchCheckAllPending()?==?MAC_AUTOACK_PENDING_ALL_ON?) ??????????{ ????????????ackWithPending?=?MAC_RX_FLAG_ACK_PENDING; ??????????} ????????} ????????else ????????{ ??????????/*?When?autopend?is?disabled,?check?the?application?pending?callback?*/ ??????????if(?macRxCheckPendingCallback()?) ??????????{ ????????????ackWithPending?=?MAC_RX_FLAG_ACK_PENDING; ??????????} ????????} ??????} ????} ????if(?ackWithPending?==?MAC_RX_FLAG_ACK_PENDING?) ????{ ??????MAC_RADIO_TX_ACK_PEND(); ????} ????else ????{ ??????MAC_RADIO_TX_ACK(); ????} ????/*?request?a?callback?to?macRxAckTxDoneCallback()?when?the?ACK?transmit?has?finished?*/ ????MAC_RADIO_REQUEST_ACK_TX_DONE_CALLBACK(); ????HAL_EXIT_CRITICAL_SECTION(s); ??} ?/*------------------------------------------------------------------------------- ??*??Populate?the?receive?buffer?going?up?to?high-level. ??*/ ??/*?configure?the?payload?buffer ???*?save?MAC?header?pointer?regardless?of?security?status. ???*/ ??pRxBuf->mhr.p???=?pRxBuf->msdu.p???=?(uint8?*)?(pRxBuf?+?1); ??pRxBuf->mhr.len?=?pRxBuf->msdu.len?=??rxPayloadLen; ??if?(MAC_SEC_ENABLED(&rxBuf[1])) ??{ ????/*?Copy?FCF?and?sequence?number?to?RX?buffer?*/ ????pRxBuf->mhr.len?=?MAC_FCF_FIELD_LEN?+?MAC_SEQ_NUM_FIELD_LEN; ????osal_memcpy(pRxBuf->mhr.p,?&rxBuf[1],?pRxBuf->mhr.len); ????pRxBuf->mhr.p?+=?pRxBuf->mhr.len; ??} ??/*?set?internal?values?*/ ??pRxBuf->mac.srcAddr.addrMode??=?srcAddrMode; ??pRxBuf->mac.dstAddr.addrMode??=?dstAddrMode; ??pRxBuf->mac.timestamp?????????=?MAC_RADIO_BACKOFF_CAPTURE(); ??pRxBuf->mac.timestamp2????????=?MAC_RADIO_TIMER_CAPTURE(); ??pRxBuf->internal.frameType????=?MAC_FRAME_TYPE(&rxBuf[1]); ??pRxBuf->mac.dsn???????????????=?MAC_SEQ_NUMBER(&rxBuf[1]); ??pRxBuf->internal.flags????????=?INTERNAL_FCF_FLAGS(&rxBuf[1])?|?ackWithPending; ??/*------------------------------------------------------------------------------- ???*??If?the?processing?the?addressing?fields?does?not?require?more?bytes?from ???*??the?FIFO?go?directly?address?processing?function.??Otherwise,?configure ???*??interrupt?to?jump?there?once?bytes?are?received. ???*/ ??if?(addrLen?==?0) ??{ ????/*?no?addressing?fields?to?read,?prepare?for?payload?interrupts?*/ ????pFuncRxState?=?&rxPayloadIsr; ????rxPrepPayload(); ??} ??else ??{ ????/*?need?to?read?and?process?addressing?fields,?prepare?for?address?interrupt?*/ ????rxNextLen?=?addrLen; ????if?(MAC_SEC_ENABLED(&rxBuf[1])) ????{ ??????/*?When?security?is?enabled,?read?off?security?control?field?as?well?*/ ??????MAC_RADIO_SET_RX_THRESHOLD(rxNextLen?+?MAC_SEC_CONTROL_FIELD_LEN); ????} ????else ????{ ??????MAC_RADIO_SET_RX_THRESHOLD(rxNextLen); ????} ????pFuncRxState?=?&rxAddrIsr; ??} }
這個函數(shù)特別長,也特別復雜,但是我們從其中標紅的這段代碼和其描述可以知道,這段代碼的作用是接受到從硬件電路通過ISA層上傳至更高層的無線數(shù)據(jù)包(第292行,第369行至395行,特別是第390行和391行)。那么我們對
pRxBuf進行分析,我們發(fā)現(xiàn)該參數(shù)在該文件中被聲明:
static?macRx_t??*?pRxBuf;
/*?Structure?for?internal?data?rx?*/ typedef?struct { ??macEventHdr_t?????hdr; ??sData_t???????????msdu; ??macRxIntData_t????internal; ??macSec_t??????????sec; ??macDataInd_t??????mac; ??sData_t???????????mhr; }?macRx_t;
然后這個參數(shù)在該函數(shù)被分配地址,并對其進行賦值。對于macDataInd_t有如下定義:
/*?Data?indication?parameters?type?*/ typedef?struct { ??sAddr_t???srcAddr;??????????/*?The?address?of?the?sending?device?*/ ??sAddr_t???dstAddr;??????????/*?The?address?of?the?destination?device?*/ ??uint32????timestamp;????????/*?The?time,?in?backoffs,?at?which?the?data?were?received?*/ ??uint16????timestamp2;???????/*?The?time,?in?internal?MAC?timer?units,?at?which?the ?????????????????????????????????data?were?received?*/ ??uint16????srcPanId;?????????/*?The?PAN?ID?of?the?sending?device?*/ ??uint16????dstPanId;?????????/*?The?PAN?ID?of?the?destination?device?*/ ??uint8?????mpduLinkQuality;??/*?The?link?quality?of?the?received?data?frame?*/ ??uint8?????correlation;??????/*?The?raw?correlation?value?of?the?received?data?frame?*/ ??int8??????rssi;?????????????/*?The?received?RF?power?in?units?dBm?*/ ??uint8?????dsn;??????????????/*?The?data?sequence?number?of?the?received?frame?*/ }?macDataInd_t;
該定義后的注釋告訴我們timestamp是收到數(shù)據(jù)時的回退(補償)時間,而timestamp是收到數(shù)據(jù)時的內(nèi)部定時器timer的值。通過對其賦值函數(shù)進行查詢:
#define?MAC_RADIO_BACKOFF_CAPTURE()???????????????????macMcuOverflowCapture() #define?MAC_RADIO_TIMER_CAPTURE()?????????????????????macMcuTimerCapture()
其中macMcuTimerCapture()函數(shù)是對系統(tǒng)時鐘timer2的16位定時器數(shù)值的讀?。?/p>
/************************************************************************************************** ?*?@fn??????????macMcuTimerCapture ?* ?*?@brief???????Returns?the?last?timer?capture.??This?capture?should?have?occurred?at?the ?*??????????????receive?time?of?the?last?frame?(the?last?time?SFD?transitioned?to?active). ?* ?*?@param???????none ?* ?*?@return??????last?capture?of?hardware?timer?(full?16-bit?value) ?************************************************************************************************** ?*/ MAC_INTERNAL_API?uint16?macMcuTimerCapture(void) { ??uint16?????????timerCapture; ??halIntState_t??s; ??HAL_ENTER_CRITICAL_SECTION(s); ??MAC_MCU_T2_ACCESS_CAPTURE_VALUE(); ??timerCapture?=?T2M1?<<?8; ??timerCapture?|=?T2M0; ??HAL_EXIT_CRITICAL_SECTION(s); ??return?(timerCapture); }
而macMucOverflowCapture()則是對定時器timer2的溢出計數(shù)器的捕獲:
/************************************************************************************************** ?*?@fn??????????macMcuOverflowCapture ?* ?*?@brief???????Returns?the?last?capture?of?the?overflow?counter.??A?special?hardware?feature ?*??????????????captures?the?overflow?counter?when?the?regular?hardware?timer?is?captured. ?* ?*?@param???????none ?* ?*?@return??????last?capture?of?overflow?count ?************************************************************************************************** ?*/ MAC_INTERNAL_API?uint32?macMcuOverflowCapture(void) { ??uint32?????????overflowCapture; ??halIntState_t??s; ??/*?for?efficiency,?the?32-bit?value?is?encoded?using?endian?abstracted?indexing?*/ ??HAL_ENTER_CRITICAL_SECTION(s); ??MAC_MCU_T2_ACCESS_OVF_CAPTURE_VALUE(); ??((uint8?*)&overflowCapture)[UINT32_NDX0]?=?T2MOVF0; ??((uint8?*)&overflowCapture)[UINT32_NDX1]?=?T2MOVF1; ??((uint8?*)&overflowCapture)[UINT32_NDX2]?=?T2MOVF2; ??((uint8?*)&overflowCapture)[UINT32_NDX3]?=?0; ??HAL_EXIT_CRITICAL_SECTION(s); ??return?(overflowCapture); }
到目前,我們可以猜測這個afIncomingMSGPacket_t::timestamp是接受到數(shù)據(jù)包的時候系統(tǒng)定時器Timer2的溢出計數(shù)器的值。但這個我們也沒有辦法確認,那么我選擇去看一看mac_tx.c和mac_tx.h文件,看在其中能否找到一些信息,對于mac_tx.h文件中對函數(shù)的聲明:
MAC_INTERNAL_API?void?macTxInit(void); MAC_INTERNAL_API?void?macTxHaltCleanup(void); MAC_INTERNAL_API?void?macTxStartQueuedFrame(void); MAC_INTERNAL_API?void?macTxChannelBusyCallback(void); MAC_INTERNAL_API?void?macTxDoneCallback(void); MAC_INTERNAL_API?void?macTxAckReceivedCallback(uint8?seqn,?uint8?pendingFlag); MAC_INTERNAL_API?void?macTxAckNotReceivedCallback(void); MAC_INTERNAL_API?void?macTxTimestampCallback(void); MAC_INTERNAL_API?void?macTxCollisionWithRxCallback(void);
我們對mac_tx.c文件中的函數(shù)作用有了一定的了解,然后我們?nèi)タ磎ac_tx.c文件。當然我們的查看重點在于發(fā)送數(shù)據(jù)包的構(gòu)建,對于該函數(shù)中有關(guān)timestamp的只有如下函數(shù):
/************************************************************************************************** ?*?@fn??????????macTxTimestampCallback ?* ?*?@brief???????This?callback?function?records?the?timestamp?into?the?receive?data?structure. ?*??????????????It?should?be?called?as?soon?as?possible?after?there?is?a?valid?timestamp. ?* ?*?@param???????none ?* ?*?@return??????none ?************************************************************************************************** ?*/ MAC_INTERNAL_API?void?macTxTimestampCallback(void) { ??MAC_ASSERT(pMacDataTx?!=?NULL);?/*?transmit?structure?must?be?there?*/ ??pMacDataTx->internal.timestamp??=?macBackoffTimerCapture(); ??pMacDataTx->internal.timestamp2?=?MAC_RADIO_TIMER_CAPTURE(); }
這個函數(shù)的描述是“該回調(diào)函數(shù)記錄時間戳到接受數(shù)據(jù)結(jié)構(gòu)中”。到這我們可以非常清楚的知道afIncomingMSGPacket_t::timestamp是發(fā)送/接受數(shù)據(jù)包時系統(tǒng)定時器的溢出計數(shù)器的值。至于這個值到底是發(fā)送者的溢出計數(shù)器的值還是接受者的溢出計數(shù)器的值,我個人比較傾向于只是接受者接受到數(shù)據(jù)包時其系統(tǒng)定時器溢出計數(shù)器的值。我們可以通過發(fā)包含macMcuOverflowCapture()數(shù)據(jù)的數(shù)據(jù)包,然后在接受者接收時將3個數(shù)據(jù)顯示出來查看。