www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 芯聞號 > 充電吧
[導讀]首先,在協(xié)議棧中應用層的事件處理函數(shù)都是通過?一個指向接收消息結(jié)構(gòu)體的指針*MSGpkt(afIncomingMSGPacket_t?)來傳遞消息的。在該結(jié)構(gòu)體中有一個參數(shù)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ù)顯示出來查看。






本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉