RTX5中没有对各线程的CPU占用统计,这里使用EventRecorder
统计各线程的CPU占用。
在RTX_Config.h
中将宏定义OS_EVR_THREAD
设置为1,在rtx_evr.c
中的EvrRtxThreadCreated()
和EvrRtxThreadSwitched()
定义如下:
__WEAK void EvrRtxThreadCreated (osThreadId_t thread_id, uint32_t thread_addr, const char *name) {
#if defined(RTE_Compiler_EventRecorder)
if (name != NULL) {
(void)EventRecord2(EvtRtxThreadCreated_Name, (uint32_t)thread_id, (uint32_t)name);
} else {
(void)EventRecord2(EvtRtxThreadCreated_Addr, (uint32_t)thread_id, thread_addr);
}
#else
(void)thread_id;
(void)thread_addr;
(void)name;
#endif
}
__WEAK void EvrRtxThreadSwitched (osThreadId_t thread_id) {
#if defined(RTE_Compiler_EventRecorder)
(void)EventRecord2(EvtRtxThreadSwitched, (uint32_t)thread_id, 0U);
#else
(void)thread_id;
#endif
}
当线程创建后,进入EvrRtxThreadCreated()
函数,通过EventRecord2()
将创建的线程信息通过调试接口发送给PC,发生线程切换时,进入EvrRtxThreadSwitched()
,通过EventRecord2()
将切换的线程id通过调试接口发送给调试的上位机。这两个函数都是弱定义,重定义这两个函数,并统计时间周期内各线程运行的时间即可计算线程的CPU占用率。
具体实现方法如下:EvrRtxThreadCreated
在线程创建时被调用,函数中统计线程的ID,并将ID存入数组中。
void EvrRtxThreadCreated (osThreadId_t thread_id, uint32_t thread_addr, const char *name)
{
uint16_t ptr;
osRtxThread_t *p_tcb;
uint32_t * sp;
for(ptr=0;ptr<MAX_THREAD_NUM;ptr++)
{
/* 检测到列表尾 */
if(cpuUsage.id[ptr] == 0)
break;
/* 当前列表已有该线程 */
if(cpuUsage.id[ptr] == (uint32_t)thread_id)
return;
}
cpuUsage.id[ptr] = (uint32_t)thread_id;
p_tcb = thread_id;
sp=(uint32_t *)(p_tcb->sp);
}
EvrRtxThreadSwitched
在发生线程切换时调用,统计上一个线程的运行时间并更新当前运行线程的ID。
void EvrRtxThreadSwitched (osThreadId_t thread_id)
{
uint16_t ptr;
uint32_t threadRunTime;
uint64_t time;
/* 获取当前的运行时间(us) */
time = GetRunTimeUs();
/* 计算上一个线程的运行时间并更新当前线程的开始时间 */
threadRunTime = time - cpuUsage.threadStartUs;
cpuUsage.threadStartUs = time;
/* 将上一个线程的运行时间累加 */
for(ptr = 0;ptr<MAX_THREAD_NUM;ptr++)
{
if(cpuUsage.id[ptr]==cpuUsage.runId)
{
cpuUsage.time[ptr] += threadRunTime;
}
if(cpuUsage.id[ptr]==0)
break;
}
/* 更新当前运行线程ID */
cpuUsage.runId = (uint32_t)thread_id;
}
CPU统计的程序每200ms执行一次,首先获取一个周期的运行时间,储存这一个周期内各个线程的运行时间,并更新下一周期的开始时间,获取当前运行的线程ID。各线程的运行时间储存在cpuUsage.usage
中,除以cpuUsage.cycleTime
即为各线程的占用率。
/* 各线程CPU占用率统计 */
/* 获取一个周期的时间 */
cpuUsage.cycleTime = bsp_Timer.RunTimeUs_Check(cpuUsage.startUs);
/* 储存线程运行时间 */
for(threadPtr = 0; threadPtr<MAX_THREAD_NUM; threadPtr++)
{
if(cpuUsage.id[threadPtr]==0)
break;
cpuUsage.usage[threadPtr] = cpuUsage.time[threadPtr];
}
/* 获取一个统计周期开始的时间 */
cpuUsage.startUs = bsp_Timer.RunTimeUs_Get();
/* 清除各线程的运行时间 */
for(threadPtr = 0; threadPtr<MAX_THREAD_NUM; threadPtr++)
{
if(cpuUsage.id[threadPtr]==0)
break;
cpuUsage.time[threadPtr] = 0;
}
/* 获取当前运行的线程ID */
cpuUsage.runId = (uint32_t)osThreadGetId();
/* 当前线程的开始时间即为本次统计周期的开始时间 */
cpuUsage.threadStartUs = cpuUsage.startUs;
1 条评论
感谢