根据上面TAG发送的代码,我直接找到如下代码

case RTLS_DEMO_MSG_TAG_POLL:

{

if(inst->mode == LISTENER)                                                                       {

……不满足条件

}

if (!inst->frameFilteringEnabled)

{

// if we missed the ACK to the ranging init message we may not have turned frame filtering on

dwt_enableframefilter(DWT_FF_DATA_EN | DWT_FF_ACK_EN); //we are starting ranging - enable the filter....

inst->frameFilteringEnabled = 1 ;

}

if(inst->previousState == TA_TXRESPONSE_WAIT_SEND)

{

inst->norange = 3;

}

if(dw_event->type3 == DWT_SIG_TX_PENDING)

{

inst->canprintinfo = 0;

inst->testAppState = TA_TX_WAIT_CONF;                                               // wait confirmation

inst->previousState = TA_TXRESPONSE_WAIT_SEND ;

}

else

{

//stay in RX wait for next frame...

inst->testAppState = TA_RXE_WAIT ;              // wait for next frame

}

}

break; //RTLS_DEMO_MSG_TAG_POLL

inst->frameFilteringEnabled 这个参数之前有接触过,确实是0,所以会执行。

后面感觉代码很少,不像之前看到的代码有很多,而且从注释中发现,这里直接就等待下一个帧了,而我们的直观感觉或者从DWM1000官方代码分析手册上看到,这个时候ANCHOR应该回复一下TAG。

我们这里追一下rxcallback 函数,这里我也困惑了很久。

发现在rxcall back 函数中确实会直接处理这个信息

if(rxd_event == DWT_SIG_RX_OKAY)

{

//check if this is a TWR message (and also which one)

if(instance_data[instance].tagListLen > 0)

{

switch(dw_event.msgu.frame[fcode_index])

{

case RTLS_DEMO_MSG_TAG_POLL:

{

这里保存了几个非常重要的变量,首先一个是

nstance_data[instance].tagPollRxTime = dw_event.timeStamp ; //Poll's Rx time

这个是ANCHOR接收数据的时间,在TAG端记录了一个发送数据的时间,两者之差就是TOF的时间长度。

下面这个变量用到再说

instance_data[instance].delayedReplyTime = 0;

后面开始构建数据发送poll response

memcpy(&instance_data[instance].msg.destAddr[0], &dw_event.msgu.frame[srcAddr_index], ADDR_BYTE_SIZE_L); //remember who to send the reply to (set destination address)

memcpy(&(instance_data[instance].msg.messageData[TOFR]), &instance_data[instance].tof, 5);

instance_data[instance].tof = 0; //clear ToF ..

instance_data[instance].msg.seqNum = instance_data[instance].frame_sn++;

instance_data[instance].wait4ack = DWT_RESPONSE_EXPECTED;

这里有个比较奇怪的地方,就是数据包为何包括了instance_data[instance].tof, 这个量是定位时间最终结果,我们这里定位才刚刚开始,数据还没法完呢。 这里剧透下,看来官方的文档才明白, 定位数据结果在下一次anchor 给tag 的poll request中,所以这里就有这么一个坑。

好了,再来几个发送函数就万事大吉了

dwt_setrxaftertxdelay((uint32)instance_data[instance].txToRxDelayAnc_sy);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)

dwt_writetxfctrl(frameLength, 0);

dwt_writetxdata(frameLength, (uint8 *)  &instance_data[instance].msg, 0) ;  // write the frame data

dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);

仔细看,由于宏定义

所以下面这行肯定被执行IMMEDIATE_RESPONSE =1

dw_event.type3 = DWT_SIG_TX_PENDING ;

// exit this interrupt and notify the application/instance that TX is in progress.

现在返回来再看testapprun_s,所以肯定会执行下面的代码,然后退出estapprun_s

if(dw_event->type3 == DWT_SIG_TX_PENDING)

{

inst->canprintinfo = 0;

inst->testAppState = TA_TX_WAIT_CONF;

inst->previousState = TA_TXRESPONSE_WAIT_SEND ;

}

根据上面两个重要变量,我们再次进入testapprun_s,,其实case TA_TX_WAIT_CONF 我们已经看过多次了,但是由于previousState 代码不同,每次执行略有不同, 这个case的主要作用是等待发送完成。 我们再把代码拿上来。

首先是这几行代码,我们之前已经分析过了,就是一直等待发送结果,一带而过,之间根据previousState 找代码吧。

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

{

if(dw_event->type == DWT_SIG_RX_TIMEOUT) //got RX timeout - i.e. did not get the response (e.g. ACK)

{

//printf("RX timeout in TA_TX_WAIT_CONF (%d)\n", inst->previousState);

//we need to wait for SIG_TX_DONE and then process the timeout and re-send the frame if needed

inst->gotTO = 1;

}

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT;

break;

}

发现这个case中的其他if 都没有满足的,但是中间会有几个变量不需要判断自动赋值的,摘录如下

inst->done = INST_NOT_DONE_YET;

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

inst->testAppState = TA_RXE_WAIT ;

message = 0;

//break ; // end case TA_TX_WAIT_CONF

和之前一样,将testAppState 设置为TA_RXE_WAIT,没有break直接进入下面的case了,这里就不分析了,和之前代码一样,一直等TAG的回复了,我们又该转到TAG端了。 这里说下一个比较重要的变量,之前我们把它遗漏了

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

这个变量保存了发送时间,在TAG端也有一个这样的值,两个一起不是冲突了,这个。。。 TAG的是TAG的,ANCHOR 是ANCHOR的,一份代码在两个不同设备上同时运行。

这里需要提前剧透,因为转到TAG发现好像刚才我们分析代码的时候没有像case RTLS_DEMO_MSG_TAG_POLL放到数据帧里发送出去。 这个让我纠结了好久,其实我们之前的代码说过了。 摘录一段之前的分析

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

这个确实是好久就准备好了,这个代码写的也是太。。。 不说了,根据这个东西,我们可以从TAG入手了。

【DWM1000】 code 解密9一 ANCHOR response poll message的更多相关文章

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

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

  2. 【DWM1000】 code 解密4一 ANCHOR 二进宫testapprun_s

    上面我们的代码分析到ANCHOR 调用了一次testapprun_s,但是后面退出后发现还是满足while 条件,逼不得已还得再次调用testapprun_s.testapprun_s 也就是这样一点 ...

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

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

  4. 【DWM1000】 code 解密8一 TAG接收blink response 信号

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 控制台操作mysql常用命令

    总结: 1. 控制台链接mysql mysql -u lzpddd -pmypassword -h -D mydb -S /opt/mysql/data/mysql//mysql.sock 2.

  2. 数据结构C++实现代码-顺序表

    参考:https://blog.csdn.net/ebowtang/article/details/43094041 //seqList.h// //包含顺序表中的声明// #include<i ...

  3. fetch请求

    get请求 return fetch('https://xxx.xxx.com/xxx.json') .then(response => response.json()) .then(respo ...

  4. settings.py常见配置项

    settings.py常见配置项 1. 配置Django_Admin依照中文界面显示 LANGUAGE_CODE = 'zh-hans' 2. 数据库配置(默认使用sqlite3) 1 .默认使用的s ...

  5. [转] js中的事件委托或是事件代理详解

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...

  6. virtualenv and virtualenvwrapper

    virtualenv 1.下载virtualenv工具 通过物理环境的pip工具安装  清华 国内 pip3 install -i https://pypi.tuna.tsinghua.edu.cn/ ...

  7. 【回顾】html链接、头部

    1.HTML 链接 HTML 使用超级链接与网络上的另一个文档相连.几乎可以在所有的网页中找到链接.点击链接可以从一张页面跳转到另一张页面. HTML 超链接(链接) HTML使用标签 <a&g ...

  8. 构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(66)-MVC WebApi 用户验证 (2)

    前言: 构建ASP.NET MVC5+EF6+EasyUI 1.4.3+Unity4.x注入的后台管理系统(65)-MVC WebApi 用户验证 (1) 回顾上一节,我们利用webapi简单的登录并 ...

  9. glusterfs分布式复制扩容卷以及平衡卷

    随着数据量的增长,需要扩容满足使用.今天测试下glusterfs磁盘扩容的具体步骤 1.扩容 之前用的2台计算机的分布式复制卷.需要同时之两个服务器增加一块磁盘并格式化,挂载并扩容 热添加磁盘 ech ...

  10. themeleaf引入公共页面

    <div th:include="/top :: html"></div>//引用公共页面 <div th:replace="head&qu ...