int done = INST_NOT_DONE_YET;

#define INST_DONE_WAIT_FOR_NEXT_EVENT       1       //this signifies that the current event has been processed and instance is ready for next one

#define INST_DONE_WAIT_FOR_NEXT_EVENT_TO    2   //this signifies that the current event has been processed and that instance is waiting for next one with a timeout

                                               //which will trigger if no event coming in specified time

#define INST_NOT_DONE_YET                 0      //this signifies that the instance is still processing the current event

 

int message = instance_peekevent(); //get any of the received events from ISR

int instance_peekevent(void)
{ int instance = 0; return instance_data[instance].dwevent[instance_data[instance].dweventPeek].type; //return the type of event that is in front of the queue }

  第一次运行到这里的时候,instance_data[instance].dweventPeek 为0 ,我们在之前初始化的时候看到的结果

Peek,也就是瞟一眼,看看是否有事件,假定我们这里还米有收到任何事件。 后面我们会看事件的产生,怎么往里面装,怎么取出。 这里只是简单的瞟一眼。

while(done == INST_NOT_DONE_YET)
{ //int state = instance_data[instance].testAppState; done = instance_localdata[instance].testapprun_fn(&instance_data[instance], message) ; // run the communications application //we've processed message message = 0; }

 由于进入函数的时候,我们定义了局部变量done 为INST_NOT_DONE_YET,所以至少会执行一下while 循环里面的内容。

done = instance_localdata[instance].testapprun_fn(&instance_data[instance], message) ;

回忆之前我们code分析如下内容

//应用层函数设定

void instance_setapprun(int (*apprun_fn)(instance_data_t *inst, int message))

{
int instance = 0 ;
instance_localdata[instance].testapprun_fn = apprun_fn;
}

  设定这些函数,只是提供入口,此时还不会执行。但是RX TX 回调函数是通过中断触发的,设定后可能会立马执行,这个我们后续看代码分析。

之前只是赋值,而现在才是真的执行这个函数testapprun_s

testapprun_s &instance_data[instance], message)

传递的两个变量A : instance_data, 也就是我们开始初始化的变量instance

B:message. instance_peekevent()是它的返回值,我们暂且还不能假定是什么东西。

那么我们现在看看testapprun_s函数吧。

/ -------------------------------------------------------------------------------------------------------------------

//

// the main instance state machine (all the instance modes Tag, Anchor or Listener use the same statemachine....)

//

// -------------------------------------------------------------------------------------------------------------------

//

int testapprun_s(instance_data_t *inst, int message)
{
switch (inst->testAppState)
{
case TA_INIT :
// printf("TA_INIT") ;
switch (inst->mode)
{
case TAG:
{

  

列出一段,对着就是十分糟糕的主要状态机部分了。

在分析这段代码前,我们需要做一些假定,暂时假定,我们现在分析流程是ANCHOR的,因为这个家伙会先启动,由于涉及到无线通信数据收发,所以我们会时不时的切换到TAG。

到目前为止,ANCHOR 和TAG 的代码基本都是一致的。后面状态机就有区别了。

好了,我们假定现在设备是ANCHOR,开始状态机第一步吧。

   switch (inst->testAppState)
{
case TA_INIT :
// printf("TA_INIT") ;
switch (inst->mode)
{
case TAG:
{
……
}
break;
case ANCHOR:
{ dwt_enableframefilter(DWT_FF_NOTYPE_EN); //disable frame filtering inst->frameFilteringEnabled = 0 ; dwt_seteui(inst->eui64); dwt_setpanid(inst->panid); #if (USING_64BIT_ADDR==0)
{
uint16 addr = inst->eui64[0] + (inst->eui64[1] << 8);
dwt_setaddress16(addr);
//set source address into the message structure
memcpy(&inst->msg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_S);
//set source address into the message structure
memcpy(&inst->rng_initmsg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_S);
}
#else
//set source address into the message structure
memcpy(&inst->msg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_L);
//set source address into the message structure
memcpy(&inst->rng_initmsg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_L);
#endif
// First time anchor listens we don't do a delayed RX
dwt_setrxaftertxdelay(0);
//change to next state - wait to receive a message
inst->testAppState = TA_RXE_WAIT ;
dwt_setrxtimeout(0);
inst->canprintinfo = 1;
}
break;
case LISTENER:
{
……
}
break ; // end case TA_INIT
default:
break;
}
break; // end case TA_INIT

上来case 是根据设备状态判断的,没错,我们之前初始化的时候见过这个家伙

 INST_STATES testAppState ;             int instance_init_s(int mode) TA_INIT

进去后,会根据不同的角色(TAG ANCHOR LISTENER)执行不同的代码,先忽略TAG 和 LISTENER的部分,看看ANCHOR做了什么

 dwt_enableframefilter(DWT_FF_NOTYPE_EN); //disable frame filtering
inst->frameFilteringEnabled = 0 ;

关于帧的控制,感觉这家伙不想接收任何数据,同时对结构体frameFilteringEnabled 赋值为0.

dwt_seteui(inst->eui64);
dwt_setpanid(inst->panid);

  

设置64位地址以及PANIND,我们在初始化的时候做的内容包括这两个家伙了。

uint8   eui64[8];                                // devices EUI 64-bit address  ????
uint16 panid ; instance_init 0 xdeca // panid used in the frames

可以追进去看看这两个函数,都是寄存器级别的操作了,我们不追了。dwt_ 开头的都是寄存器级别的操作。

宏定义有如下一行内容

#define USING_64BIT_ADDR (1) //when set to 0 - the DecaRanging application will use 16-bit addresses

所以我们就知道执行的东西是

#else
//set source address into the message structure
memcpy(&inst->msg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_L);
//set source address into the message structure
memcpy(&inst->rng_initmsg.sourceAddr[0], inst->eui64, ADDR_BYTE_SIZE_L);
#endif

好,关于结构体,已知参数又多了两个msg.sourceAddr[0] 和rng_initmsg.sourceAddr[0]。 这两个参数都是ANCHOR的长地址。(这两个参数的值归ANCHOR所有)

// First time anchor listens we don't do a delayed RX
dwt_setrxaftertxdelay(0);
//change to next state - wait to receive a message
inst->testAppState = TA_RXE_WAIT ;
dwt_setrxtimeout(0);
inst->canprintinfo = 1;

这段代码中有两个dwt_ 开头的函数,我们看注释就可以了,取消delayed RX设定以及将rxtimeout设置为0. 修改了testAppState = TA_RXE_WAIT,同时canprintinfo 被设置为1

看到这里突然想到我们testapprun_s 传入两个函数,第二message 还没有用到,确实,对ANCHOR 的TA_INIT 还没有用到这个参数。

case TA_INIT :
……
Break;

Break 了,我们需要看看  switch (inst->testAppState)之外是否还有代码。

一直拉到testapprun_s最后,发现只有这个了

    return inst->done;
} // end testapprun()

好吧,我们刚才没有看inst->done是个什么东西,返回去再看看

仔细在TA_INITàANCHOR 代码块找了一圈发现并没有设置这个inst->done. 好吧,那我们看看之前初始化的时候是否有设置。

  int done ;                                      //done with the current event/wait for next event to arrive

没有标记,那可能是没有设置,我们那认为它返回的初始值0. 先这样吧,第一次尝试了testapprun_s,我们赶快跳到instance_run(void) 中吧。

while(done == INST_NOT_DONE_YET)
{
//int state = instance_data[instance].testAppState;
done = instance_localdata[instance].testapprun_fn(&instance_data[instance], message) ; // run the communications application
//we've processed message
message = 0;
}

我们假定done为0,name看看是否还在while中

#define INST_NOT_DONE_YET               0

看来很不幸,满足while 条件,再次执行,再次进入到testapprun_s中。

【DWM1000】 code 解密3一ANCHOR RUN起来的更多相关文章

  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 解密9一 ANCHOR response poll message

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. java提取出一个字符串里面的Double类型数字

    String str="hh\n1\n22\n798.809\n0.89\n";         String regex="\\d+(?:\\.\\d+)?" ...

  2. String 类的实现(2)引用计数与写时拷贝

    1.引用计数 我们知道在C++中动态开辟空间时是用字符new和delete的.其中使用new test[N]方式开辟空间时实际上是开辟了(N*sizeof(test)+4)字节的空间.如图示其中保存N ...

  3. MVC开发中的常见错误-01未能加载文件或程序集“EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”或它的某一个依赖项。

    错误信息:未能加载文件或程序集“EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”或 ...

  4. Javascript中函数提升和变量提升

    词法分析 词法分析方法: js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤: 分析参数 再分析变量的声明 分析函数说明 具体步骤如下: 函数在运行的瞬间,生成一个活动对象(Active ...

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

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

  6. 期货大赛项目|二,DAL详解

    接口层就不重点讲述了,直接DAL层 DAL层 using System; using System.Collections.Generic; using System.Linq; using Syst ...

  7. 【Ruby】Mac gem的一些坑

    前言 自上一次升级MacOS系统后出现jekyll无法构建的问题,当时处理半天.谁知道最近又升级了MacOS,荒废博客多时,今天吝啬写了一篇准备发布,构建报错,问题重新.还是记录下,以防下次升级出问题 ...

  8. 开源工具软件XMusicDownloader——音乐下载神器

    XMusicDownloader,一款 支持从百度.网易.qq和酷狗等音乐网站搜索并下载歌曲的程序. 缘起: 一直用网易音乐听歌,但是诸如李健.周杰伦的不少歌曲,网易都没有版权,要从QQ等音乐去下载, ...

  9. NOI2018Day2T1 屠龙勇士 set 扩展欧几里德 中国剩余定理

    原文链接https://www.cnblogs.com/zhouzhendong/p/NOI2018Day2T1.html 题目传送门 - 洛谷P4774 题意 题解 首先我们仔细看一看样例可以发现如 ...

  10. 配置maven从自己的私服下载jar包nexus、maven私服仓库(二)

    配置maven项目从私服下载jar包 pom文件配置从maven私服下载jar包 settings文件配置从maven私服下载jar包 (方便自己关键字搜索,所以多写了几行o(* ̄︶ ̄*)o) 今天自 ...