RT-Thread / RT-Thread/rt-thread

[Bug] pm组件对于peripheral device已经进入对应 的suspend,后续可能不执行对应的resume

Open
#11,046 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
12.2k
Forks
5.4k
Avg merge
4d 12h
Merged PRs (30d)
40

Description

RT-Thread Version

5.2.2

Hardware Type/Architectures

CORTEX-M4

Develop Toolchain

Other

Describe the bug

pm组件对于peripheral `device已经进入低功耗后,因tickless进入低功耗,会导致sleep_mode这个变量可能会变,导致后续执行resume不会执行对应的退出功耗代码

/* Notify app will enter sleep mode */
        if (_pm_notify.notify)
            _pm_notify.notify(RT_PM_ENTER_SLEEP, pm->sleep_mode, _pm_notify.data);

        /* Suspend all peripheral device */
#ifdef PM_ENABLE_SUSPEND_SLEEP_MODE
        int ret = _pm_device_suspend(pm->sleep_mode);
        if (ret != RT_EOK)
        {
            _pm_device_resume(pm->sleep_mode);
            if (_pm_notify.notify)
                _pm_notify.notify(RT_PM_EXIT_SLEEP, pm->sleep_mode, _pm_notify.data);
            if (pm->sleep_mode > PM_SUSPEND_SLEEP_MODE)
            {
                pm->sleep_mode = PM_SUSPEND_SLEEP_MODE;
            }
            pm->ops->sleep(pm, pm->sleep_mode); /* suspend failed */
             rt_pm_exit_critical(level, pm->sleep_mode);
            return;
        }
#else
        _pm_device_suspend(pm->sleep_mode); //假如sleep_mode 等于3
#endif

        /* Tickless*/
        if (pm->timer_mask & (0x01 << pm->sleep_mode)) //哪些低功耗模式需要启用tickless
        {
            pre_tick = timeout_tick = pm_timer_next_timeout_tick(pm->sleep_mode);
            
            timeout_tick = timeout_tick - rt_tick_get();

            /* Judge sleep_mode from threshold time */
            pm->sleep_mode = pm_get_sleep_threshold_mode(pm->sleep_mode, timeout_tick); //这里会修改稿sleep_mode的值

            if (pm->timer_mask & (0x01 << pm->sleep_mode))
            {
                if (pre_tick == RT_TICK_MAX)
                {
                    pm_lptimer_start(pm, RT_TICK_MAX);
                }
                else
                {
                    pm_lptimer_start(pm, timeout_tick);
                }
            }
        }

        /* enter lower power state */
        pm_sleep(pm, pm->sleep_mode);

        /* wake up from lower power state*/
        if (pm->timer_mask & (0x01 << pm->sleep_mode))
        {
            delta_tick = pm_lptimer_get_timeout(pm);
            pm_lptimer_stop(pm);
            if (delta_tick)
            {
                rt_tick_set(rt_tick_get() + delta_tick);
            }
        }

        /* resume all device */
        _pm_device_resume(pm->sleep_mode); //如果sleep_mode的值被修改了,就不会执行与suspend对应的resume了
Other additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the PM sleep flow through _pm_device_suspend, pm_get_sleep_threshold_mode, pm_sleep, and _pm_device_resume in the code shown. Verify that a peripheral suspended for the original sleep mode is resumed for that same mode even when threshold selection changes sleep_mode; done means the matching resume path is reliably exercised after wake-up.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
operating-systems
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.