2931|6

79

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请教DVS、DFS(动态电压、频率)的问题 [复制链接]

现在有个任务,当系统进入空闲的时候,要调整core电压和core的频率,但现在有个问题,当我一开机的时候,系统会不断的调用OEMIdle(),那么这样有一个问题,系统什么时候在什么情况下会调用OEMIdle(),又在什么样的情况下会结束OEMIdle()?因为,它如果每次一进入我就调整电压和频率,这样会引起问题的:它可能实际上非常忙,只是一闪而过的idle一下就结束了。我希望的策略是当它稳定在idle状态下我才调整电压和频率,这样才能真正省电有效率。
有没有哪位做过这样的工作,给我讲讲,或者提示一下啊?或者推荐一些文档也行啊,谢谢了。

最新回复

请教一下楼主,是怎么实现的?  详情 回复 发表于 2009-2-26 17:59
点赞 关注

回复
举报

80

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
This function is called by the kernel to place the CPU in the idle state when there are no threads ready to run.
我们以前的做法也不是一旦系统进入IDLE就去调频调压的,而是要等一段时间足够长后才去调整
可以参考一下Intel平台的IPM代码,或者是Samsung平台的DVS代码
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
The kernel calls OEMIdle whenever there are no threads ready to run. The kernel provides an extern DWORD dwReschedTime value that indicates when the next known event is to occur. Such asynchronous events as user-generated interrupt from a keyboard or mouse can occur before then and need to be handled.

You can find code samples of OEMIdle in %_WINCEROOT%\Platform\Common\Src\Common\Timer\Idle\Idle.c.
When the kernel calls the OEMIdle function, the OEM device is requested to go into a sleep, or idle, state. This consists of saving the current state, placing the memory into a refresh state if necessary, stopping the clock, and suspending execution.
In order to conserve power while continually awakening the target device, OEMIdle should sleep for as long as possible. This is usually until the sooner of two events: dwReschedTime, or the maximum delay supported by the hardware timer.
When an interrupt occurs, scheduled or otherwise, the device ends its idle state, the previous state is restored, and the scheduler is invoked. If no new threads are ready to run, the kernel will again call OEMIdle.
When the system returns from idle, OEMIdle must update the CurMSec variable with the real number of milliseconds that have elapsed. The sample OAL also keeps partial millisecond counts, dwPartialCurMSec, in case another interrupt occurs, which will cause the system to stop idling before the system timer fires.
The following code example shows how to implement OEMIdle with these variables.
void OEMIdle(DWORD idleParam)
{
    UINT32 baseMSec;
    UINT32 idleTimeMSec;
    INT32 idleSysTicks;
    INT32 usedCounts;
    INT32 idleCounts;
    ULARGE_INTEGER idle;

    // Get current system timer counter
    baseMSec = CurMSec;

    // Compute the remaining idle time
    idleTimeMSec = dwReschedTime - baseMSec;
   
    // Idle time has expired - we need to return
    if ((INT32)idleTimeMSec <= 0) return;

    // Limit the maximum idle time to what is supported.  
    // Counter size is the limiting parameter.  When kernel
    // profiler or interrupt latency timing is active it is set
    // to one system tick.
    if (idleTimeMSec > g_oalTimer.maxIdleMSec) {
        idleTimeMSec = g_oalTimer.maxIdleMSec;
    }

    // We can wait only full systick
    idleSysTicks = idleTimeMSec/g_oalTimer.msecPerSysTick;
   
    // This is idle time in hi-res ticks
    idleCounts = idleSysTicks * g_oalTimer.countsPerSysTick;

    // Find how many hi-res ticks was already used
    usedCounts = OALTimerCountsSinceSysTick();

    // Prolong beat period to idle time -- don't do it idle time isn't
    // longer than one system tick. Even if OALTimerExtendSysTick function
    // should accept this value it can cause problems if kernel profiler
    // or interrupt latency timing is active.
    if (idleSysTicks > 1) {
        OALTimerExtendSysTick(idleCounts, g_oalTimer.countsMargin, 0);
    }

    // Move SoC/CPU to idle mode
    OALCPUIdle();

    // Return system tick period back to original. Don't call when idle
    // time was one system tick. See comment above.
    if (idleSysTicks > 1) {

        // Return system tick period back to original
        idleSysTicks = OALTimerReduceSysTick(
            g_oalTimer.countsPerSysTick, g_oalTimer.countsMargin
        );

        // Do we need offset counters?
        if (idleSysTicks > 0) {        
            // Fix system tick counters
            CurMSec += idleSysTicks * g_oalTimer.msecPerSysTick;
            g_oalTimer.curCounts += idleSysTicks * g_oalTimer.countsPerSysTick;
        }            

        // Get where we are inside tick
        idleCounts = OALTimerCountsSinceSysTick();
    }

    // Update idle time
    idle.LowPart = curridlelow;
    idle.HighPart = curridlehigh;
    idle.QuadPart += idleCounts - usedCounts;
    curridlelow  = idle.LowPart;
    curridlehigh = idle.HighPart;
}
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

4
 
引用 1 楼 hzdysymbol 的回复:
This function is called by the kernel to place the CPU in the idle state when there are no threads ready to run.
我们以前的做法也不是一旦系统进入IDLE就去调频调压的,而是要等一段时间足够长后才去调整
可以参考一下Intel平台的IPM代码,或者是Samsung平台的DVS代码


对,我也有这样的一个想法,但现在的问题是,系统进入idle,当idle时间结束的时候,它就会立即返回了,即使什么任务都没有,它也要返回调度一次。我们现在的调度时间是1ms,即使我把它设置成10ms,它也要离开的啊。这个时候,我的新的CPU频率、电压还不一定能稳定呢,马上又要restore了,看上去频率和电压就是在不断的切换中,真的能省电嘛?

第二个问题,你们现在采用的调度时间是多少毫秒?

第三个问题,你说参考intel或者三星的代码,请问,你参考的是三星哪个平台的代码?

问题比较多,谢谢哦
 
 
 

回复

123

帖子

0

TA的资源

一粒金砂(初级)

5
 
已经实现了。。。。。
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

6
 
恭喜LZ
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

7
 
请教一下楼主,是怎么实现的?
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表