【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\n", ( 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】 code 解密7一ANCHOR接收到BLINK的更多相关文章
- 【DWM1000】 code 解密3一ANCHOR RUN起来
int done = INST_NOT_DONE_YET; #define INST_DONE_WAIT_FOR_NEXT_EVENT 1 //this signifies that the curr ...
- 【DWM1000】 code 解密9一 ANCHOR response poll message
根据上面TAG发送的代码,我直接找到如下代码 case RTLS_DEMO_MSG_TAG_POLL: { if(inst->mode == LISTENER) ...
- 【DWM1000】 code 解密4一 ANCHOR 二进宫testapprun_s
上面我们的代码分析到ANCHOR 调用了一次testapprun_s,但是后面退出后发现还是满足while 条件,逼不得已还得再次调用testapprun_s.testapprun_s 也就是这样一点 ...
- 【DWM1000】 code 解密10 一 TAG 发送最后一个消息
更上面ANCHOR发送信息时的RTLS_DEMO_MSG_ANCH_RESP, 我们很快就可以找到如下代码 case RTLS_DEMO_MSG_ANCH_RESP: { 这里面一部分是设置重要变量, ...
- 【DWM1000】 code 解密8一 TAG接收blink response 信号
在分析这个部分前,目前我看到DWM1000 的资料,data可以分为blink和一般无线数据,后面有内容我们再扩充, 上面我们已经看到接收到blink触发的事件为 case SIG_RX_BLINK ...
- 【DWM1000】 code 解密6一TAG 状态机第一步
我们前面分析过,不论ANCHOR 还是TAG,前面变量的初始化基本都是一样的,只是状态机必须明确区分不同的设备类型.我们从开始看TAG.由于初始化TAG的 testAppState一样初始化为TA_I ...
- 【DWM1000】 code 解密2一 工程初始化代码分析
instance_init 函数追下去,绝大多数的代码都在初始化如下结构体 typedef struct { INST_MODE mode; instance_init -ANCHOR //insta ...
- 【DWM1000】 code 解密1一 去掉Main 函数多余内容
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: 室内定位兴起,DWM1000 作为超宽带UWB的代表,在国内用的越来越多,但是可见资料非常少. 一方面 ...
- 【DWM1000】 code 解密5一ACHOR 第一次回家Main 函数
instance_run(); if((instance_data[0].monitor == 1) && ((portGetTickCnt() - instance_data[0]. ...
随机推荐
- PXE+HTTP+TFTP+Kickstart实现无人值守部署centos6.10
在联网的状态下安装所需软件: Shell> yum install dhcp httpd tftp-server xinetd syslinux system-config-kickstart ...
- 从零开始 DOM操作 笔记
<div id="box" class="box"></div> --> var myBox = document.g ...
- Centos7.4上Apache(http)编译安装
前提:1.这个centos操作系统能上网 2.yum 安装apr,apr-util,zlib-devel,groupinstall Development Tools,gcc 1.在apache的 ...
- 查看CPU 内存 硬盘 网络 查看进程使用的文件 uptime top ps -aux vmstat iostat iotop nload iptraf nethogs
#安装命令 yum install sysstat #包含 iostat vmstat yum install iotop yum install nload yum install iptraf ...
- Caused by: java.net.ConnectException: Connection refused/Caused by: java.lang.RuntimeException: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
1.使用sqoop技术将mysql的数据导入到Hive出现的错误如下所示: 第一次使用命令如下所示: [hadoop@slaver1 sqoop--cdh5.3.6]$ bin/sqoop impor ...
- js高级程序设计
defer 异步脚本,脚本延迟到文档完全被解析和显示之后再执行.只对外部脚本文件有效.按顺序执行脚本.但在实际情况下,并不一定会按照顺序执行最好只有一个延迟脚本.支持H5的浏览器会忽略给脚本设置 de ...
- 安装CentOS 7(转)
转载地址:https://www.cnblogs.com/wcwen1990/p/7630545.html CentOS7安装详解 本文基于vmware workstations进行CentOS7 ...
- python_异常处理_断言
一.Python标准异常 常用异常 Exception 常规错误的基类 AttributeError 试图访问一个对象没有的属性 IOError 输入/ 输出异常,基本上是无法打开文件 ImportE ...
- memcached 配置
Memcached是一款开源.高性能.分布式内存对象缓存系统,可应用各种需要缓存的场景,其主要目的是通过降低对Database的访问来加速web应用程序.它是一个基于内存的“键值对”存储,用于存储数据 ...
- POJ3076 Sudoku 舞蹈链 DLX
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目(传送门) 题意概括 给出一个残缺的16*16数独,求解. 题解 DLX + 矩阵构建 (两个传送门) 学完这个之后,再 ...