zoukankan      html  css  js  c++  java
  • 【DWM1000】 code 解密2一 工程初始化代码分析

    instance_init 函数追下去,绝大多数的代码都在初始化如下结构体 

    typedef struct
    {
        INST_MODE mode; instance_init -ANCHOR                      //instance mode (tag or anchor)
        INST_STATES testAppState ;             int instance_init_s(int mode) TA_INIT    //state machine - current state
        INST_STATES nextState ;                         //state machine - next state
        INST_STATES previousState ;                     //state machine - previous state
        int done ;                                      //done with the current event/wait for next event to arrive
       
    //configuration structures dwt_config_t configData ; //DW1000 channel configuration dwt_txconfig_t configTX ; //DW1000 TX power configuration uint16 txantennaDelay ; //DW1000 TX antenna delay uint16 rxantennaDelay ; //DW1000 RX antenna delay uint8 antennaDelayChanged;
    // "MAC" features uint8 frameFilteringEnabled ; //frame filtering is enabled // Is sleeping between frames enabled? uint8 sleep_en; instance_init 1 //timeouts and delays int tagSleepTime_ms; instancesettagsleepdelay 500//in milliseconds int tagBlinkSleepTime_ms; instancesettagsleepdelay 1000 //this is the delay used for the delayed transmit (when sending the ranging init, response, and final messages) uint64 rnginitReplyDelay ; uint64 finalReplyDelay ; uint64 responseReplyDelay ; int finalReplyDelay_ms ; // xx_sy the units are 1.0256 us uint32 txToRxDelayAnc_sy ; // this is the delay used after sending a response and turning on the receiver to receive final uint32 txToRxDelayTag_sy ; // this is the delay used after sending a poll and turning on the receiver to receive response int rnginitW4Rdelay_sy ; // this is the delay used after sending a blink and turning on the receiver to receive the ranging init message int fwtoTime_sy ; //this is final message duration (longest out of ranging messages) int fwtoTimeB_sy ; //this is the ranging init message duration uint32 delayedReplyTime; // delayed reply time of delayed TX message - high 32 bits uint32 rxTimeouts ; instanceclearcounts 0 // - not used in the ARM code uint32 responseTimeouts ; // Pre-computed frame lengths for frames involved in the ranging process, // in microseconds. uint32 fl_us[FRAME_TYPE_NB]; //message structures used for transmitted messages #if (USING_64BIT_ADDR == 1) srd_msg_dlsl rng_initmsg ; // ranging init message (destination long, source long) srd_msg_dlsl msg ; // simple 802.15.4 frame structure (used for tx message) - using long addresses #else srd_msg_dlss rng_initmsg ; // ranging init message (destination long, source short) srd_msg_dsss msg ; // simple 802.15.4 frame structure (used for tx message) - using short addresses #endif iso_IEEE_EUI64_blink_msg blinkmsg ; // frame structure (used for tx blink message) //messages used in "fast" ranging ... srd_msg_dlss rnmsg ; // ranging init message structure srd_msg_dsss msg_f ; // ranging message with 16-bit addresses - used for "fast" ranging //Tag function address/message configuration uint8 eui64[8]; // devices EUI 64-bit address uint16 tagShortAdd ; // Tag's short address (16-bit) used when USING_64BIT_ADDR == 0 uint16 psduLength ; // used for storing the frame length uint8 frame_sn; instanceclearcounts 0 // modulo 256 frame sequence number - it is incremented for each new frame transmittion uint16 panid ; instance_init 0 xdeca // panid used in the frames uint8 relpyAddress[8] ; // address of the anchor the tag is ranging with //64 bit timestamps //union of TX timestamps union { uint64 txTimeStamp ; // last tx timestamp uint64 tagPollTxTime ; // tag's poll tx timestamp uint64 anchorRespTxTime ; // anchor's reponse tx timestamp }txu; uint64 anchorRespRxTime ; // receive time of response message uint64 tagPollRxTime ; // receive time of poll message //32 bit timestamps (when "fast" ranging is used) uint32 tagPollTxTime32l ; // poll tx time - low 32 bits uint32 tagPollRxTime32l ; // poll rx time - low 32 bits uint32 anchorRespTxTime32l ; // response tx time - low 32 bits uint32 anchResp1RxTime32l ; // response 1 rx time - low 32 bits //application control parameters uint8 wait4ack ; instance_init 0 // if this is set to DWT_RESPONSE_EXPECTED, then the receiver will turn on automatically after TX completion uint8 instToSleep; instance_init 0 // if set the instance will go to sleep before sending the blink/poll message uint8 stoptimer; instance_init 0 // stop/disable an active timer uint8 instancetimer_en; instance_init 0 // enable/start a timer uint32 instancetimer; // e.g. this timer is used to timeout Tag when in deep sleep so it can send the next poll message uint32 instancetimer_saved; // - not used in the ARM code //uint8 deviceissleeping; // this disabled reading/writing to DW1000 while it is in sleep mode // (DW1000 will wake on chip select so need to disable and chip select line activity) uint8 gotTO; // got timeout event uint8 responseRxNum; // response number //diagnostic counters/data, results and logging int32 tof32 ; int64 tof ; instance_init 0 double clockOffset ; instance_init 0 uint32 blinkRXcount ; instcleartaglist 0 int txmsgcount; instanceclearcounts 0 int rxmsgcount; instanceclearcounts 0 int lateTX; instanceclearcounts 0 int lateRX; instanceclearcounts 0 double adist[RTD_MED_SZ] ; double adist4[4] ; double longTermRangeSum ; instanceclearcounts 0 int longTermRangeCount ; instanceclearcounts 0 int tofindex ; instance_init 0 instanceclearcounts 0 int tofcount ; instance_init 0 instanceclearcounts 0 int last_update ; // detect changes to status report double idistmax; instanceclearcounts 0 double idistmin; instanceclearcounts 1000 double idistance ; // instantaneous distance int newrange; int norange; int newrangeancaddress; //last 4 bytes of anchor address int newrangetagaddress; //last 4 bytes of tag address
    // - not used in the ARM code uint32 lastReportTime; int respPSC; //if set to 1 then it means that DW1000 is in DEEP_SLEEP //so the ranging has finished and micro can output on USB/LCD //if sending data to LCD during ranging this limits the speed of ranging uint8 canprintinfo ; //devicelogdata_t devicelogdata; uint8 tagToRangeWith; instcleartaglist 0//it is the index of the tagList array which contains the address of the Tag we are ranging with uint8 tagListLen ; instcleartaglist 0 uint8 anchorListIndex ; int instance_init_s(int mode) 0 uint8 tagList[TAG_LIST_SIZE][8]; instcleartaglist 0 //event queue - used to store DW1000 events as they are processed by the dw_isr/callback functions event_data_t dwevent[MAX_EVENT_NUMBER]; instance_clearevents 0 //this holds any TX/RX events and associated message data event_data_t saved_dwevent; //holds an RX event while the ACK is being sent uint8 dweventIdxOut; instance_clearevents 0 uint8 dweventIdxIn; instance_clearevents 0 uint8 dweventPeek; instance_clearevents 0 uint8 monitor; instance_init 0 uint32 timeofTx ; int dwIDLE; } instance_data_t ;

    上述默认初始化设别为,但是后面接着会根据拨码开关再次决定设备类型

    if(s1switch & SWS1_ANC_MODE)
    {
         instance_mode = ANCHOR;
         led_on(LED_PC6);
    }
    else
    {
        instance_mode = TAG;
        led_on(LED_PC7);
    }

    并再次调用函数设置设备类型

    //Set this instance role as the Tag, Anchor or Listener
    void instancesetrole(int inst_mode)
    {
        // assume instance 0, for this
        instance_data[0].mode =  inst_mode;   // set the role
    }
    

    注意:设置全部都保存在结果体instance_data中,如果我们想扩充设备,那就需要修改这个家伙的数组了。 

    后面是初始化init 结构体

    int instance_init_s(int mode)
    {
        int instance = 0 ;
        instance_data[instance].mode =  mode;     //上面已经设定过了     // assume anchor,
        instance_data[instance].testAppState = TA_INIT ; //后面状态机会用到这个。 
    
        // if using auto CRC check (DWT_INT_RFCG and DWT_INT_RFCE) are used instead of DWT_INT_RDFR flag
        // other errors which need to be checked (as they disable receiver) are
        //dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_SFDT | DWT_INT_RFTO /*| DWT_INT_RXPTO*/), 1);
        //暂时不看具体寄存器设定
        dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_ARFE | DWT_INT_RFSL | DWT_INT_SFDT | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFTO /*| DWT_INT_RXPTO*/), 1); 
    
        //this is platform dependent - only program if DW EVK/EVB
        dwt_setleds(3) ; //configure the GPIOs which control the LEDs on EVBs
        //非常重要,这个是两个回调函数   
        dwt_setcallbacks(instance_txcallback, instance_rxcallback);
        //非常重要,这个应用层主要函数
        instance_setapprun(testapprun_s); 
        instance_data[instance].anchorListIndex = 0 ; 
        //sample test calibration functions
        //xtalcalibration();   
         //powertest();
        return 0 ;
    }
    

    回调函数设定

    void dwt_setcallbacks(void (*txcallback)(const dwt_callback_data_t *), void (*rxcallback)(const dwt_callback_data_t *))
    {
        dw1000local.dwt_txcallback = txcallback;
        dw1000local.dwt_rxcallback = rxcallback;
    }
    

    应用层函数设定

    void instance_setapprun(int (*apprun_fn)(instance_data_t *inst, int message))
    {
             int instance = 0 ;
             instance_localdata[instance].testapprun_fn = apprun_fn;
    }
    

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

     instance_init_s(instance_mode);
     dr_mode = decarangingmode(s1switch);
    //NOTE: Channel 5 is not supported for the non-discovery mode
    int decarangingmode(uint8 s1switch)
    {
        int mode = 0;
        if(s1switch & SWS1_SHF_MODE)
        {
            mode = 1;
        }
        if(s1switch & SWS1_64M_MODE)
        {
            mode = mode + 2;
        }
        if(s1switch & SWS1_CH5_MODE)
        {
            mode = mode + 4;
        }
        return mode;
    }
    

    我们暂时还不确定目前sw组合,看代码不难理解,后续我们再分析这一块。

    instConfig.channelNumber = chConfig[dr_mode].channel ;
    instConfig.preambleCode = chConfig[dr_mode].preambleCode ;
    instConfig.pulseRepFreq = chConfig[dr_mode].prf ;
    instConfig.pacSize = chConfig[dr_mode].pacSize ;
    instConfig.nsSFD = chConfig[dr_mode].nsSFD ;
    instConfig.sfdTO = chConfig[dr_mode].sfdTO ;
    instConfig.dataRate = chConfig[dr_mode].datarate ;
    instConfig.preambleLen = chConfig[dr_mode].preambleLength ;
    instance_config(&instConfig) ;       // Set operating channel etc
    

    根据上面按键sw 确定某一种模式,然后将chConfig 全局变量的一部分提取出来,放到instConfig中,然后调用instance_config配置,这些都是DWM1000 工作必须配置,需要配合datasheet 查看,具体我们这里就不解释了,我们注重的逻辑

    调用instance_config我们就认为RF 相关的参数已经正确配置到DWM1000了。 

    instancesettagsleepdelay(POLL_SLEEP_DELAY, BLINK_SLEEP_DELAY); //set the Tag sleep time(500,1000)
    

    其实从函数内容来看,还是在初始化结构体instace_data。

    // -------------------------------------------------------------------------------------------------------------------
    // function to set the tag sleep time (in ms)
    //
    void instancesettagsleepdelay(int sleepdelay, int blinksleepdelay) //sleep in ms
    {
        int instance = 0 ;
        instance_data[instance].tagSleepTime_ms = sleepdelay ;
        instance_data[instance].tagBlinkSleepTime_ms = blinksleepdelay ;
    }
    

    Inittestapplication 最后一个函数instance_init_timings

    从下面的解释可以看出还是初始化相关,这个函数稍微复杂点,我们暂时先不看。

    // Pre-compute frame lengths, timeouts and delays needed in ranging process.
    // /! This function assumes that there is no user payload in the frame.
    void instance_init_timings(void)  

     现在我们就基本分析完了inittestapplication, 正如它的名字一样,这个主要是init, 一些关键参数的值我们在上面的结构体中也有标注

    博客讨论一些室内定位(DWM1000/CC2431/CC2530) 以及一些随性的技术。博文可以转载,但需要注明出处!
  • 相关阅读:
    windows下安装rocketmq采坑全记录
    测试日常使用---网络协议与抓包
    python重写及重写后调用父类方法
    python继承和多态
    python私有成员都以双下划线“__”开头,仅类内部可访问
    http中的post请求发生了两次(多了一次options请求)的原因
    测试日常使用---linux命令:
    数据库性能优化
    pytest常用配置文件之pytest.ini
    pytest.main()的使用
  • 原文地址:https://www.cnblogs.com/tuzhuke/p/7705614.html
Copyright © 2011-2022 走看看