【DWM1000】 code 解密3一ANCHOR RUN起來


int done = INST_NOT_DONE_YET; 

#define INST_DONE_WAIT_FOR_NEXT_EVENT       1       //this signifies that the current event has been processed and instance is ready for next one

#define INST_DONE_WAIT_FOR_NEXT_EVENT_TO    2   //this signifies that the current event has been processed and that instance is waiting for next one with a timeout

                                               //which will trigger if no event coming in specified time

#define INST_NOT_DONE_YET                 0      //this signifies that the instance is still processing the current event

 

int message = instance_peekevent(); //get any of the received events from ISR

int instance_peekevent(void)
{

    int instance = 0;

    return instance_data[instance].dwevent[instance_data[instance].dweventPeek].type; //return the type of event that is in front of the queue

}

  第一次運行到這里的時候,instance_data[instance].dweventPeek 為0 ,我們在之前初始化的時候看到的結果

Peek,也就是瞟一眼,看看是否有事件,假定我們這里還米有收到任何事件。 后面我們會看事件的產生,怎么往里面裝,怎么取出。 這里只是簡單的瞟一眼。

while(done == INST_NOT_DONE_YET)
{

      //int state = instance_data[instance].testAppState;

     done = instance_localdata[instance].testapprun_fn(&instance_data[instance], message) ;   // run the communications application

     //we've processed message

      message = 0;

}

 由於進入函數的時候,我們定義了局部變量done 為INST_NOT_DONE_YET,所以至少會執行一下while 循環里面的內容。

done = instance_localdata[instance].testapprun_fn(&instance_data[instance], message) ; 

回憶之前我們code分析如下內容

//應用層函數設定

void instance_setapprun(int (*apprun_fn)(instance_data_t *inst, int message))

{
         int instance = 0 ;
         instance_localdata[instance].testapprun_fn = apprun_fn;
}

  設定這些函數,只是提供入口,此時還不會執行。但是RX TX 回調函數是通過中斷觸發的,設定后可能會立馬執行,這個我們后續看代碼分析。

之前只是賦值,而現在才是真的執行這個函數testapprun_s

testapprun_s &instance_data[instance], message)

傳遞的兩個變量A : instance_data, 也就是我們開始初始化的變量instance

B:message. instance_peekevent()是它的返回值,我們暫且還不能假定是什么東西。

 

那么我們現在看看testapprun_s函數吧。

/ -------------------------------------------------------------------------------------------------------------------

//

// the main instance state machine (all the instance modes Tag, Anchor or Listener use the same statemachine....)

//

// -------------------------------------------------------------------------------------------------------------------

//

int testapprun_s(instance_data_t *inst, int message)
{
    switch (inst->testAppState)
    {
        case TA_INIT :
            // printf("TA_INIT") ;
            switch (inst->mode)
            {
                case TAG:
                {

  

列出一段,對着就是十分糟糕的主要狀態機部分了。

 

在分析這段代碼前,我們需要做一些假定,暫時假定,我們現在分析流程是ANCHOR的,因為這個家伙會先啟動,由於涉及到無線通信數據收發,所以我們會時不時的切換到TAG。

到目前為止,ANCHOR 和TAG 的代碼基本都是一致的。后面狀態機就有區別了。

 

好了,我們假定現在設備是ANCHOR,開始狀態機第一步吧。

   switch (inst->testAppState)
    {
        case TA_INIT :
            // printf("TA_INIT") ;
            switch (inst->mode)
            {
                case TAG:
                {
                ……
                }
                break;
                case ANCHOR:
                {

                    dwt_enableframefilter(DWT_FF_NOTYPE_EN); //disable frame filtering

                    inst->frameFilteringEnabled = 0 ;

                    dwt_seteui(inst->eui64);

                    dwt_setpanid(inst->panid); 

#if (USING_64BIT_ADDR==0)
                    {
                        uint16 addr = inst->eui64[0] + (inst->eui64[1] << 8);
                        dwt_setaddress16(addr);
                        //set source address into the message structure
                         memcpy(&inst->msg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_S);
//set source address into the message structure memcpy(&inst->rng_initmsg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_S); } #else //set source address into the message structure memcpy(&inst->msg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_L); //set source address into the message structure memcpy(&inst->rng_initmsg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_L); #endif // First time anchor listens we don't do a delayed RX dwt_setrxaftertxdelay(0); //change to next state - wait to receive a message inst->testAppState = TA_RXE_WAIT ; dwt_setrxtimeout(0); inst->canprintinfo = 1; } break; case LISTENER: { …… } break ; // end case TA_INIT default: break; } break; // end case TA_INIT

上來case 是根據設備狀態判斷的,沒錯,我們之前初始化的時候見過這個家伙

 INST_STATES testAppState ;             int instance_init_s(int mode) TA_INIT

進去后,會根據不同的角色(TAG ANCHOR LISTENER)執行不同的代碼,先忽略TAG 和 LISTENER的部分,看看ANCHOR做了什么

 dwt_enableframefilter(DWT_FF_NOTYPE_EN); //disable frame filtering
 inst->frameFilteringEnabled = 0 ;

關於幀的控制,感覺這家伙不想接收任何數據,同時對結構體frameFilteringEnabled 賦值為0.

dwt_seteui(inst->eui64);
dwt_setpanid(inst->panid);

  

設置64位地址以及PANIND,我們在初始化的時候做的內容包括這兩個家伙了。

uint8   eui64[8];                                // devices EUI 64-bit address  ????
uint16  panid ;        instance_init 0          xdeca                          // panid used in the frames

可以追進去看看這兩個函數,都是寄存器級別的操作了,我們不追了。dwt_ 開頭的都是寄存器級別的操作。 

宏定義有如下一行內容

#define USING_64BIT_ADDR (1) //when set to 0 - the DecaRanging application will use 16-bit addresses

所以我們就知道執行的東西是

#else
    //set source address into the message structure
    memcpy(&inst->msg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_L);
    //set source address into the message structure
    memcpy(&inst->rng_initmsg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_L);
#endif

好,關於結構體,已知參數又多了兩個msg.sourceAddr[0] 和rng_initmsg.sourceAddr[0]。 這兩個參數都是ANCHOR的長地址。(這兩個參數的值歸ANCHOR所有)

// First time anchor listens we don't do a delayed RX
dwt_setrxaftertxdelay(0);
//change to next state - wait to receive a message
inst->testAppState = TA_RXE_WAIT ;
dwt_setrxtimeout(0);
inst->canprintinfo = 1;

這段代碼中有兩個dwt_ 開頭的函數,我們看注釋就可以了,取消delayed RX設定以及將rxtimeout設置為0. 修改了testAppState = TA_RXE_WAIT,同時canprintinfo 被設置為1

 看到這里突然想到我們testapprun_s 傳入兩個函數,第二message 還沒有用到,確實,對ANCHOR 的TA_INIT 還沒有用到這個參數。

case TA_INIT :
……
Break;

Break 了,我們需要看看  switch (inst->testAppState)之外是否還有代碼。

一直拉到testapprun_s最后,發現只有這個了

    return inst->done;
} // end testapprun()

好吧,我們剛才沒有看inst->done是個什么東西,返回去再看看

仔細在TA_INITàANCHOR 代碼塊找了一圈發現並沒有設置這個inst->done. 好吧,那我們看看之前初始化的時候是否有設置。

  int done ;                                      //done with the current event/wait for next event to arrive

沒有標記,那可能是沒有設置,我們那認為它返回的初始值0. 先這樣吧,第一次嘗試了testapprun_s,我們趕快跳到instance_run(void) 中吧。

while(done == INST_NOT_DONE_YET)
{
     //int state = instance_data[instance].testAppState;
     done = instance_localdata[instance].testapprun_fn(&instance_data[instance], message) ;   // run the communications application
     //we've processed message
      message = 0;
}

我們假定done為0,name看看是否還在while中

#define INST_NOT_DONE_YET               0

 看來很不幸,滿足while 條件,再次執行,再次進入到testapprun_s中。


免責聲明!

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



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