This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ZStack 2.51 a 版本, 终端主动从协调器退网后 就出现死机,电流2.9mA,按下任何中断按键都没有反应,除非是复位

Other Parts Discussed in Thread: Z-STACK

void leaveNetBySelf(void)
{
     //主动离开参考
     NLME_LeaveReq_t leaveReq;
     osal_memset((uint8 *)&leaveReq,0,sizeof(NLME_LeaveReq_t));
     osal_memcpy(leaveReq.extAddr,NLME_GetExtAddr(),Z_EXTADDR_LEN);
     leaveReq.removeChildren = 1;
     leaveReq.rejoin = 0;
     leaveReq.silent = 0;

     HalLedBlink (HAL_LED_1, 0, 50, 2000 );
     if( NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS )
     {
       
      
      ZDApp_LeaveReset(false);
     }
     
}

这是按键按下后终端主动从A协调器退网指令,执行后就会出现死机,我原本意思就是从A协调器断网,加入B协调器,从A协调器断网后就出现死机,求教

  • 需要先确保是否已经离网成功,最好抓包看一下具体信息
  • 抓包现实已经离开网络 ,但是后面就死机了
  • 抓包文件上传一下,还修改了哪些部分,之前是否开启过NV_RESTORE?若开启过则需要先清除NV保存的网络信息

  • 送出leave request建議做個system reset

  • 已经开启NV_RESTORE ,怎么清除
  • zgWriteStartupOptions(ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE); 是不是这个清除NV-RESTORE
  • ZDApp_LeaveReset(true); 是不是这个
  • if(keys & HAL_KEY_SW_JOIN)//加入网络
    {
    if(joinFlag==0)//断网状态下--加入
    {

    devState = DEV_HOLD;
    HalLedBlink (HAL_LED_1, 20, 50, 500 );
    ZDApp_StartJoiningCycle();
    ZDOInitDevice( 0 ); //加入网络
    osal_start_timerEx( SampleApp_TaskID,SAMPLEAPP_JOIN_MSG_EVT,SAMPLEAPP_JOIN_MSG_EVT_TIMEOUT );//时间间隔
    }
    else//---有网状态下--离开
    {
    //特别重要代码,不要删除
    leaveNetBySelf();
    // ZDApp_StopJoiningCycle();
    // HalLedBlink (HAL_LED_1, 5, 50, 2000 );
    // osal_stop_timerEx( SampleApp_TaskID,SAMPLEAPP_JOIN_MSG_EVT );//时间间隔
    }

    if(joinFlag==0)
    joinFlag=1;
    else
    joinFlag=0;
    }

    //////////////////////////上面是按键处理第一次是入网 第二次退网
    退网用leaveNetSelf函数

    void leaveNetBySelf(void)
    {
    // zAddrType_t *zaddr;
    //uint8 coorAddr[8];
    //uint8 ieee[8];

    //主动离开参考
    NLME_LeaveReq_t leaveReq;
    osal_memset((uint8 *)&leaveReq,0,sizeof(NLME_LeaveReq_t));
    osal_memcpy(leaveReq.extAddr,NLME_GetExtAddr(),Z_EXTADDR_LEN);

    leaveReq.removeChildren = 1;
    leaveReq.rejoin = 0;
    leaveReq.silent = 0;

    if( NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS )
    {
    //
    ZDApp_LeaveReset(true);
    zgWriteStartupOptions(ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE);
    HalLedBlink (HAL_LED_1, 0, 50, 2000 );
    }

    }

    入网没有问题,按下退网就死机了 我的设计是退网后 再次加入别的协调器【协调器通过按键允许加入,】
  • 是的,再按照YiKai所说在清除后面加上SystemResetSoft()复位系统
  • 我抓包了,好像没有发现离开离开网络命令啊,是不是省电终端不会发啊啊,NWK_AUTO_POLL
    POWER_SAVING
    NV_RESTORE
    NV_INIT
    xHOLD_AUTO_SATART
    xZTOOL_P1
    xMT_TASK
    xMT_SYS_FUNC
    xMT_ZDO_FUNC
    xLCD_SUPPORTED=DEBUG
    上面是我的省电终端编译选项
    /*
    * f8wConfig.cfg
    *
    * Compiler command-line options used to define a TI Z-Stack ZigBee device.
    * To move an option from here to the project file, comment out or delete the
    * option from this file and enter it into the "Define Symbols" box under the
    * Preprocessor tab of the C/C++ Compiler Project Options. New user defined
    * options may be added to this file, as necessary.
    *
    * Each macro is prefixed with '-D'. The entries are to be constructed as if
    * they are to be on the compiler command line invocation (which they are).
    *
    * NOTE: The RHS (Right-Hand-Side) must be quoted if there are embedded blanks.
    * See the DEFAULT_KEY definition for an example.
    */

    /* Enable ZigBee-Pro */
    -DZIGBEEPRO

    /* Set to 0 for no security, otherwise non-0 */
    -DSECURE=1
    -DZG_SECURE_DYNAMIC=0

    /* Enable the Reflector */
    -DREFLECTOR

    /* Default channel is Channel 11 - 0x0B */
    // Channels are defined in the following:
    // 0 : 868 MHz 0x00000001
    // 1 - 10 : 915 MHz 0x000007FE
    // 11 - 26 : 2.4 GHz 0x07FFF800
    //
    //-DMAX_CHANNELS_868MHZ 0x00000001
    //-DMAX_CHANNELS_915MHZ 0x000007FE
    //-DMAX_CHANNELS_24GHZ 0x07FFF800
    //-DDEFAULT_CHANLIST=0x04000000 // 26 - 0x1A
    //-DDEFAULT_CHANLIST=0x02000000 // 25 - 0x19
    //-DDEFAULT_CHANLIST=0x01000000 // 24 - 0x18
    //-DDEFAULT_CHANLIST=0x00800000 // 23 - 0x17
    //-DDEFAULT_CHANLIST=0x00400000 // 22 - 0x16
    //-DDEFAULT_CHANLIST=0x00200000 // 21 - 0x15
    //-DDEFAULT_CHANLIST=0x00100000 // 20 - 0x14
    //-DDEFAULT_CHANLIST=0x00080000 // 19 - 0x13
    //-DDEFAULT_CHANLIST=0x00040000 // 18 - 0x12
    //-DDEFAULT_CHANLIST=0x00020000 // 17 - 0x11
    //-DDEFAULT_CHANLIST=0x00010000 // 16 - 0x10
    //-DDEFAULT_CHANLIST=0x00008000 // 15 - 0x0F
    //-DDEFAULT_CHANLIST=0x00004000 // 14 - 0x0E
    //-DDEFAULT_CHANLIST=0x00002000 // 13 - 0x0D
    //-DDEFAULT_CHANLIST=0x00001000 // 12 - 0x0C
    -DDEFAULT_CHANLIST=0x00000800 // 11 - 0x0B

    /* Define the default PAN ID.
    *
    * Setting this to a value other than 0xFFFF causes
    * ZDO_COORD to use this value as its PAN ID and
    * Routers and end devices to join PAN with this ID
    */
    -DZDAPP_CONFIG_PAN_ID=0xFFFF

    /* Minimum number of milliseconds to hold off the start of the device
    * in the network and the minimum delay between joining cycles.
    */
    -DNWK_START_DELAY=100

    /* Mask for the random joining delay. This value is masked with
    * the return from osal_rand() to get a random delay time for
    * each joining cycle. This random value is added to NWK_START_DELAY.
    * For example, a value of 0x007F will be a joining delay of 0 to 127
    * milliseconds.
    */
    -DEXTENDED_JOINING_RANDOM_MASK=0x007F

    /* Minimum number of milliseconds to delay between each beacon request
    * in a joining cycle.
    */
    -DBEACON_REQUEST_DELAY=100

    /* Mask for the random beacon request delay. This value is masked with the
    * return from osal_rand() to get a random delay time for each joining cycle.
    * This random value is added to DBEACON_REQUEST_DELAY. For example, a value
    * of 0x00FF will be a beacon request delay of 0 to 255 milliseconds.
    */
    -DBEACON_REQ_DELAY_MASK=0x00FF

    /* Jitter mask for the link status report timer. This value is masked with the
    * return from osal_rand() to add a random delay to _NIB.nwkLinkStatusPeriod.
    * For example, a value of 0x007F allows a jitter between 0-127 milliseconds.
    */
    -DLINK_STATUS_JITTER_MASK=0x007F

    /* in seconds; set to 0 to turn off route expiry */
    -DROUTE_EXPIRY_TIME=30

    /* This number is used by polled devices, since the spec'd formula
    * doesn't work for sleeping end devices. For non-polled devices,
    * a formula is used. Value is in 2 milliseconds periods
    */
    -DAPSC_ACK_WAIT_DURATION_POLLED=3000

    /* Default indirect message holding timeout value:
    * 1-65535 (0 -> 65536) X CNT_RTG_TIMER X RTG_TIMER_INTERVAL
    */
    -DNWK_INDIRECT_MSG_TIMEOUT=7

    /* The number of simultaneous route discoveries in network */
    -DMAX_RREQ_ENTRIES=8

    /* The maximum number of retries allowed after a transmission failure */
    -DAPSC_MAX_FRAME_RETRIES=3

    /* Max number of times retry looking for the next hop address of a message */
    -DNWK_MAX_DATA_RETRIES=2

    /* Number of times retry to poll parent before indicating loss of synchronization
    * with parent. Note that larger value will cause longer delay for the child to
    * rejoin the network.
    */
    -DMAX_POLL_FAILURE_RETRIES=2

    /* The number of items in the broadcast table */
    -DMAX_BCAST=9

    /* The maximum number of groups in the groups table */
    -DAPS_MAX_GROUPS=16

    /* Number of entries in the regular routing table plus additional
    * entries for route repair
    */
    -DMAX_RTG_ENTRIES=40

    /* Maximum number of entries in the Binding table. */
    -DNWK_MAX_BINDING_ENTRIES=4

    /* Maximum number of cluster IDs for each binding table entry.
    * Note that any value other than the default value may cause a
    * compilation warning but Device Binding will function correctly.
    */
    -DMAX_BINDING_CLUSTER_IDS=4

    /* Default security key. */
    -DDEFAULT_KEY="{-----------------------------------------------------------------}"

    /* Reset when ASSERT occurs, otherwise flash LEDs */
    //-DASSERT_RESET

    /* Set the MAC MAX Frame Size (802.15.4 default is 102) */
    -DMAC_MAX_FRAME_SIZE=116

    /* Minimum transmissions attempted for Channel Interference detection,
    * Frequency Agility can be disabled by setting this parameter to zero.
    */
    -DZDNWKMGR_MIN_TRANSMISSIONS=20

    /* Compiler keywords */
    -DCONST="const __code"
    -DGENERIC=__generic

    /****************************************
    * The following are for End Devices only
    ***************************************/

    -DRFD_RCVC_ALWAYS_ON=FALSE

    /* The number of milliseconds to wait between data request polls to the coordinator. */
    -DPOLL_RATE=0

    /* This is used after receiving a data indication to poll immediately
    * for queued messages...in milliseconds.
    */
    -DQUEUED_POLL_RATE=0

    /* This is used after receiving a data confirmation to poll immediately
    * for response messages...in milliseconds
    */
    -DRESPONSE_POLL_RATE=0

    /* This is used as an alternate response poll rate only for rejoin request.
    * This rate is determined by the response time of the parent that the device
    * is trying to join.
    */
    -DREJOIN_POLL_RATE=440

    这是config文件,密钥被我--------------代替,看看有什么问题,为什么不发出leave request
  • 最新的离开网络函数 省电终端自主离开

    void leaveNetBySelf(void)
    {
    NLME_LeaveReq_t leaveReq;
    osal_memset((uint8 *)&leaveReq,0,sizeof(NLME_LeaveReq_t));
    osal_memcpy(leaveReq.extAddr,NLME_GetExtAddr(),Z_EXTADDR_LEN);

    leaveReq.removeChildren = 1;
    leaveReq.rejoin = 0;
    leaveReq.silent = 0;

    if( NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS )
    {
    zgWriteStartupOptions(ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE);
    SystemResetSoft();
    HalLedBlink (HAL_LED_1, 0, 50, 2000 );
    }

    }
  • 建議先調試NLME_LeaveReq是不是回覆SUCCESS
  • 当按下退网按钮后,会发出Orphan notification
  • 設置個斷點在if( NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS )看看有沒有走到它
  • 执行没有success ,好像离网不成功啊
  • NLME_LeaveReq的返回值是什麼?你有確定調用NLME_LeaveReq的時候裝置是連上Zigbee網路的嗎?
  • 确定,我已经抓包了,
  • 只要执行这句,设备就死了 还发出orphan notifaction
  • 試試用下面的程序
        NLME_LeaveReq_t leaveReq;
        osal_memset( &leaveReq, 0, sizeof( NLME_LeaveReq_t ) );
          
        NLME_LeaveReq( &leaveReq );
        if( NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS )...



  • 仍然没法退网,执行到这里就死了
  • 执行到这那里就死了?
  • 是的,整个终端就死了
  • 你在哪個程序裡頭調用leaveNetBySelf?
  • 要不把终端程序发给你看看
  • 你只要告訴我在哪個地方調用leaveNetBySelf就好
  • 按键处理函数void SampleApp_HandleKeys( uint8 shift, uint8 keys )
    {
    (void)shift; // Intentionally unreferenced parameter
    uint8 data[70]={'\0'};
    uint8 len;

    //对应的按键开关
    if ( keys & HAL_KEY_SW_ON )//
    {
    replySubChannel=HAL_SENSOR_CHANNEL_1;
    sensor1State=HAL_SENSOR_MODE_ON;
    // if(netConnectFlag==1)
    // {
    // DeviceSensor_Upload_Message(1);
    // HalLedBlink (HAL_LED_1, 1, 50, 100 );
    //}
    HalLedBlink (HAL_LED_1, 1, 50, 100 );
    osal_stop_timerEx( SampleApp_TaskID,SAMPLEAPP_TEST_MSG_EVT);
    osal_start_timerEx( SampleApp_TaskID,SAMPLEAPP_TEST_MSG_EVT,SAMPLEAPP_TEST_MSG_TIMEOUT );//时间间隔
    }
    if ( keys & HAL_KEY_SW_OFF )
    {
    replySubChannel=HAL_SENSOR_CHANNEL_1;
    sensor1State=HAL_SENSOR_MODE_OFF;

    osal_stop_timerEx( SampleApp_TaskID,SAMPLEAPP_TEST_MSG_EVT);
    osal_start_timerEx( SampleApp_TaskID,SAMPLEAPP_TEST_MSG_EVT,SAMPLEAPP_TEST_MSG_TIMEOUT );//时间间隔
    HalLedBlink (HAL_LED_1, 1, 50, 100 );
    // if(netConnectFlag==1)
    // {
    // DeviceSensor_Upload_Message(1);
    // HalLedBlink (HAL_LED_1, 1, 50, 100 );
    // }
    }

    if(keys & HAL_KEY_SW_JOIN)//加入网络
    {
    if(joinFlag==1)//断网状态下--加入
    {
    devState = DEV_HOLD;
    HalLedBlink (HAL_LED_1, 20, 50, 500 );
    ZDApp_StartJoiningCycle();
    ZDOInitDevice( 0 ); //加入网络
    osal_stop_timerEx( SampleApp_TaskID,SAMPLEAPP_JOIN_MSG_EVT);
    osal_start_timerEx( SampleApp_TaskID,SAMPLEAPP_JOIN_MSG_EVT,SAMPLEAPP_JOIN_MSG_EVT_TIMEOUT );//时间间隔
    }
    else//---有网状态下--离开
    {
    osal_stop_timerEx( SampleApp_TaskID,SAMPLEAPP_JOIN_MSG_EVT);
    ZDApp_StopJoiningCycle();//停止加入网络

    leaveNetBySelf();
    }

    if(joinFlag==0)
    joinFlag=1;
    else
    joinFlag=0;
    }


    }
  • leaveNetBySelf之前不要再調用ZDApp_StopJoiningCycle了吧
  • 即使屏蔽也没有用,我现在终端是低功耗设备,就是退网会死机,抓包也没有成功退网,但是断电重启或者复位可以证明已经退出A协调器了,
  • 不知道是不是因为设置了-DRFD_RCVC_ALWAYS_ON=FALSE

    /* The number of milliseconds to wait between data request polls to the coordinator. */
    -DPOLL_RATE=0

    /* This is used after receiving a data indication to poll immediately
    * for queued messages...in milliseconds.
    */
    -DQUEUED_POLL_RATE=0

    /* This is used after receiving a data confirmation to poll immediately
    * for response messages...in milliseconds
    */
    -DRESPONSE_POLL_RATE=0

    /* This is used as an alternate response poll rate only for rejoin request.
    * This rate is determined by the response time of the parent that the device
    * is trying to join.
    */
    -DREJOIN_POLL_RATE=440

    导致无法退出网络,
  • 即使屏蔽也没有用,现在是退网按下后就卡死了,我的设备是低功耗设备,不知道是不是因为

    -DRFD_RCVC_ALWAYS_ON=FALSE

    /* The number of milliseconds to wait between data request polls to the coordinator. */
    -DPOLL_RATE=0

    /* This is used after receiving a data indication to poll immediately
    * for queued messages...in milliseconds.
    */
    -DQUEUED_POLL_RATE=0

    /* This is used after receiving a data confirmation to poll immediately
    * for response messages...in milliseconds
    */
    -DRESPONSE_POLL_RATE=0

    /* This is used as an alternate response poll rate only for rejoin request.
    * This rate is determined by the response time of the parent that the device
    * is trying to join.
    */
    -DREJOIN_POLL_RATE=440

    导致系统处于死等待状态不
  • 感覺上像是按鍵的其他程序丶如果按下按鍵的時候不調用leaveNetBySelf會有同樣的問題?
  • 只要不调用leaveNetBySelf 这个函数就不会出现问题,
  • 同时leaveNetBySelf 是自己退网,
  • 調试看的出來卡在哪裡嗎?
  • 好像没有成功发出leave 帧, 我这个是低功耗设备,做了一些编译选项,还有一些配置,估计是这些阻止发出leave 帧,这样就没有成功离开网络

  • 只要清除NV,設備自行調用reset後就會清除設備上的網路資訊了

  • //主动离开参考
    NLME_LeaveReq_t leaveReq;
    osal_memset((uint8 *)&leaveReq,0,sizeof(NLME_LeaveReq_t));
    osal_memcpy(leaveReq.extAddr,NLME_GetExtAddr(),Z_EXTADDR_LEN);
    leaveReq.extAddr=NULL;
    leaveReq.removeChildren = 1;
    leaveReq.rejoin = 0;
    leaveReq.silent = 0;
    zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE | ZCD_STARTOPT_DEFAULT_CONFIG_STATE );
    if( NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS )
    {
    ZDApp_LeaveReset(false);
    }
    只要执行这段函数,程序就死了
  • 不去执行下面这段函数還會死嗎?
    if( NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS )
    {
    ZDApp_LeaveReset(false);
    }
  • 試試把ZDApp_LeaveReset(false)改成ZDApp_ResetTimerStart(5000)看看
  • 这个函数好像不支持调用啊
    要手动改,要不把代码发给你看看
    有微信吗,我的微信是hbredison
  • 你用的協議棧太舊了,不支持ZDApp_ResetTimerStart,你試試自己用個timer event,過5000ms再去調用SystemResetSoft
    我沒用微信
  • ZDAPP 这个没有把他引出来,我收到用了,还是进去会死机
  • 所以是走進去ZDApp_ResetTimerStart才会死机?
  • NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS 走到这里就卡死了,
  • 你osal_memcpy(leaveReq.extAddr,NLME_GetExtAddr(),Z_EXTADDR_LEN)有沒有先移掉,還有leaveReq.removeChildren 也先設置為0試試看
  • NLME_LeaveReq_t leaveReq;
    osal_memset((uint8 *)&leaveReq,0,sizeof(NLME_LeaveReq_t));
    leaveReq.extAddr=NULL;
    leaveReq.removeChildren = 0;
    leaveReq.rejoin = 0;
    leaveReq.silent = 0;
    zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE | ZCD_STARTOPT_DEFAULT_CONFIG_STATE );

    if( NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS )
    {
    // ZDApp_LeaveReset(false);
    ZDApp_ResetTimerStart(5000);
    }
    现在改为这样还是不行
  • 只用下面的程序呢?
    NLME_LeaveReq_t leaveReq;
    osal_memset((uint8 *)&leaveReq,0,sizeof(NLME_LeaveReq_t));
    if( NLME_LeaveReq(&leaveReq)!=afStatus_SUCCESS )
    {
    // ZDApp_LeaveReset(false);
    ZDApp_ResetTimerStart(5000);
    }