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.

zigbeeCC2530休眠问题

Other Parts Discussed in Thread: CC2530

请问,我启用休眠模式,本意想用定时唤醒,5S唤醒一次,当我设置终端的LED亮时,是闪烁的状态,并且闪烁频率很高,我找资料说是闪烁频率高说明一直有让CPU工作,理论上应该是没有的,请问我该怎么查找究竟是哪些任务在执行?另外,休眠的时候我是否可以不改变IO状态?谢谢

  • 查找究竟是哪些任务在执行?

    设置不同的标志或者输出调试信息才知道的。

    休眠的时候我是否可以不改变IO状态?

    看看数据手册上休眠模式的描述是否支持呢?

  • 如果使用的是zigbee协议的话.可以一步步调试看看

    1. 从osal_run_system 看是否能进入osal_pwrmgr_powerconserve(), 如不行要分析还有什么一直在run的task

    2. 确认是否会调用如下的OSAL_SET_CPU_INTO_SLEEP()

    void osal_pwrmgr_powerconserve( void )
    {
    uint32 next;
    halIntState_t intState;

    // Should we even look into power conservation
    if ( pwrmgr_attribute.pwrmgr_device != PWRMGR_ALWAYS_ON )
    {
    // Are all tasks in agreement to conserve
    if ( pwrmgr_attribute.pwrmgr_task_state == 0 )
    {
    // Hold off interrupts.
    HAL_ENTER_CRITICAL_SECTION( intState );

    // Get next time-out
    next = osal_next_timeout();

    // Re-enable interrupts.
    HAL_EXIT_CRITICAL_SECTION( intState );

    // Put the processor into sleep mode
    OSAL_SET_CPU_INTO_SLEEP( next );
    }
    }
    }

    3. 再一步步debug ,hal_sleep函数,最终是否能执行到HAL_SLEEP_SET_POWER_MODE();

    void halSleep( uint32 osal_timeout )
    {
    uint32 timeout;
    uint32 macTimeout = 0;

    /* get next OSAL timer expiration converted to 320 usec units */
    timeout = HAL_SLEEP_MS_TO_320US(osal_timeout);
    if (timeout == 0)
    {
    timeout = MAC_PwrNextTimeout();
    }
    else
    {
    /* get next MAC timer expiration */
    macTimeout = MAC_PwrNextTimeout();

    /* get lesser of two timeouts */
    if ((macTimeout != 0) && (macTimeout < timeout))
    {
    timeout = macTimeout;
    }
    }

    /* HAL_SLEEP_PM2 is entered only if the timeout is zero and
    * the device is a stimulated device.
    */
    halPwrMgtMode = (timeout == 0) ? HAL_SLEEP_DEEP : HAL_SLEEP_TIMER;

    /* DEEP sleep can only be entered when zgPollRate == 0.
    * This is to eliminate any possibility of entering PM3 between
    * two network timers.
    */
    #if ZG_BUILD_ENDDEVICE_TYPE && defined (NWK_AUTO_POLL)
    if ((timeout > HAL_SLEEP_MS_TO_320US(PM_MIN_SLEEP_TIME)) ||
    (timeout == 0 && zgPollRate == 0))
    #else
    if ((timeout > HAL_SLEEP_MS_TO_320US(PM_MIN_SLEEP_TIME)) ||
    (timeout == 0))
    #endif
    {
    halIntState_t ien0, ien1, ien2;

    HAL_ASSERT(HAL_INTERRUPTS_ARE_ENABLED());
    HAL_DISABLE_INTERRUPTS();

    /* always use "deep sleep" to turn off radio VREG on CC2530 */
    if (halSleepPconValue != 0 && MAC_PwrOffReq(MAC_PWR_SLEEP_DEEP) == MAC_SUCCESS)
    {
    /* The PCON value is not zero. There is no interrupt overriding the
    * sleep decision. Also, the radio granted the sleep request.
    */

    #if ((defined HAL_KEY) && (HAL_KEY == TRUE))
    /* get peripherals ready for sleep */
    HalKeyEnterSleep();
    #endif

    #ifdef HAL_SLEEP_DEBUG_LED
    HAL_TURN_OFF_LED3();
    #else
    /* use this to turn LEDs off during sleep */
    HalLedEnterSleep();
    #endif

    if(timeout > maxSleepLoopTime)
    {
    timeout = maxSleepLoopTime;
    }

    do
    {
    /* enable sleep timer interrupt */
    if(timeout != 0)
    {
    if (timeout > HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ))
    {
    timeout -= HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME );
    halSleepSetTimer(HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ));
    }
    else
    {
    /* set sleep timer */
    halSleepSetTimer(timeout);
    timeout = 0;
    }

    /* set up sleep timer interrupt */
    HAL_SLEEP_TIMER_CLEAR_INT();
    HAL_SLEEP_TIMER_ENABLE_INT();
    }

    #ifdef HAL_SLEEP_DEBUG_LED
    if (halPwrMgtMode == CC2530_PM1)
    {
    HAL_TURN_ON_LED1();
    }
    else
    {
    HAL_TURN_OFF_LED1();
    }
    #endif
    /* Prep CC2530 power mode */
    HAL_SLEEP_PREP_POWER_MODE(halPwrMgtMode);

    /* save interrupt enable registers and disable all interrupts */
    HAL_SLEEP_IE_BACKUP_AND_DISABLE(ien0, ien1, ien2);
    HAL_ENABLE_INTERRUPTS();

    /* set CC2530 power mode, interrupt is disabled after this function
    * Note that an ISR (that could wake up from power mode) which runs
    * between the previous instruction enabling interrupts and before
    * power mode is set would switch the halSleepPconValue so that
    * power mode shall not be entered in such a case.
    */

    HAL_SLEEP_SET_POWER_MODE();

    /* the interrupt is disabled - see halSetSleepMode() */

    /* restore interrupt enable registers */
    HAL_SLEEP_IE_RESTORE(ien0, ien1, ien2);

    /* disable sleep timer interrupt */
    HAL_SLEEP_TIMER_DISABLE_INT();

    #ifdef HAL_SLEEP_DEBUG_LED
    HAL_TURN_ON_LED3();
    #else
    /* use this to turn LEDs back on after sleep */
    HalLedExitSleep();
    #endif

    #if ((defined HAL_KEY) && (HAL_KEY == TRUE))
    /* handle peripherals */
    if(HalKeyExitSleep())
    {
    break;
    }
    #endif

    } while(timeout != 0);

    /* power on the MAC; blocks until completion */
    MAC_PwrOnReq();

    HAL_ENABLE_INTERRUPTS();

    /* For CC2530, T2 interrupt won抰 be generated when the current count is greater than
    * the comparator. The interrupt is only generated when the current count is equal to
    * the comparator. When the CC2530 is waking up from sleep, there is a small window
    * that the count may be grater than the comparator, therefore, missing the interrupt.
    * This workaround will call the T2 ISR when the current T2 count is greater than the
    * comparator. The problem only occurs when POWER_SAVING is turned on, i.e. the 32KHz
    * drives the chip in sleep and SYNC start is used.
    */
    macMcuTimer2OverflowWorkaround();
    }
    else
    {
    /* An interrupt may have changed the sleep decision. Do not sleep at all. Turn on
    * the interrupt, exit normally, and the next sleep will be allowed.
    */
    HAL_ENABLE_INTERRUPTS();
    }
    }
    }

  •  您好:

    我在这里有如下疑问:如果mac层没有关于定时器的事件,只有应用层有定时器事件,获取的最小溢出时间大于睡眠定时器的最大

    溢出周期,此处会进行轮询,则到时间为0?轮询每次减去的时间为什么是HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME )