【转载】WinCE OAL中的Profiler的实现
转载自:http://blog.csdn.net/nanjianhui/article/details/4076593
OAL中的Profiler的实现是指Monte Carlo Profiler,作为WinCE Kernel profiler的一种,它主要是通过高精度Timer的中断来进行周期性的计数,从而统计各函数的sample数,达到评测某一个模块或者函数的性能的目的。
关于OAL中Monte Carlo Profiler的实现,有一篇不错的文章如下:
http://blogs.msdn.com/ce_base/archive/2006/01/23/516637.aspx
我想我在这里要说的大概也是这个意思,可能会解释的稍微详细一点。下面介绍一下如何实现:
1. 实现OEMProfileTimerEnable和OEMProfileTimerDisable
当profiler启动的时候会调用OEMProfileTimerEnable函数来启动一个高精度的Timer,该函数还会注册并使能Timer中断。当profiler停止的时候会调用OEMProfileTimerDisable函数来停止Timer的运行,同时也会屏蔽Timer的中断。举例说明一下:
VOID OEMProfileTimerEnable(DWORD interval)
{
BOOL enabled;
UINT32 Irq;
// Profiler已经启动,直接返回
if (g_profiler.enabled) return;
// 计算高精度Timer的count数
g_profiler.countsPerHit = (g_oalTimer.countsPerMSec*interval)/1000;
// 关闭中断
enabled = INTERRUPTS_ENABLE(FALSE);
// 赋值Profiler的中断处理函数
g_pProfilerISR = OALProfileIntrHandler;
// 配置高精度Timer的count值
ConfigureNextProfilerCount(g_profiler.countsPerHit);
// 打开中断
INTERRUPTS_ENABLE(enabled);
Irq = IRQ_TIMER2;
OALIntrDoneIrqs(1, &Irq);
// 设置Profiler使能标记位
g_profiler.enabled = TRUE;
}
VOID OEMProfileTimerDisable()
{
BOOL enabled;
UINT32 irq;
// Profiler已经屏蔽,直接返回
if (!g_profiler.enabled) return;
// 关闭中断
enabled = INTERRUPTS_ENABLE(FALSE);
// 清楚高精度Timer的中断标记位
g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) | TIMER2_PENDING_CLEAR;
// 禁用高精度Timer
g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) & ~TIMER2_INTERRUPT_ENABLE;
// 屏蔽高精度Timer中断
irq = IRQ_TIMER2;
OALIntrDisableIrqs(1, &irq);
// 设置Profiler的中断处理函数为NULL
g_pProfilerISR = NULL;
// 设置Profiler标记位
g_profiler.enabled = FALSE;
// 打开中断
INTERRUPTS_ENABLE(enabled);
}
2. 实现OALProfileIntrHandler来处理Profiler的中断
函数OALProfileIntrHandler用于处理高精度Timer的中断,该函数会在OEMInterruptHandler中被调用,并返回SYSINTR_NOP。在该函数中需要调用ProfileHit函数,这里传入ProfileHit函数的参数要和OEMInterruptHandler的参数一致。举例如下:
UINT32 OALProfileIntrHandler(UINT32 ra)
{
UINT32 Irq;
// 更新高精度Timer的计数
ConfigureNextProfilerCount(g_profiler.countsPerHit);
// 调用ProfilerHit采样
ProfilerHit(ra);
// 使能Timer
Irq = IRQ_TIMER2;
OALIntrDoneIrqs(1, &Irq);
return(SYSINTR_NOP);
}
在OAL中实现上面的3个函数就可以了,要支持Monte Carlo Profiler还需要对你的WinCE工程做其它的设置。在WinCE的编译选项中选择”Enable profiling (IMGPROFILER=1)”并确认config.bib文件有如下代码:
IF IMGPROFILER
PROFILE=ON
ELSE
PROFILE=OFF
ENDIF
最后要做的就是Makeimg了。在WinCE运行以后,可以通过以下几种方法控制Monte Carlo Profiler,如下:
1. 通过Target Control命令来控制
prof on -m :启动Monte Carlo Profiler
prof off :停止Profiler
2. 通过键盘来控制
如果系统支持键盘,那么默认情况下,键盘是支持Profiler的控制的。按F9启动Monte Carlo Profiler,按F12停止Profiler功能。实际上,在按下这些按键的时候系统调用了API函数来启动和停止Profiler,分别是ProfileStart和ProfileStop函数。
3. 通过Profiler的API函数来到控制
通过ProfileStart和ProfileStop函数来控制。
VOID ProfileStart(DWORD dwUSecInterval, DWORD dwOptions)
dwUSecInterval:采样精度,微秒级。
dwOptions:Profiler的标记位
PROFILE_BUFFER:使用Buffer模式
PROFILE_CONTINUE:恢复Profiler采样
PROFILE_KCALL:记录内核调用
PROFILE_OBJCALL:记录目标调用
PROFILE_PAUSE:停止Profiler采样
PROFILE_STARTPAUSED:启动Profiler但处在暂停状态
该函数用于启动Profiler,一般在Buffer模式下,推荐将dwUSecInterval设置为200微秒。
VOID ProfileStop (void);
该函数用于停止Profiler功能。