在分析这个部分前,目前我看到DWM1000 的资料,data可以分为blink和一般无线数据,后面有内容我们再扩充, 上面我们已经看到接收到blink触发的事件为

case SIG_RX_BLINK :

一般数据包应该触发的的是

case DWT_SIG_RX_OKAY :

表示接收到一个无线无线数据包,具体怎么解析这个数据包我们一点点分析。

好了,看TAG收到ANCHOR的blink response,这个数据包为一般数据包,具体数据内容我们前面简单列出来了,这里从TAG接收的角度一点点在分析。

好了,还是上代码

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

uint8  srcAddr[8] = {0,0,0,0,0,0,0,0};

int fcode = 0;

int fn_code = 0;

uint8 *messageData;

inst->stoptimer = 0; //clear the flag, as we have received a message

首先是获取事件getevent,这个应该是获取到接收数据成功的事件。后面紧随其后是一下变量的生命。后面看用到这些变量再看。

switch(dw_event->msgu.frame[1])

这个msgu.frame[1] 是啥内容,我们需要回到ANCHOR发送端看了

#if (USING_64BIT_ADDR == 1)

inst->rng_initmsg.frameCtrl[1] = 0xCC;

inst->psduLength += FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;

#else

我们接着摘录具体的代码

case 0xCC: //

memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_ll.sourceAddr[0]), ADDR_BYTE_SIZE_L);

fn_code = dw_event->msgu.rxmsg_ll.messageData[FCODE];

messageData = &dw_event->msgu.rxmsg_ll.messageData[0];

这个决定了我们从不同地方去srcAddr以及fn_code 和messageData。 后面用到这几个变量再看具体是什么内容

if(inst->mode == ANCHOR)

{

……

}

else // LISTENER or TAG

{

fcode = fn_code;

}

接着后面看

switch(fcode)

{

case RTLS_DEMO_MSG_RNG_INIT:

{

原来fcode是这些家伙,我们再看看ANCHOR发送的时候fcode是什么吧

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

正好是第一个case,直接在拉代码看看做了什么,没看代码前,我们根据发送时的数据(短地址以及两个delay)可以大概猜出来,TAG应该是保持这些数据,因为ANCHOR那边还在等着,所以应该还会发一个数据给ANCHOR。

好,上代码

先修改了两个非常重要的变量,我们记一下,等一会还会用到

inst->testAppState = TA_TXE_WAIT;

inst->nextState = TA_TXPOLL_WAIT_SEND ; // send next poll

后面就是从数据包提取短地址和两个delay

inst->tagShortAdd = messageData[RNG_INIT_TAG_SHORT_ADDR_LO]                                                        + (messageData[RNG_INIT_TAG_SHORT_ADDR_HI] << 8) ;

// Get response delays from message and update internal timings accordingly

resp_dly[RESP_DLY_ANC] =  messageData[RNG_INIT_ANC_RESP_DLY_LO]

+ (messageData[RNG_INIT_ANC_RESP_DLY_HI] << 8);

resp_dly[RESP_DLY_TAG] =  messageData[RNG_INIT_TAG_RESP_DLY_LO]

+ (messageData[RNG_INIT_TAG_RESP_DLY_HI] << 8);

其中短地址被保存到结构体instance中,而两个delay目前只保存到临时变量里。

后面两个delay在代码中进行了转换,最终计算出了两个delay保存到instance中了

// Update delay between poll transmission and response reception.

inst->txToRxDelayTag_sy

// Update delay between poll transmission and final transmission.

inst->finalReplyDelay

inst->finalReplyDelay_ms

后面的inst->sleep_en = 0; 我们姑且认为是吧。 接着分析后面的代码

#if (USING_64BIT_ADDR == 1)

memcpy(&inst->msg.destAddr[0], &srcAddr[0], ADDR_BYTE_SIZE_L);

//set the anchor address for the reply (set destination address)

#else

看代码,用的是64bit 地址,前面分析srcAddr其实是源地址

memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_ll.sourceAddr[0]), ADDR_BYTE_SIZE_L);

也就是ANCHOR的地址,我们可以看到执行

memcpy(&inst->msg.destAddr[0], &srcAddr[0], ADDR_BYTE_SIZE_L);

也就是destAddr[0]里面存放的ANCHOR的地址

接着看后面依然有个地址复制,我们先记录先来看看是否有用。

memcpy(&inst->relpyAddress[0], &srcAddr[0], ADDR_BYTE_SIZE_L);

//remember who to send the reply to (set destination address)

后面的代码就是几个变量的赋值了

inst->mode = TAG ;

inst->instToSleep = 0;

inst->instancetimer_saved = inst->instancetimer = portGetTickCount(); //set timer base

然后退出testapprun_s,来回分析ANCHOR 和TAG已经忘记done的状态了,我们暂且认为不需要定时器,所以回很快再次进去testapprun_s。首先列一下重要变量

inst->testAppState = TA_TXE_WAIT;

inst->nextState = TA_TXPOLL_WAIT_SEND ; // send next poll

inst->mode = TAG ;

然后在testapprun_s找案发现场

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

//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

)

{

根据绿色标出的地方,可以看出,满足if判断

//the app should put chip into low power state and wake up in tagSleepTime_ms time...

//the app could go to *_IDLE state and wait for uP to wake it up...

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT_TO;

//don't sleep here but kick off the TagTimeoutTimer (instancetimer)

inst->testAppState = TA_SLEEP_DONE;

if(inst->mode == TAG_TDOA) //once we start ranging we want to display the new range

{

……不满足条件

}

#if (DEEP_SLEEP == 1) 宏定义确实为1

if (inst->sleep_en) 上面我们假定这个参数为0

{

……不满足条件

}

#endif

//DW1000 gone to sleep - report the received range

if(inst->tof > 0) //if ToF == 0 - then no new range to report

{

……

}

后面的tof我们之前也没有遇到过,假定为0,也不满足。绕了一圈,发现其实这次进入到testapprun_s只设置两个两个重要变量

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT_TO;

inst->testAppState = TA_SLEEP_DONE;

根据之前分析,由于是INST_DONE_WAIT_FOR_NEXT_EVENT_TO,在instance_run 会开个定时器。我们认为溢出前会先进入testapprun_s,看看在TA_SLEEP_DONE 做了什么吧。接着找作案现场

case TA_SLEEP_DONE :

{

event_data_t* dw_event = instance_getevent(10); //clear the event from the queue

// waiting for timout from application to wakup IC

if (dw_event->type != DWT_SIG_RX_TIMEOUT)

{

// if no pause and no wake-up timeout continu waiting for the sleep to be done.

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT; //wait here for sleep timeout

break;

}

可以看出如果进来发现不是TIMEOUT,一直break,所以定时器一直需要等待溢出才执行后面的代码。

……等待定时器,等待定时器……溢出。好了,我们看后面的代码

inst->done = INST_NOT_DONE_YET;

inst->instToSleep = 0;

inst->testAppState = inst->nextState;

inst->nextState = 0; //clear

inst->instancetimer_saved = inst->instancetimer = portGetTickCount(); //set timer base

有点尴尬nextState好像好久没用到,没事回头找代码

case RTLS_DEMO_MSG_RNG_INIT:

{

if(inst->mode == TAG_TDOA) //only start ranging with someone if not ranging already

{

uint32 final_reply_delay_us;

uint32 resp_dly[RESP_DLY_NB];

int i;

inst->testAppState = TA_TXE_WAIT;

inst->nextState = TA_TXPOLL_WAIT_SEND ; // send next poll

根据done = INST_NOT_DONE_YET;退出不加载定时器,根据TA_TXPOLL_WAIT_SEND 我们再找作案现场

case TA_TXPOLL_WAIT_SEND :  //TAG:send poll message

{

这里主要是发送poll message给ANCHOR

与发送相关的代码

inst->msg.seqNum = inst->frame_sn++;

setupmacframedata(inst, RTLS_DEMO_MSG_TAG_POLL);

#if (USING_64BIT_ADDR==1)

inst->psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;

#else

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

dwt_writetxfctrl(inst->psduLength, 0);

dwt_starttx(DWT_START_TX_IMMEDIATE | inst->wait4ack);

发送具体数据包在meg中了,我们现在具体不看,ANCHOR用到在看,反正是发送了,而且还是个DWT_RESPONSE_EXPECTED

inst->wait4ack = DWT_RESPONSE_EXPECTED;

还设置了两个延时,tx后多久打开接收器等待应答,以及rx 的timeout

//set the delayed rx on time (the response message will be sent after this delay)

dwt_setrxaftertxdelay(inst->txToRxDelayTag_sy);

dwt_setrxtimeout((uint16)inst->fwtoTime_sy);

发送完poll message等待应答需要转状态,保存重要变量

inst->testAppState = TA_TX_WAIT_CONF ;   // wait confirmation

inst->previousState = TA_TXPOLL_WAIT_SEND ;

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set below)

根据done,知道退出后不需要启动定时器。

之前我们就分析过TA_TX_WAIT_CONF,不过这个函数会根据previousState有很多岔路,我们接着分析它

if(dw_event->type != DWT_SIG_TX_DONE) //wait for TX done confirmation

{

if(dw_event->type == DWT_SIG_RX_TIMEOUT)

{

……没有启动定时器,所以不会执行到这里

}

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT;

break;

}

由这段代码可以看出,TAG一直不停的循环,直到等待DWT_SIG_TX_DONE,也就是DWM1000把数据包发送出去。

inst->done = INST_NOT_DONE_YET;

else

{

inst->txu.txTimeStamp = dw_event->timeStamp;

if(inst->previousState == TA_TXPOLL_WAIT_SEND)

{

可以看出,满足if 判断会接着执行后面的代码,后面很多代码都是计算poll message 发送时间的。

uint64 tagCalculatedFinalTxTime ;

// Embed into Final message: 40-bit pollTXTime,  40-bit respRxTime,  40-bit finalTxTime

tagCalculatedFinalTxTime = (inst->txu.txTimeStamp + inst->finalReplyDelay) & MASK_TXDTS;

// time we should send the response

inst->delayedReplyTime = tagCalculatedFinalTxTime >> 8;

// Calculate Time Final message will be sent and write this field of Final message

// Sending time will be delayedReplyTime, snapped to ~125MHz or ~250MHz boundary by

// zeroing its low 9 bits, and then having the TX antenna delay added

// getting antenna delay from the device and add it to the Calculated TX Time

tagCalculatedFinalTxTime = tagCalculatedFinalTxTime + inst->txantennaDelay;

tagCalculatedFinalTxTime &= MASK_40BIT;

// Write Calculated TX time field of Final message

memcpy(&(inst->msg.messageData[FTXT]), (uint8 *)&tagCalculatedFinalTxTime, 5);

// Write Poll TX time field of Final message

memcpy(&(inst->msg.messageData[PTXT]), (uint8 *)&inst->txu.tagPollTxTime, 5);

这几个时间我们后面在分析,我们先看代码

inst->testAppState = TA_RXE_WAIT ;

message = 0;

//break ; // end case TA_TX_WAIT_CONF

case TA_RXE_WAIT :  //enable rx,and  wait to recive a message

接着会执行TA_RXE_WAIT ,根据之前的分析结果,这里只是打开接收器等到数据,所以到此为止,TAG又开始等待了,等待ANCHOR回复。

总结一下该小段: TAG发送poll message给ANCHOR后进入等待状态,ANCHOR应该此时接收数据并回复TAG。

【DWM1000】 code 解密8一 TAG接收blink response 信号的更多相关文章

  1. 【DWM1000】 code 解密10 一 TAG 发送最后一个消息

    更上面ANCHOR发送信息时的RTLS_DEMO_MSG_ANCH_RESP, 我们很快就可以找到如下代码 case RTLS_DEMO_MSG_ANCH_RESP: { 这里面一部分是设置重要变量, ...

  2. 【DWM1000】 code 解密6一TAG 状态机第一步

    我们前面分析过,不论ANCHOR 还是TAG,前面变量的初始化基本都是一样的,只是状态机必须明确区分不同的设备类型.我们从开始看TAG.由于初始化TAG的 testAppState一样初始化为TA_I ...

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

    接着之前ANCHOR的代码分析,但接收到无线数据,应该执行如下代码 case TA_RX_WAIT_DATA :   //already recive a message                ...

  4. 底层由于接收到操作系统的信号而停止(the inferior stopped because it triggered an exception)

    QT开发内存管理问题: 在linux上提示:底层由于接收到操作系统的信号而停止: 在windows上提示:the inferior stopped because it triggered an ex ...

  5. 【DWM1000】 code 解密2一 工程初始化代码分析

    instance_init 函数追下去,绝大多数的代码都在初始化如下结构体 typedef struct { INST_MODE mode; instance_init -ANCHOR //insta ...

  6. 【DWM1000】 code 解密1一 去掉Main 函数多余内容

    蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: 室内定位兴起,DWM1000 作为超宽带UWB的代表,在国内用的越来越多,但是可见资料非常少. 一方面 ...

  7. 【DWM1000】 code 解密9一 ANCHOR response poll message

    根据上面TAG发送的代码,我直接找到如下代码 case RTLS_DEMO_MSG_TAG_POLL: { if(inst->mode == LISTENER)                  ...

  8. 【DWM1000】 code 解密3一ANCHOR RUN起来

    int done = INST_NOT_DONE_YET; #define INST_DONE_WAIT_FOR_NEXT_EVENT 1 //this signifies that the curr ...

  9. 【DWM1000】 code 解密5一ACHOR 第一次回家Main 函数

    instance_run(); if((instance_data[0].monitor == 1) && ((portGetTickCnt() - instance_data[0]. ...

随机推荐

  1. mysql 去除重复 Select中DISTINCT关键字的用法 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是 distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了很久,用distinct不能解决的话,

      在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记 ...

  2. 关于C++ const 的全面总结 (转)

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类 ...

  3. 集腋成裘-01 sublime常用的快捷键

    sublime使用的快捷键 1:Html 结构代码  : Html:xt + tab键 2:补全标签代码   : tab键 3:快速复制一行代码 : Ctrl+shift+d 4:快速选中一行代码 : ...

  4. 在Ubuntu内制作自己的VOC数据集

    一.VOC数据集的简介 PASCAL VOC为图像的识别和分类提供了一整套标准化的优秀数据集,基本上就是目标检测数据集的模板.现在有VOC2007,VOC2012.主要有20个类.而现在主要的模型评估 ...

  5. paython3-练习

    在文本每行末尾加; f = open(r'D:\test1\1.txt','rb') w = open(r'D:\test1\2.txt','wb') for line in f.readlines( ...

  6. LOCK TABLES 和 UNLOCK TABLES

    MySQLdump的时LOCK TABLES 和 UNLOCK TABLES 在mysqldump后的数据中会发现有 LOCK TABLES tables_name WRITE;和结尾处有 UNLOC ...

  7. MySQL表按月切割

    按月份切割MySQL表数据: 千万级别的数据量也可在毫秒内完成切割操作 注:数据无价请提前自行备份 #!/bin/bash USERNAME=MySQL_user PASSWORD=MySQL_pwd ...

  8. jQuery中的extend()方法

    通常我们使用jquery的extend时,大都是为了实现默认字段的覆盖,即若传入某个字段的值,则使用传入值,否则使用默认值.如下面的代码: function getOpt(option){ var _ ...

  9. [转] 跨域资源共享 CORS 详解

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从 ...

  10. (转载)dotnet core 中文乱码 codepages

    引子 转载自:http://www.jianshu.com/p/1c9c59c5749a 参考:.Net Core 控制台输出中文乱码 上文中我查阅了一些cli的源码, 闲来无事就继续翻代码, 冥冥之 ...