mirror of
https://gitee.com/Lamdonn/varch.git
synced 2025-12-06 16:56:42 +08:00
212 lines
7.1 KiB
C
212 lines
7.1 KiB
C
/*********************************************************************************************************
|
|
* ------------------------------------------------------------------------------------------------------
|
|
* file description
|
|
* ------------------------------------------------------------------------------------------------------
|
|
* \file cpul.c
|
|
* \unit cpul
|
|
* \brief This is a simple cpuload module for C language
|
|
* \author Lamdonn
|
|
* \version v1.0.0
|
|
* \license GPL-2.0
|
|
* \copyright Copyright (C) 2023 Lamdonn.
|
|
********************************************************************************************************/
|
|
#include "cpul.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
// Buffer for CRC calculation, initialized with some values
|
|
uint8_t calbuffer[CPUL_GEN_BSIZE] = {'A', 'B', 0};
|
|
|
|
/**
|
|
* \brief Adjust the refined load based on current and target loads.
|
|
*
|
|
* This function controls the refined load adjustment by comparing
|
|
* the current load with the target load and modifying the refined
|
|
* load accordingly.
|
|
*
|
|
* \param[in] cpul: Pointer to the CPUL instance.
|
|
* \return Returns the adjusted refined load value.
|
|
*/
|
|
static uint32_t controller(CPUL *cpul)
|
|
{
|
|
// If the current load is less than the target load
|
|
if (cpul->ctrl.cload < cpul->ctrl.tload)
|
|
{
|
|
// If adding resolution to refined load does not exceed its current value
|
|
if (cpul->ctrl.refine + cpul->resolution > cpul->ctrl.refine)
|
|
{
|
|
// Increase the refined load by the resolution value
|
|
cpul->ctrl.refine += cpul->resolution;
|
|
}
|
|
}
|
|
// If the current load is greater than target load + 1
|
|
else if (cpul->ctrl.cload > (cpul->ctrl.tload + 1))
|
|
{
|
|
// If the refined load is greater than or equal to the resolution
|
|
if (cpul->ctrl.refine >= cpul->resolution)
|
|
{
|
|
// Decrease the refined load by the resolution value
|
|
cpul->ctrl.refine -= cpul->resolution;
|
|
}
|
|
}
|
|
|
|
return cpul->ctrl.refine; // Return the adjusted refined load
|
|
}
|
|
|
|
/**
|
|
* \brief Calculate CRC8 checksum.
|
|
*
|
|
* This function computes the CRC8 checksum for a given data buffer.
|
|
* It iterates through each byte of data and processes it to generate
|
|
* the CRC value.
|
|
*
|
|
* \param[in] data: Pointer to the data buffer.
|
|
* \param[in] len: Length of the data buffer.
|
|
* \return Returns the calculated CRC8 value.
|
|
*/
|
|
static uint8_t crc8(uint8_t *data, uint32_t len)
|
|
{
|
|
uint8_t i; // Loop index for bit processing
|
|
uint8_t crc = 0; // Initialize CRC value to 0
|
|
while (len--) // Process each byte in the data buffer
|
|
{
|
|
crc ^= *data++; // XOR the current byte with the CRC value
|
|
for (i = 0; i < 8; i++) // Process each bit of the byte
|
|
{
|
|
if (crc & 0x80) // If the highest bit of CRC is set
|
|
crc = (crc << 1) ^ 0x07; // Shift left and XOR with the polynomial
|
|
else
|
|
crc <<= 1; // Just shift left if the highest bit is not set
|
|
}
|
|
}
|
|
return crc; // Return the calculated CRC8 value
|
|
}
|
|
|
|
/**
|
|
* \brief Update the granularity of the load control.
|
|
*
|
|
* This function updates the calbuffer values based on the refined load
|
|
* using CRC8 checksum for each iteration specified by the input parameter.
|
|
*
|
|
* \param[in] input: Number of iterations to update the buffer.
|
|
* \return none.
|
|
*/
|
|
static void granularity(uint32_t input)
|
|
{
|
|
// Loop through the specified number of iterations
|
|
for (uint32_t i = 0; i < input; i++)
|
|
{
|
|
// Update calbuffer with a CRC8 value calculated from the current buffer
|
|
calbuffer[calbuffer[0] % sizeof(calbuffer)] = crc8(calbuffer, sizeof(calbuffer));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Initialize the CPUL instance.
|
|
*
|
|
* This function initializes the CPUL structure to default values
|
|
* and checks for valid pointers.
|
|
*
|
|
* \param[in] cpul: Pointer to the CPUL instance.
|
|
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
|
*/
|
|
int cpul_init(CPUL *cpul)
|
|
{
|
|
// Check if the cpul pointer is valid
|
|
if (!cpul) return CPUL_E_INVALID;
|
|
// Check if the raw function pointer is valid
|
|
if (!cpul->raw) return CPUL_E_RAW;
|
|
|
|
cpul->ctrl.cload = 0xFFFF; // Set current load to untested value
|
|
cpul->ctrl.tload = 0; // Default target load to zero (no load increase)
|
|
cpul->ctrl.refine = 0; // Initialize refined load
|
|
|
|
return CPUL_E_OK; // Initialization successful
|
|
}
|
|
|
|
/**
|
|
* \brief Get the current CPU load.
|
|
*
|
|
* This function retrieves the current load from the CPUL instance
|
|
* and checks for validity of parameters and state.
|
|
*
|
|
* \param[in] cpul: Pointer to the CPUL instance.
|
|
* \param[out] load: Pointer to store the current load value.
|
|
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
|
*/
|
|
int cpul_get(CPUL *cpul, uint16_t *load)
|
|
{
|
|
// Check if the cpul pointer is valid
|
|
if (!cpul) return CPUL_E_INVALID;
|
|
// Check if the raw function pointer is valid
|
|
if (!cpul->raw) return CPUL_E_RAW;
|
|
// Check if the load parameter is valid
|
|
if (!load) return CPUL_E_PARA;
|
|
|
|
// If current load is still untested, return an error
|
|
if (cpul->ctrl.cload == 0xFFFF) return CPUL_E_NTEST;
|
|
// Check if the current load exceeds the maximum allowed value
|
|
if (cpul->ctrl.cload > 10000) return CPUL_E_OVER;
|
|
|
|
*load = cpul->ctrl.cload; // Retrieve the current load value
|
|
|
|
return CPUL_E_OK; // Success
|
|
}
|
|
|
|
/**
|
|
* \brief Set the target CPU load.
|
|
*
|
|
* This function sets the target load for the CPUL instance and checks for valid parameters.
|
|
*
|
|
* \param[in] cpul: Pointer to the CPUL instance.
|
|
* \param[in] load: Target load value to set.
|
|
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
|
*/
|
|
int cpul_set(CPUL *cpul, uint16_t load)
|
|
{
|
|
// Check if the cpul pointer is valid
|
|
if (!cpul) return CPUL_E_INVALID;
|
|
// Check if the raw function pointer is valid
|
|
if (!cpul->raw) return CPUL_E_RAW;
|
|
// Check if the load parameter is zero
|
|
if (!load) return CPUL_E_PARA;
|
|
|
|
// Check if the load exceeds the maximum allowed value
|
|
if (load > 10000) return CPUL_E_OVER;
|
|
|
|
cpul->ctrl.tload = load; // Set the target load
|
|
|
|
return CPUL_E_OK; // Success
|
|
}
|
|
|
|
/**
|
|
* \brief Execute a CPUL management task.
|
|
*
|
|
* This function executes a task to manage the CPU load based on
|
|
* the current and target load values.
|
|
*
|
|
* \param[in] cpul: Pointer to the CPUL instance.
|
|
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
|
*/
|
|
int cpul_task(CPUL *cpul)
|
|
{
|
|
// Check if the cpul pointer is valid
|
|
if (!cpul) return CPUL_E_INVALID;
|
|
// Check if the raw function pointer is valid
|
|
if (!cpul->raw) return CPUL_E_RAW;
|
|
|
|
// Call the raw function to get the current load value
|
|
cpul->ctrl.cload = cpul->raw(cpul->coreid);
|
|
|
|
// If the target load is not zero, perform load management
|
|
if (cpul->ctrl.tload != 0)
|
|
{
|
|
// Adjust the refined load based on current and target load
|
|
cpul->ctrl.refine = controller(cpul);
|
|
// Update granularity based on the refined load
|
|
granularity(cpul->ctrl.refine);
|
|
}
|
|
|
|
return CPUL_E_OK; // Success
|
|
}
|