Querying CPU data (generic)

This sample demonstrates access to CPU data by the IPC diagnostics via the generic function block FB_MDP_ReadElement.

The program is structured in such a way that it can easily be adapted for access to other IPC diagnostics modules. Program lines, which have to be modified to adapt the program to other IPC diagnostics modules, are identified in the comment with the string //**.

Following the program code of the sample you will find the textual Description of the sample program.

Sample: access via the generic function block FB_MDP_ReadElement

Individual CPU data can be read via a subindex in module CPU in the Configuration Area of the IPC diagnostics. The generic function block FB_MDP_ReadElement is used for this purpose.

Enumeration definition

//** = simply adjust these lines if modifying code for own purposes
 
// central definition of state machine states
// (supports easy program modification)
{attribute 'qualified_only'}
TYPE E_State :
(
    Idle,
    ReadCPUusageInit,      //** initiate reading CPU usage
    ReadCPUusageProcess    //** process reading CPU usage
);
END_TYPE

Variable Declaration

PROGRAM MAIN
VAR
    // internal use
    sAmsNetId           : STRING := '';       //** ADS Net ID (local = '')    
    eState              : E_State;            // Enum with index for state machine     
    bStart              : BOOL := TRUE;       // flag to trigger (re)start of statemachine
    nData               : UINT;               // data storage for unsigned integer     
    stMDP_Addr          : ST_MDP_Addr;        // structure will include all address parameters  
    
    // FB instances
    fbReadMDPElement    : FB_MDP_ReadElement; // instance of FB for reading MDP element  

    // results of execution
    bError              : BOOL;               // error flag (indicator: error occured)
    nErrID              : UDINT;              // last error ID
    nCpuUsage           : UINT;               // buffer for CPU usage (%)
END_VAR 

Program code

// For an easy re-use of the following code for own purposes, parts of this sample program use
// "general" data names (and copy the results in specific variables after processing the code).
 
CASE eState OF
    E_State.Idle:
        IF bStart THEN
            bStart := FALSE;
            eState := E_State.ReadCPUusageInit; //** initiate first state
        END_IF

    E_State.ReadCPUusageInit:    
        stMDP_Addr.nArea    := INT_TO_BYTE(eMDP_Area_ConfigArea); //** set area address to "Config Area"
        stMDP_Addr.nTableId := 1;              //** table ID in module for "cpu properties"
        stMDP_Addr.nSubIdx  := 2;              //** subindex in table ID for "CPU usage"                     
        
        fbReadMDPElement(
            bExecute    := TRUE,               // Flag: trigger execution of FB
            eModuleType := eMDP_ModT_CPU,      //** desired module type = CPU         
            stMDP_Addr  := stMDP_Addr,         // MDP address structure. Dynamic module ID added internally. 
            iModIdx     := 0,                  //** instance of desired module type (0 = first instance) 
            pDstBuf     := ADR(nData),         // buffer for storing data
            cbDstBufLen := SIZEOF(nData),      // length of buffer
            sAmsNetId   := sAmsNetId,          // AMS Net ID
            );                                 //** Note: fbReadMDPElement.tTimeOut must be > cycle time!

        eState := E_State.ReadCPUusageProcess;  //** next state: process FB
            
    E_State.ReadCPUusageProcess:                //** process FB: request CPU data
        fbReadMDPElement(bExecute := FALSE);   // Flag: Get execution state of FB 
                                               //** Note: fbReadMDPElement.tTimeOut must be > cycle time!

        IF NOT fbReadMDPElement.bBusy THEN     // FB executed?
            IF fbReadMDPElement.bError THEN    // Error?
                bError    := TRUE;             // set error flag
                nErrID    := fbReadMDPElement.nErrID; // store error id (16#ECA60105 = BIOS or HW does 
                                               // not support this data (here: mainboard data))
                eState    := E_State.Idle;     // finish state machine
            ELSE                               // set parameters for next steps
                bError    := FALSE;            // turn off error flag
                nCpuUsage := nData;            //** store CPU usage in dedicated variable
                eState    := E_State.ReadCPUusageInit; //** next state 
            END_IF
        END_IF
    
END_CASE 

Description of the sample program

The function block FB_MDP_ReadElement requires at least the parameters listed below:

Querying CPU data (generic) 1:
Querying CPU data (generic) 2:

The output values of the function block are described here for completeness:

Querying CPU data (generic) 3:

A very important role is played by the structure for addressing the desired information. It is described by the data type ST_MDP_Addr:

Querying CPU data (generic) 4:

There are two possibilities to determine the parameter "nArea":

Querying CPU data (generic) 5:

The parameter "nModule" is NOT an input parameter. The module address (=ModuleID) determined by the function block is assigned to it after it has determined the desired module instance.

"nTableId" corresponds to the right-hand 4 bits of the table index (yellow arrow).

"Subindex" is the number of the entry in the table (blue arrow).

The "eModuleType" parameter specifies the type of the module. There is also an enumeration for the module type that can be used for better readability of the program:

Querying CPU data (generic) 6:

Alternatively the value can also be taken from the module description and entered directly.

Structure of the state machine

The states of the state machine are defined via enumeration values in a DUT and can thus be adapted or extended centrally and easily.

Querying CPU data (generic) 7:

Functional areas of the state machine

Querying CPU data (generic) 8:

Input and output parameters of the sample program

Querying CPU data (generic) 9:
Querying CPU data (generic) 10:
Querying CPU data (generic) 11: