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:


- A memory area for the MDP address structure
- The MDP module types
- The address and size of the memory area for the output data of the function block
- The AMS address (AMS Net ID)
The output values of the function block are described here for completeness:

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

There are two possibilities to determine the parameter "nArea":
- The individual areas are stored as enumerations in the Tc2_MDP library. This entry can be used as easily readable input parameter (dashed red arrow).
- The value for the area can alternatively be taken from the index of a table (left-hand 4 bits - red arrow)

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:

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.

Functional areas of the state machine

Input and output parameters of the sample program


