在分析这个部分前,目前我看到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. 论文阅读笔记三十五:R-FCN:Object Detection via Region-based Fully Convolutional Networks(CVPR2016)

    论文源址:https://arxiv.org/abs/1605.06409 开源代码:https://github.com/PureDiors/pytorch_RFCN 摘要 提出了基于区域的全卷积网 ...

  2. meaven

    一个项目管理工具.java语言编写的,所以可以跨平台 https://mvnrepository.com/

  3. python列表1

    List (列表)List(列表) 是 Python 中使用最 频繁的数据类 型.列表 可以 完成大 多数集 合类 的数据 结构 实现. 列表中 元素 的类型 可以 不相同 ,它支 持数 字,字 符串 ...

  4. POJ 3080 Blue Jeans (字符串处理暴力枚举)

    Blue Jeans  Time Limit: 1000MS        Memory Limit: 65536K Total Submissions: 21078        Accepted: ...

  5. cnetos 7 mariadb 集群报错分析解答

    1.故障1:通过查看/var/log/message 发现报错 2017-04-14 14:44:10 139845276428544 [ERROR] WSREP: It may not be saf ...

  6. 【C++ Primer | 10】再探迭代器

    插入迭代器 1. 测试代码: #include<iostream> #include<vector> #include<list> #include<iter ...

  7. Hive启动失败

    启动hive报如下错误 [root@node01 conf]# hive19/03/31 09:57:31 WARN conf.HiveConf: HiveConf of name hive.meta ...

  8. Git和Github入门教程

    一.常用命令 所有命令前都要加 git,如表中的init是指 git init.点击命令可直接跳转至本文第一次使用的地方.以下命令都在命令行里执行. 1.本地命令 行为 命令 备注 初始化 init ...

  9. 【BZOJ1778】[Usaco2010 Hol]Dotp 驱逐猪猡

    题解: 网上有一种复杂的方法..好像复杂度并没有优势就没看 定义f[i]表示i的期望经过次数,f[i]=sigma{f[j]*p/q/du[j]}+(i==1); 然后高斯消元就可以了 最后求出来的f ...

  10. pandas处理finance.yahoo股票数据 WTI CL USO OIL

    1.参考 用Python做科学计算-基础篇 »matplotlib-绘制精美的图表 »快速绘图 使用pyplot模块绘图 2.数据来源 CL USO OIL 3.代码 #encoding='utf-8 ...