【DWM1000】 code 解密7一ANCHOR接收到BLINK


 

 接着之前ANCHOR的代碼分析,但接收到無線數據,應該執行如下代碼

case TA_RX_WAIT_DATA :   //already recive a message                   // Wait RX data

         //printf("TA_RX_WAIT_DATA %d", message) ;

   switch (message)

    {

           case SIG_RX_BLINK :

           case DWT_SIG_RX_OKAY :

           case DWT_SIG_RX_TIMEOUT :

           case DWT_SIG_TX_AA_DONE:

           case 0:

                      default :

}

因為我們分析TAG時明確知道,此時收到的BLINK,所以應該執行case SIG_RX_BLINK。

那我們看看這個是如何來的? 以后分析~

 

下面是ANCHOR接收到BLINK信號后的動作。

event_data_t* dw_event = instance_getevent(12); //get and clear this event

                    //printf("we got blink message from %08X\n", ( tagaddr& 0xFFFF));

                    if((inst->mode == LISTENER) || (inst->mode == ANCHOR))

                    {

                                                        inst->canprintinfo = 1;

 

                        //add this Tag to the list of Tags we know about

                                                        instaddtagtolist(inst, &(dw_event->msgu.rxblinkmsg.tagID[0]));

 

                        //initiate ranging message

                        if(inst->tagToRangeWith < TAG_LIST_SIZE)

                        {

                            //initiate ranging message this is a Blink from the Tag we would like to range to

                                                                 if(memcmp(&inst->tagList[inst->tagToRangeWith][0],  &(dw_event->msgu.rxblinkmsg.tagID[0]), BLINK_FRAME_SOURCE_ADDRESS) == 0)

                            {

                                inst->tagShortAdd = (dwt_getpartid() & 0xFF);

                                                                           inst->tagShortAdd =  (inst->tagShortAdd << 8) + dw_event->msgu.rxblinkmsg.tagID[0] ;

 

                                                                           //if using longer reply delay time (e.g. if interworking with a PC application)

                                                                           inst->delayedReplyTime = (dw_event->timeStamp + inst->rnginitReplyDelay) >> 8 ;  // time we should send the blink response

 

                                                                           //set destination address

                                                                           memcpy(&inst->rng_initmsg.destAddr[0], &(dw_event->msgu.rxblinkmsg.tagID[0]), BLINK_FRAME_SOURCE_ADDRESS); //remember who to send the reply to

 

                                inst->testAppState = TA_TXE_WAIT;

                                inst->nextState = TA_TXRANGINGINIT_WAIT_SEND ;

 

                                break;

                            }

 

                            //else stay in RX

                        }

                    }

                    //else //not initiating ranging - continue to receive

1 全局變量inst->canprintinfo = 1;,與打印log相關,我們記錄以后查看即可

2 add list, 這個主要功能是將發送blink 信號的TAG加入到自己已知節點list當中。

//add this Tag to the list of Tags we know about

instaddtagtolist(inst, &(dw_event->msgu.rxblinkmsg.tagID[0]));

 

我們先搜一下msgu.rxblinkmsg.tagID 在TAG階段賦值是啥

memcpy(inst->blinkmsg.tagID, inst->eui64, ADDR_BYTE_SIZE_L);

 

TAG雖然是blinkmsg,ANCHOR是rxblinkmsg,兩者應該是一致的,這段是聯想,可以具體看代碼實現,我們這里不看了。 所以msgu.rxblinkmsg.tagID[0]應該保存的是TAG的64位長地址。

 

在instaddtagtolist關鍵代碼就是如下,將64位長地址復制到instance的taglist,這個開始初始化為0,所以現在有了一個非0值了。

  memcpy(&inst->tagList[i][0], &tagAddr[0], 8) ;

 

//initiate ranging message

if(inst->tagToRangeWith < TAG_LIST_SIZE)

我們初始化的時候沒有操作tagToRangeWith,所以是0,而TAG_LIST_SIZE宏定義為1,所以滿足判斷條件。

下面又有一個判斷

if(memcmp(&inst->tagList[inst->tagToRangeWith][0],  &(dw_event->msgu.rxblinkmsg.tagID[0]), BLINK_FRAME_SOURCE_ADDRESS) == 0)

上面我們說了,[inst->tagToRangeWith] 沒有初始化,所以是0,也就是比較inst->tagList[0][0],與剛才接收到blink信號源64位長地址,而inst->tagList[0][0]是我們剛才設定的,所以兩者一致,滿足條件,接着往下走

這個是分配16位短地址,分配方法有點特別,保存到tagShortAdd,后面肯定會發送出去,TAG收到這個后作為自己的短地址。

inst->tagShortAdd = (dwt_getpartid() & 0xFF);

inst->tagShortAdd =  (inst->tagShortAdd << 8) + dw_event->msgu.rxblinkmsg.tagID[0] ;

設置blink 應答時間,先記錄變量delayedReplyTime,看后續怎么用吧

//if using longer reply delay time (e.g. if interworking with a PC application)

inst->delayedReplyTime = (dw_event->timeStamp + inst->rnginitReplyDelay) >> 8 ;  // time we should send the blink response

設定目的地址,因為TAG還沒有短地址,所以必須先用64位長地址

memcpy(&inst->rng_initmsg.destAddr[0], &(dw_event->msgu.rxblinkmsg.tagID[0]), BLINK_FRAME_SOURCE_ADDRESS);

設置兩個重要的變量

inst->testAppState = TA_TXE_WAIT;

inst->nextState = TA_TXRANGINGINIT_WAIT_SEND ;

后面是break,我們看看是否有關於instance->done 的配置

---沒找到,直接返回的是最后return inst->done; 那我們只能查一下之前ANCHOR保存的done了。

找之前的分析,發現done的值是

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT; //using RX FWTO

所以根據之前分析經驗,在instance_run中不會啟動定時器,而回到Main中什么也不做,然后又是instance_run,然后的然后有進入到testapprun_s。

 

根據上次退出情況的重要變量找案發現場

inst->testAppState = TA_TXE_WAIT;

inst->nextState = TA_TXRANGINGINIT_WAIT_SEND ;

 

case TA_TXE_WAIT : //either go to sleep or proceed to TX a message

            // printf("TA_TXE_WAIT") ;

            //if we are scheduled to go to sleep before next sending then sleep first.

            if(((inst->nextState == TA_TXPOLL_WAIT_SEND)

                || (inst->nextState == TA_TXBLINK_WAIT_SEND))

                    && (inst->instToSleep)  //go to sleep before sending the next poll

                    )

            {

 

進入TA_TXE_WAIT后發現if條件不滿足,很多代碼就不用看了。

else //proceed to configuration and transmission of a frame

{

         inst->testAppState = inst->nextState;

         inst->nextState = 0; //clear

}

break ; // end case TA_TXE_WAIT

直接到else 設定重要變量testAppState后break了,done依然沒有設定,好了,重要變量為:

inst->testAppState = TA_TXRANGINGINIT_WAIT_SEND ;

根據上面一樣,轉了一大圈,然后再次回到testapprun_s,依然找案發現場

case TA_TXRANGINGINIT_WAIT_SEND :

     {

          uint16 resp_dly_us, resp_dly;

inst->psduLength = RANGINGINIT_MSG_LEN;

//tell Tag what it's address will be for the ranging exchange

          inst->rng_initmsg.messageData[FCODE] = RTLS_DEMO_MSG_RNG_INIT;

        ……

突然發現這里代碼好多。 基本分一下類別

inst->rng_initmsg 這個是ANCHOR設定回復blink的數據。 分為messageData (數據內容)和frameCtrl(控制部分)以及PANID  panID 和seqNum

dwt_writetxdata(inst->psduLength, (uint8 *)  &inst->rng_initmsg, 0) ;      // write the frame data

將要發送的數據寫到寄存器

instancesendpacket(inst->psduLength, DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED, inst->delayedReplyTime

發送數據。

我們關注在關注幾個變量

// First response delay to send is anchor's response delay.

// Second response delay to send is tag's response delay.

具體內容被放置到發送的數據里,同時發送數據里最開始的兩個字節包含了給TAG分配的短地址, 這兩個reponse delay,我們后期到TAG看。

其它幾個非常重要的變量賦值

inst->wait4ack = DWT_RESPONSE_EXPECTED;

inst->testAppState = TA_TX_WAIT_CONF;

inst->previousState = TA_TXRANGINGINIT_WAIT_SEND ;

我們仔細再看下發送函數

instancesendpacket(inst->psduLength, DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED, inst->delayedReplyTime)

與之對應的函數原型

int instancesendpacket(uint16 length, uint8 txmode, uint32 dtime)

可以看出,這里ANCHOR是想要一個delay tx,具體delay時間為inst->delayedReplyTime,具體為何這樣做,我們暫時不關注,發送數據成功或者失敗后執行不同的代碼,我們假定發送成功。 根據DWM1000代碼的宏定義可以0表示成功,其實這里在instancesendpacket 函數中有一句result = 1; //late/error  也印證我們自覺0成功。

#define DWT_SUCCESS (0)

#define DWT_ERROR   (-1)

發送數據成功后,執行的代碼為

inst->testAppState = TA_TX_WAIT_CONF ;                                               // wait confirmation

inst->previousState = TA_TXRANGINGINIT_WAIT_SEND ;

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT;  //no timeout

//CONFIGURE FIXED PARTS OF RESPONSE MESSAGE FRAME (these won't change)

//program option octet and parameters (not used currently)

inst->msg.messageData[RES_R1] = 0x2; // "activity"

inst->msg.messageData[RES_R2] = 0x0; //

inst->msg.messageData[RES_R3] = 0x0;

setupmacframedata(inst, RTLS_DEMO_MSG_ANCH_RESP);

 

前三句我們比較熟悉是我們案發現場的三個變量。 后面四句好像在組合什么幀的數據,准備下次發送(重要)。 我們簡單看下setupmacframedata

void setupmacframedata(instance_data_t *inst, int fcode)

{

inst->msg.messageData[FCODE] = fcode

//message function code (specifies if message is a poll, response or other...)

         instanceconfigframeheader(inst);

}

我們可以看出,似乎只用到了RTLS_DEMO_MSG_ANCH_RESP ,HEADER部分應該都一樣。在來看下

void instanceconfigframeheader(instance_data_t *inst)

{

    inst->msg.panID[0] = (inst->panid) & 0xff;

    inst->msg.panID[1] = inst->panid >> 8;

 

    //set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)

inst->msg.frameCtrl[0] = 0x1

/*frame type 0x1 == data*/ | 0x40 /*PID comp*/;

#if (USING_64BIT_ADDR==1)

    //source/dest addressing modes and frame version

inst->msg.frameCtrl[1] = 0xC

/*dest extended address (64bits)*/ | 0xC0 /*src extended address (64bits)*/;

#else

inst->msg.frameCtrl[1] = 0x8

 /*dest short address (16bits)*/ | 0x80 /*src short address (16bits)*/;

#endif

}

果然,這里是panid以及幀控制的東西。 我們就看到這里了。

Break后,此時的done是INST_DONE_WAIT_FOR_NEXT_EVENT;也就是沒有定時器了, 繞一圈以后還會進入到testapprun_s,根據上面的兩個重要變量,我們接着分析代碼

inst->testAppState = TA_TX_WAIT_CONF ;                                               // wait confirmation

inst->previousState = TA_TXRANGINGINIT_WAIT_SEND ;

其實我們可以從TA_TX_WAIT_CONF 看出,此時ANCHOR應該等TAG的應答,可能我們分析不了多少東西又得跑到TAG端了

想想前面的分析,這里我們分析過了,看看代碼其實一樣的,接收到應答后狀態機會由TA_TX_WAIT_CONF轉到TA_RXE_WAIT,將接收器打開,等待來自TAG的數據,狀態機進一步交到TA_RX_WAIT_DATA。

 

分析到這里我們簡單總結一下,TAG發送blink,ANCHOR接收到blink 后回復response 一條信息給TAG,其中包含量給TAG分別的短地址以及兩個delay值。 AHCHOR發送完這個回復后,接着打開接收器,等待TAG進一步的回復。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM