• 【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 ", ( 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进一步的回复。

    博客讨论一些室内定位(DWM1000/CC2431/CC2530) 以及一些随性的技术。博文可以转载,但需要注明出处!
  • 相关阅读:
    16-hadoop-mapreduce简介
    centos7-windows10 双系统安装
    5.4 RDD编程---综合案例
    8.2 数据结构---字符串(查找)
    8.1 数据结构---字符串
    5.3 RDD编程---数据读写
    5.2 RDD编程---键值对RDD
    5.1 RDD编程
    4.Spark环境搭建和使用方法
    3.3 Spark的部署和应用方式
  • 原文地址:https://www.cnblogs.com/tuzhuke/p/7719425.html
Copyright © 2020-2023  润新知