Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pm.c中notify、_pm_device_suspend/_pm_device_resume传参不对称,是bug还是设计如此? #9017

Open
wzd5230 opened this issue May 31, 2024 · 1 comment

Comments

@wzd5230
Copy link

wzd5230 commented May 31, 2024

在pm.c中的_pm_change_sleep_mode()函数实现了notify、device_suspend/device_resume的调用,但是在sleep之前调用的notify、device_suspend传入的参数sleep_mode,与sleep之后调用的notify、device_resume传入的参数sleep_mode值可能不一样,以下是部分核心的代码,我用注释标注问题点:

_pm_notify.notify(RT_PM_ENTER_SLEEP, pm->sleep_mode, _pm_notify.data);
_pm_device_suspend(pm->sleep_mode);

if (pm->timer_mask & (0x01 << pm->sleep_mode))
{
    timeout_tick = pm_timer_next_timeout_tick(pm->sleep_mode);
    timeout_tick = timeout_tick - rt_tick_get();

    /* Judge sleep_mode from threshold time */
    // 睡眠时间太短,会切换成IDLE模式,这里sleep_mode就会变了
    **pm->sleep_mode** = pm_get_sleep_threshold_mode(pm->sleep_mode, timeout_tick);

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

pm_sleep(pm, pm->sleep_mode);
// 后面的device_resume、notify传入的参数中的sleep_mode与之前的不同,出现了不对称现象
_pm_device_resume(pm->sleep_mode);
_pm_notify.notify(RT_PM_EXIT_SLEEP, pm->sleep_mode, _pm_notify.data);

如果当前需要进入deep_sleep,但是因为时间太短,在pm_get_sleep_threshold_mode()中被设置到IDLE模式,那么在sleep之后调用device_resume、notify传入的sleep_mode与sleep之前传入的不同。
假设作为console的串口通过rt_pm_device_register注册进来,其伪代码为:

int uart_suspend(const struct rt_device *device, rt_uint8_t mode)
{
    if(mode < PM_SLEEP_MODE_DEEP)
   {
        return 0;
   }

   uart_deinit();
   return 0;
}
void uart_resume(const struct rt_device *device, rt_uint8_t mode)
{
    if(mode < PM_SLEEP_MODE_DEEP)
   {
        return 0;
   }

   uart_init();
   return 0;
}

在上面这种情况下会调用uart_suspend中会重置uart,但是resume中并没有对uart进行初始化。
不知道是我对pm框架的理解不正确,还是这里真的存在bug?

@wdfk-prog
Copy link
Contributor

  • 或许来说,mode只是传入而已;你可以选择不进行判断直接重新初始化与卸载;
  • 这一块就看用户的使用进行编写啦;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants