目前有多种在嵌入式计算机操作系统中检测CPU占用率的方法,例如,目前在嵌入式操作系统vxWorks中主要有两种CPU占用率检测的方法。

第一种:通过spy工具利用辅助定时器产生中断,并且为每个任务维护一个计数器。然后记下被中断的任务,并且将该任务的计数器加一。经过一段时间后,每个任务的计数器反映了该任务占用CPU利用率的情况。很明显,这是利用抽样技术。并且得到的cpu利用率的准确程度取决于任务的持续性和周期性。

通过查找spyLib.h的文件,我们发现除了spy()函数外,还有一spyCommon函数,带一函数指针参数。推测函数指针类型为(int)(*p)(char * fmtStr,…)(经过验证确实如此)。所以可以写一自己的函数去接受spy需要打印的数据,Spy调用该函数按行打印结果。我们可以不断分析一行字符串来得到我们需要的结果。

int SpyPtnFunc(const char * fmtPtn,...)
{
  char buf[128];

  CPUUSAGEDATAMSG data;

  va_list vl;

  va_start(vl,fmtPtn);

  vsprintf(buf,fmtPtn,vl);  //得到一行字符串。

  va_end(vl);

  //分析buf,得到一个任务的CPU的使用情况。

  return 0;
}

第二种:通过创建两个特殊的任务,一个优先级别最高的任务和一个优先级别最低的任务,在这个优先级别最高的任务里运行一个循环次数很大的循环用于占用所有的CPU时间,记录一段时间内计数值;然后再设置一个优先级别最低的任务,当所有任务都停止时CPU才会调度此任务,此任务记下在无其他任务占用CPU的情况下计数,最后通过算法CPU占用率 = (total -idle)% total。

但这两种算法都需要硬件系统配备相应高精度的辅助时钟,为了节约成本,通常没有这样的时钟,相对第一种方法来说,精确计算各任务CPU占用率没有必要,作为报警需要,计算系统总的CPU占用率即可;第二种虽然是计算整个系统的占用率,但必须需要硬件时钟的中断才能实现。

第二种方法的另一种解释是: 利用一特殊任务,该任务的优先级比系统中的所有任务的优先级都低,该任务是死循环,该任务的目的就是消耗cpu资源,占用cpu空闲时间,因为当系统中其它任务都被挂其时,该任务才能得到cpu的使用权。假设一段时间total内,该任务的运行时间为idle,cpu利用率的计算公式为(total-idle)%total。这一种方法实现起来很简单,但是它只能算得整个系统的cpu使用情况,不能得到单个任务的cpu使用情况!同时它会使cpu满负荷工作。源代码如下

#include "VxWorks.h"
#include "semLib.h"
#include "taskLib.h"

#define SECONDS_TO_BURN 60

typedef struct cpuUsage {

    SEM_ID        startSem;
    int           didNotComplete;
    unsigned long ticksNoContention;
    int           nBurnNoContention;
    unsigned long ticksNow;
    int           nBurnNow;
    double        usage;
} cpuUsage;

static cpuUsage *pcpuUsage=0;

static double cpuBurn()
{
    int i;
    double result = 0.0;

    for(i=0;i<5; i++) result += sqrt((double)i);
    return(result);
}

static void cpuUsageTask()
{
        while(TRUE) {
        int    i;
        unsigned long tickStart,tickEnd;

        semTake(pcpuUsage->startSem,WAIT_FOREVER);
        pcpuUsage->ticksNow=0;
        pcpuUsage->nBurnNow=0;
        tickStart = tickGet();

        for(i=0; i< pcpuUsage->nBurnNoContention; i++) {

            cpuBurn();
            pcpuUsage->ticksNow = tickGet() - tickStart;
            ++pcpuUsage->nBurnNow;

        }
        tickEnd = tickGet();
        pcpuUsage->didNotComplete = FALSE;
        pcpuUsage->ticksNow = tickEnd - tickStart;

    }
}

double getCpu()
{
    if(pcpuUsage->didNotComplete && pcpuUsage->nBurnNow==0) {

        pcpuUsage->usage = 0.0;

    } else {

        double temp;
        double ticksNow,nBurnNow;
        ticksNow = (double)pcpuUsage->ticksNow;
        nBurnNow = (double)pcpuUsage->nBurnNow;
        ticksNow *= (double)pcpuUsage->nBurnNoContention/nBurnNow;
        temp = ticksNow - (double)pcpuUsage->ticksNoContention;
        temp = 100.0 * temp/ticksNow;
        if(temp100.0) temp=0.0; /*handle tick overflow*/
        pcpuUsage->usage = temp;

    }

    pcpuUsage->didNotComplete = TRUE;
    semGive(pcpuUsage->startSem);
    printf("CPU usage:%f/r/n",pcpuUsage->usage);
    return(pcpuUsage->usage);
}

void cpuUsageInit(void)
{
    unsigned long tickStart,tickNow;
    int           nBurnNoContention=0;
    int         ticksToWait;
    ticksToWait = SECONDS_TO_BURN*sysClkRateGet();
    pcpuUsage = calloc(1,sizeof(cpuUsage));
    tickStart = tickGet();
    /*wait for a tick*/
    while(tickStart==(tickNow = tickGet())) {;}
    tickStart = tickNow;

    while(TRUE) {
        if((tickGet() - tickStart)>=ticksToWait) break;
        cpuBurn();
        nBurnNoContention++;
    }
    pcpuUsage->nBurnNoContention = nBurnNoContention;
    pcpuUsage->startSem = semBCreate (SEM_Q_FIFO,SEM_EMPTY);
    pcpuUsage->ticksNoContention = ticksToWait;
    pcpuUsage->didNotComplete = TRUE;
    taskSpawn("cpuUsageTask",255,VX_FP_TASK,1000,(FUNCPTR)cpuUsageTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
VxWorks cpu utilization(spy command)

% spyHelp

spyHelp Print this list

spyClkStart [ticksPerSec] Start task activity monitor running at ticksPerSec ticks per second

spyClkStop Stop collecting data

spyReport Prints display of task activity statistics

spyStop Stop collecting data and reports

spy [freq[,ticksPerSec]] Start spyClkStart and do a report [every "freq" second ]

* spyReport - display task activity data

*

* This routine reports on data gathered at interrupt level for the amount of

* CPU time utilized by each task, the amount of time spent at interrupt level,

* the amount of time spent in the kernel, and the amount of idle time. Time

* is displayed in ticks and as a percentage, and the data is shown since both

* the last call to spyClkStart() and the last spyReport(). If no interrupts

* have occurred since the last spyReport(), nothing is displayed.

*

* RETURNS: N/A

*

* SEE ALSO: spyLib, spyClkStart(),

* .pG "Target Shell"

% spyReport
 
NAME          ENTRY         TID   PRI   total % (ticks)  delta % (ticks)
--------     --------      -----  ---   ---------------  ---------------
tExcTask     excTask    2f788870    0     0% (       0)    0% (       0)
tLogTask     logTask    2f7807a0    0     0% (       0)    0% (       0)
DebugDaemon             2e64abd0   21     0% (       0)    0% (       0)
MsTimer_task            2e6b22f0   29     0% (       0)    0% (       0)
CpuUsageTask Get_Cpu_Us 2f432560   40     0% (       0)    0% (       0)
ipcom_tickd             2e5e0ef0   40     0% (       0)    0% (       0)
tNetTask     netTask    2f434fa0   50     0% (       1)    0% (       1)
monitor      monitorTas 2eda2880   50     0% (       0)    0% (       0)
timer_util              2e6efb60   51     0% (       0)    0% (       0)
tPortmapd    portmapd   2edaeeb0   54     0% (       0)    0% (       0)
ifa_Prt                  69f4ff0   58     0% (       0)    0% (       0)
DmmListenTas            2e69ac50   60     0% (       0)    0% (       0)
DmmSendTask             2e6aa610   61     0% (       0)    0% (       0)
DmmRecvTask             2e6a2930   61     0% (       0)    0% (       0)
ipcom_syslog            2e60da20   70     0% (       0)    0% (       0)
ipsshd       ipssh      2e5e5130   70     0% (       0)    0% (       0)
cps                      7f70460   81     0% (       0)    0% (       0)
cpa                      7f39670   81     0% (       0)    0% (       0)
phyStatus    phyStatusC 2eda6650  100     0% (       0)    0% (       0)
tTftpdTask   tftpdTask  2e6ffb40  100     0% (       0)    0% (       0)
tHwm                    2ff42ae0  101     0% (       0)    0% (       0)
gfm                      7f510e0  101     0% (       0)    0% (       0)
HWM_socket               6eb1e20  101     0% (       0)    0% (       0)
SDD_1HZInt   sdd_1HZInt 2ffbe810  106     0% (       0)    0% (       0)
SFT_CheckTas            2e68b0c0  131     0% (       0)    0% (       0)
SFT_SwitchTa            2e682ed0  131     0% (       0)    0% (       0)
te_schdl                 78a30a0  160     0% (       0)    0% (       0)
DmmLinkCtrlT            2e692f70  166     0% (       0)    0% (       0)
ppp_ctl                  7ed5930  170     0% (       0)    0% (       0)
Ipinip       Ipinip_Tas  6868e80  170     0% (       0)    0% (       0)
IpTunnel     IpTunnel_T  36c2f40  170     0% (       0)    0% (       0)
OsiLight     OsiLight    3879370  170     0% (       0)    0% (       0)
DALLAS_OVERF             7f02c50  171     0% (       0)    0% (       0)
ppp_rcv                  7ee6370  171     0% (       0)    0% (       0)
ppp_snd                  7ec4ef0  171     0% (       0)    0% (       0)
TM_daemon               2e89e660  179     0% (       0)    0% (       0)
AmmBringUpTa            2e652b20  179     0% (       0)    0% (       0)
DCC_IF                  2ffb3db0  180     0% (       0)    0% (       0)
DCC                     2ffa3240  180     0% (       0)    0% (       0)
ccs                      7fae0a0  180     0% (       0)    0% (       0)
tFtpdTask                6ed6060  180     0% (       0)    0% (       0)
tDtlRecvMsg  dtl_socket 2e8694c0  181     0% (       0)    0% (       0)
tSnmp                   2ff926d0  181     0% (       0)    0% (       0)
GCB                     2ff62320  181     0% (       0)    0% (       0)
GCM                     2ff5a510  181     0% (       0)    0% (       0)
GRM                     2ff52700  181     0% (       0)    0% (       0)
cli                      7f0a930  181     0% (       0)    0% (       0)
cli_console              6d10710  181     0% (       0)    0% (       0)
GCB_socket_t             6863e20  181     0% (       0)    0% (       0)
GCB_TSB_sock             685bfe0  181     0% (       0)    0% (       0)
tAgentX      snmpAgentX  6847790  181     0% (       0)    0% (       0)
GMSL1                    66c9510  181     0% (       0)    0% (       0)
GMSL2                    3e94db0  181     0% (       0)    0% (       0)
tPsm_Sync                66932d0  191     0% (       0)    0% (       0)
rpr_rpm                  7f21fd0  200     0% (       0)    0% (       0)
tSnmpTmr     timerTask   6cf4740  200     0% (       0)    0% (       0)
pcm                     2ff0f840  201     0% (       0)    0% (       0)
spm                      7f68780  201     0% (       1)    0% (       1)
ccs_mib                  6d3bea0  210     0% (       0)    0% (       0)
fmm_LedPolli             69c4b00  210     0% (       0)    0% (       0)
fmm_SendAlar             69b63e0  210     0% (       0)    0% (       0)
fmm_ProcessA             69ae700  210     0% (       0)    0% (       0)
SFT_SynTask             2e67afe0  221     0% (       0)    0% (       0)
SFT_PollTask            2e6730f0  221     0% (       0)    0% (       0)
SDD_Slot_Mon sdd_SlotSe 2ffbbd90  221     0% (       0)    0% (       0)
SDD_Slot_Pol sdd_slotPo 2ffb9310  221     0% (       0)    0% (       0)
cmi                      7fd8d70  221     0% (       0)    0% (       0)
cmc                      7fd1090  221     0% (       0)    0% (       0)
cpc                      7f78140  221     0% (       0)    0% (       0)
pm_manager               7fffdd0  226     0% (       0)    0% (       0)
pm_agent                 7ff80f0  226     0% (       0)    0% (       0)
fma_agent                7ff0410  226     0% (       0)    0% (       0)
fm_convert               7fb5d80  226     0% (       0)    0% (       0)
ifa                      7f95980  228     0% (       0)    0% (       0)
cad                      7fc6ca0  230     0% (       0)    0% (       0)
ifm                      7f87b00  230     0% (       0)    0% (       0)
tTffsPTask   flPollTask 2f77e9c0  231     0% (       0)    0% (       0)
tMibMgr                 2e663230  231     0% (       0)    0% (       0)
tMibRmt                 2e65aad0  231     0% (       0)    0% (       0)
tLcm                    2ff71f40  231     0% (       0)    0% (       0)
lea                     2ff3abf0  231     0% (       0)    0% (       0)
lem                     2ff32de0  231     0% (       0)    0% (       0)
cfa                     2ff2afd0  231     0% (       0)    0% (       0)
tod                     2ff231c0  231     0% (       0)    0% (       0)
tmi                      7fe8730  231     0% (       0)    0% (       0)
cai                      7fe0a50  231     0% (       0)    0% (       0)
fm_mgr                   7fbefc0  231     0% (       0)    0% (       0)
m4m                      7fa63c0  231     0% (       0)    0% (       0)
oam                      7f7fe20  231     0% (       0)    0% (       0)
Msm                      7f60aa0  231     0% (       0)    0% (       0)
mpm                      7f58dc0  231     0% (       0)    0% (       0)
cpm                      7f41350  231     0% (       0)    0% (       0)
epm                      7f31990  231     0% (       0)    0% (       0)
UDM                      7f29cb0  231     0% (       0)    0% (       0)
prbs_manager             7f1a2f0  231     0% (       0)    0% (       0)
c80_s                    7f12610  231     0% (       0)    0% (       0)
tMibRmt1                 6ef4a00  231     0% (       0)    0% (       0)
tMibRmt2                 6eecd20  231     0% (       0)    0% (       0)
tCfCardPoll  cfCardPoll  69daa80  231     0% (       0)    0% (       0)
tod_SCP      tod_System  69d8130  231     0% (       0)    0% (       0)
tmi_MsgTask              666ee50  231     0% (       0)    0% (       0)
SDD          sdd_PollTa 2ffc3b80  232     1% (       5)    1% (       5)
tUpgrade                2ff81b60  232     0% (       0)    0% (       0)
tMfm                    2ff79d50  232     0% (       0)    0% (       0)
tFtm                    2ff6a130  232     0% (       0)    0% (       0)
tTrap                    7878890  232     0% (       0)    0% (       0)
m4m_socket               69a6a20  232     0% (       0)    0% (       0)
trap_dest_1  trapWorkTa  34bfda0  232     0% (       0)    0% (       0)
trap_dest_2  trapWorkTa  34aca10  232     0% (       0)    0% (       0)
ael_EventMsg             66d11f0  235     0% (       0)    0% (       0)
SDD_CardPre  sdd_Pollin 2ffb6890  236     0% (       0)    0% (       0)
ael                     2ff1b3b0  236     0% (       0)    0% (       0)
cmi_Poll                 7849ea0  236     0% (       0)    0% (       0)
lea_LedPolli             69e2760  236     0% (       0)    0% (       0)
slowJOB      slowJobTas 2f72efb0  238     0% (       0)    0% (       0)
slowJOB2     slowJobTas 2f72c570  238     0% (       0)    0% (       0)
pinger                   7516180  238     0% (       0)    0% (       0)
fmc_DefectPr fmc_Defect  6ab88a0  238    14% (      44)   14% (      44)
fma_DefectPr fma_Defect  69f8cd0  238     0% (       0)    0% (       0)
ifa_Poll                 69eb9a0  238     0% (       0)    0% (       0)
tPsm                    2ff4a8f0  241     0% (       0)    0% (       0)
tMibSaver                6ed2380  241     0% (       0)    0% (       0)
tGCM_Save                6d074d0  241     0% (       0)    0% (       0)
tGCM_Test_St             6cff7f0  241     0% (       0)    0% (       0)
tPsm_Backup              6727480  241     0% (       0)    0% (       0)
tPsm_Save                671f7a0  241     0% (       0)    0% (       0)
tDcacheUpd   dcacheUpd  2e610a10  250     0% (       0)    0% (       0)
Pmm_WriteFil             6ab4bc0  250     0% (       0)    0% (       0)
Pmm_WritexSe             6aacee0  250     0% (       0)    0% (       0)
tDtlPrintMsg dtl_PrintP 2e71a870  251     6% (      18)    6% (      18)
SFT_FileTask            2e66b120  251    12% (      36)   12% (      36)
tDtldmmMsg              2e642c20  251     0% (       0)    0% (       0)
ael_LogTask              66dcc30  251     0% (       0)    0% (       0)
tPbPrint     printTask  2f7898c0  252     0% (       0)    0% (       0)
security_log             6eca6a0  253     0% (       1)    0% (       1)
StackCheck              2e717c60  254     0% (       1)    0% (       1)
trapTest                 786d030  254     0% (       0)    0% (       0)
Idle                    2e70fe50  255    63% (     187)   63% (     187)
KERNEL                                    0% (       1)    0% (       1)
INTERRUPT                                 0% (       0)    0% (       0)
IDLE                                      0% (       0)    0% (       0)
TOTAL