Implementation
Delay job
The CPU load is implemented with the help of the PXROS-HR feature called Delay job. The Delay job is a PXROS-HR time object with associated function that runs as a kernel service after the configurable timeout is reached. The service runs in the context of the task that created this delay job, but as it runs as a kernel service, it has higher priority than any task in the system.
The purpose of the Delay job function is to read the reached variable count at precise time intervals and store it in the buffer for later processing. Before returning, the Delay job restarts itself to maintain periodic behavior.
Sysload data structure
The Sysload module uses the below structure to store all data necessary for computing the CPU load and controlling its execution.
#define BUFFERENTRIES 64 /* Size of averaging buffer (FIR filter length) */
typedef struct
{
/* Delay-job object whose function is called every "Time" ticks */
PxDelay_t Delay;
/* Period of system load measurements (argument to delay-job) */
PxTicks_t Time;
/* Stop flag used to stop the "Cnt" counting */
volatile PxBool_t Stop;
/* Count variable for evaluating the idle time */
volatile PxULong_t Cnt;
/* Reference "Cnt" value of unloaded system (got after calibration) */
PxULong_t Base;
/* Attribute indicating validity of filtered system load value */
PxBool_t Valid;
/* Temporary variable for computing time delta */
PxULong_t Old;
/* Temporary sum of N values used for FIR filtering (N=BUFFERENTRIES) */
PxUInt64_t Sum;
/* Index to "Buffer" where to store last value for FIR filtering */
PxUInt_t Idx;
/* Buffer for FIR filtering */
PxUInt_t Buffer[BUFFERENTRIES];
/* Temporary debug variable - remove in real application */
PxULong_t debugLoad;
} PxuSysload_T;
The structure is defined as a global variable because some data members need to be shared between tasks. In the PXROS-HR application, tasks can only share data using messages or via global data regions (when proper data access is given). Messages would make the implementation significantly more complex, so the global data approach has been used. In this case, sharing data is possible by simply writing to and reading from the global structure because data consistency is achieved by the application design.
Data placement
The Sysload data structure is placed in the 0xD0000000-addressed memory space, which means that the instance of that structure is mirrored to N different globally-addressed data memory spaces. In other words, there are N unique instances visible from different CPUs. More implementation details and exact placement strategy using linker scripts can be found in the TC39x PXROS-HR CPU Load Example - Quick Guide.
Data integrity
The current implementation ensures data integrity by the use of Delay Job, which has a higher priority than any task. The data being modified by the handler can only be read by any task after the modification is complete. The result is then exchanged via the Sysload.Sum variable, which is a 32-bit number and therefore, the data access is atomic.