From 4eca03352377fc1c88396028c891ba3d1b4713c1 Mon Sep 17 00:00:00 2001 From: wuhaotian <694496640@qq.com> Date: Sun, 27 Nov 2022 11:13:28 +0800 Subject: [PATCH] Add cpu freq range get and set function --- common/inc/pwrdata.h | 4 ++ common/inc/pwrmsg.h | 2 + pwrapic/inc/powerapi.h | 2 + pwrapic/inc/pwrcpu.h | 2 + pwrapic/src/powerapi.c | 16 +++++++ pwrapic/src/pwrcpu.c | 38 ++++++++++++++++ pwrapic/test/demo_main.c | 27 +++++++++++- pwrapis/inc/cpuservice.h | 2 + pwrapis/inc/utils.h | 3 ++ pwrapis/src/cpuservice.c | 95 +++++++++++++++++++++++++++++++++++++++- pwrapis/src/server.c | 5 +++ pwrapis/src/utils.c | 51 +++++++++++++++++++++ 12 files changed, 245 insertions(+), 2 deletions(-) diff --git a/common/inc/pwrdata.h b/common/inc/pwrdata.h index a3b9e6e..914724b 100644 --- a/common/inc/pwrdata.h +++ b/common/inc/pwrdata.h @@ -146,6 +146,10 @@ typedef struct PWR_CPU_FreqAbility { char freqDomain[0]; } PWR_CPU_FreqAbility; +typedef struct PWR_CPU_FreqRange { + int minFreq; + int maxFreq; +} PWR_CPU_FreqRange; typedef struct PWR_CPU_CurFreq { int policyId; diff --git a/common/inc/pwrmsg.h b/common/inc/pwrmsg.h index 8366692..e6ebdd7 100644 --- a/common/inc/pwrmsg.h +++ b/common/inc/pwrmsg.h @@ -57,6 +57,8 @@ enum OperationType { CPU_GET_USAGE, CPU_GET_PERF_DATA, CPU_GET_FREQ_ABILITY, + CPU_GET_FREQ_RANGE, + CPU_SET_FREQ_RANGE, CPU_GET_FREQ_GOVERNOR, CPU_SET_FREQ_GOVERNOR, CPU_GET_CUR_FREQ, diff --git a/pwrapic/inc/powerapi.h b/pwrapic/inc/powerapi.h index ad916a0..9767bb9 100644 --- a/pwrapic/inc/powerapi.h +++ b/pwrapic/inc/powerapi.h @@ -46,6 +46,8 @@ PWR_API int PWR_CPU_GetInfo(PWR_CPU_Info *cpuInfo); PWR_API int PWR_CPU_GetUsage(PWR_CPU_Usage *usage, uint32_t bufferSize); PWR_API int PWR_CPU_GetPerfData(PWR_CPU_PerfData *perfData); PWR_API int PWR_CPU_GetFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize); +PWR_API int PWR_CPU_GetFreqRange(PWR_CPU_FreqRange *freqRange); +PWR_API int PWR_CPU_SetFreqRange(const PWR_CPU_FreqRange *freqRange); PWR_API int PWR_CPU_GetFreqGovernor(char gov[], uint32_t size); // len: MAX_ELEMENT_NAME_LEN PWR_API int PWR_CPU_SetFreqGovernor(const char gov[]); PWR_API int PWR_CPU_GetFreq(PWR_CPU_CurFreq curFreq[], uint32_t *len, int spec); diff --git a/pwrapic/inc/pwrcpu.h b/pwrapic/inc/pwrcpu.h index 69bce2a..0483a6c 100644 --- a/pwrapic/inc/pwrcpu.h +++ b/pwrapic/inc/pwrcpu.h @@ -21,6 +21,8 @@ int GetCpuInfo(PWR_CPU_Info *cpuInfo); int GetCpuUsage(PWR_CPU_Usage *usage, uint32_t bufferSize); int GetCpuPerfData(PWR_CPU_PerfData *perfData); int GetCpuFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize); +int GetCpuFreqRange(PWR_CPU_FreqRange *freqRange); +int SetCpuFreqRange(const PWR_CPU_FreqRange *freqRange); int GetCpuFreqGovernor(char gov[], uint32_t size); int SetCpuFreqGovernor(const char gov[], uint32_t size); int GetCpuCurFreq(PWR_CPU_CurFreq curFreq[], uint32_t *len, int spec); diff --git a/pwrapic/src/powerapi.c b/pwrapic/src/powerapi.c index 4ebbe38..214318c 100644 --- a/pwrapic/src/powerapi.c +++ b/pwrapic/src/powerapi.c @@ -197,6 +197,22 @@ int PWR_CPU_GetFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize) return GetCpuFreqAbility(freqAbi, bufferSize); } +int PWR_CPU_GetFreqRange(PWR_CPU_FreqRange *freqRange) +{ + CHECK_STATUS(STATUS_REGISTERTED); + CHECK_NULL_POINTER(freqRange); + + return GetCpuFreqRange(freqRange); +} + +int PWR_CPU_SetFreqRange(const PWR_CPU_FreqRange *freqRange) +{ + CHECK_STATUS(STATUS_AUTHED); + CHECK_NULL_POINTER(freqRange); + + return SetCpuFreqRange(freqRange); +} + int PWR_CPU_GetFreqGovernor(char gov[], uint32_t size) { CHECK_STATUS(STATUS_REGISTERTED); diff --git a/pwrapic/src/pwrcpu.c b/pwrapic/src/pwrcpu.c index c1d3166..9a814b8 100644 --- a/pwrapic/src/pwrcpu.c +++ b/pwrapic/src/pwrcpu.c @@ -105,6 +105,44 @@ int GetCpuFreqAbility(PWR_CPU_FreqAbility *freqAbi, uint32_t bufferSize) return ret; } +int GetCpuFreqRange(PWR_CPU_FreqRange *freqRange) +{ + ReqInputParam input; + input.optType = CPU_GET_FREQ_RANGE; + input.dataLen = 0; + input.data = NULL; + RspOutputParam output; + uint32_t size = sizeof(PWR_CPU_FreqRange); + output.rspBuffSize = &size; + output.rspData = (void *)freqRange; + int ret = SendReqAndWaitForRsp(input, output); + if (ret != SUCCESS) { + PwrLog(ERROR, "GetCpuFreqRange failed. ret:%d", ret); + } else { + PwrLog(DEBUG, "GetCpuFreqRange Succeed."); + } + return ret; +} + +int SetCpuFreqRange(const PWR_CPU_FreqRange *freqRange) +{ + ReqInputParam input; + input.optType = CPU_SET_FREQ_RANGE; + input.dataLen = sizeof(PWR_CPU_FreqRange); + input.data = (char *)freqRange; + RspOutputParam output; + output.rspBuffSize = NULL; + output.rspData = NULL; + + int ret = SendReqAndWaitForRsp(input, output); + if (ret != SUCCESS) { + PwrLog(ERROR, "SetCpuFreqRange failed. ret:%d", ret); + } else { + PwrLog(DEBUG, "SetCpuFreqRange Succeed."); + } + return ret; +} + int GetCpuFreqGovernor(char gov[], uint32_t size) { ReqInputParam input; diff --git a/pwrapic/test/demo_main.c b/pwrapic/test/demo_main.c index adefd7b..00fd64b 100644 --- a/pwrapic/test/demo_main.c +++ b/pwrapic/test/demo_main.c @@ -26,6 +26,9 @@ #define TEST_CPU_DMA_LATENCY 2000 #define TASK_INTERVAL 1000 #define TASK_RUN_TIME 10 +#define TEST_FREQ_RANGE_MIN 1100 +#define TEST_FREQ_RANGE_MAX 2500 + static int g_run = 1; enum { @@ -198,6 +201,26 @@ static void TEST_PWR_CPU_GetFreqAbility(void) free(freqAbi); } +static void TEST_PWR_CPU_GetAndSetFreqRange(void) +{ + int ret = 0; + int len = sizeof(PWR_CPU_FreqRange); + PWR_CPU_FreqRange *freqRange = (PWR_CPU_FreqRange *)malloc(len); + if (!freqRange) { + return; + } + bzero(freqRange, len); + ret = PWR_CPU_GetFreqRange(freqRange); + printf("PWR_CPU_GetFreqRange ret: %d, MinFreq:%d, MaxFreq: %d\n", ret, freqRange->minFreq, freqRange->maxFreq); + freqRange->minFreq = TEST_FREQ_RANGE_MIN; + freqRange->maxFreq = TEST_FREQ_RANGE_MAX; + ret = PWR_CPU_SetFreqRange(freqRange); + printf("PWR_CPU_SetFreqRange ret: %d\n", ret); + ret = PWR_CPU_GetFreqRange(freqRange); + printf("PWR_CPU_GetFreqRange ret: %d, MinFreq:%d, MaxFreq: %d\n", ret, freqRange->minFreq, freqRange->maxFreq); + free(freqRange); +} + static void TEST_PWR_CPU_SetAndGetFreqGov(void) { int ret = 0; @@ -302,13 +325,15 @@ int main(int argc, const char *args[]) TEST_PWR_CPU_GetFreqAbility(); // PWR_CPU_GetFreqGovernor PWR_CPU_SetFreqGovernor - TEST_PWR_CPU_SetAndGetFreqGov(); + // TEST_PWR_CPU_SetAndGetFreqGov(); TEST_SYS_GetRtPowerInfo(); // TEST_SYS_SetPowerState(); // PWR_CPU_GetCurFreq PWR_CPU_SetCurFreq TEST_PWR_CPU_SetAndGetCurFreq(); + TEST_PWR_CPU_GetAndSetFreqRange(); + // PWR_CPU_DmaSetLatency PWR_CPU_DmaGetLatency // TEST_PWR_CPU_DmaSetAndGetLatency(); // TEST_PWR_COM_DcTaskMgr(); diff --git a/pwrapis/inc/cpuservice.h b/pwrapis/inc/cpuservice.h index c767c8e..78a7a20 100644 --- a/pwrapis/inc/cpuservice.h +++ b/pwrapis/inc/cpuservice.h @@ -28,5 +28,7 @@ int CPUUsageRead(PWR_CPU_Usage *rstData, int coreNum); void GetCpuFreqGovernor(PwrMsg *req); void SetCpuFreqGovernor(PwrMsg *req); void GetCpuFreqAbility(PwrMsg *req); +void GetCpuFreqRange(PwrMsg *req); +void SetCpuFreqRange(PwrMsg *req); int GetCpuCoreNumber(void); #endif diff --git a/pwrapis/inc/utils.h b/pwrapis/inc/utils.h index e74b506..0cafcd1 100644 --- a/pwrapis/inc/utils.h +++ b/pwrapis/inc/utils.h @@ -234,5 +234,8 @@ int DeleteSubstr(char *str, char *substr); char *StrMatch(char *str, char *want); void StrCopy(char *dest, const char *src, int destSize); int InIntRange(int *range, int len, int a); +int ReadFile(const char *strInfo, char *buf, int bufLen); +int WriteFile(const char *strInfo, char *buf, int bufLen); +int WriteFileAndCheck(const char *strInfo, char *buf, int bufLen); #endif diff --git a/pwrapis/src/cpuservice.c b/pwrapis/src/cpuservice.c index fbfc7c8..5495017 100644 --- a/pwrapis/src/cpuservice.c +++ b/pwrapis/src/cpuservice.c @@ -13,13 +13,14 @@ * Description: provide cpu service * **************************************************************************** */ -#include "cpuservice.h" +#include "fcntl.h" #include "string.h" #include "pwrerr.h" #include "server.h" #include "log.h" #include "unistd.h" #include "utils.h" +#include "cpuservice.h" const char cpuAttributes[MAX_ARRRIBUTES][MAX_NAME_LEN] = { "Architecture", "Model name", "Byte Order", "NUMA node(s)", "NUMA node", "CPU(s)", @@ -218,6 +219,8 @@ int CPUUsageRead(PWR_CPU_Usage *rstData, int coreNum) return ERR_COMMON; } if (UsageToLong(buf1, paras[0], i) != UsageToLong(buf2, paras[1], i)) { + pclose(fp1); + pclose(fp2); return ERR_COMMON; } CalculateUsage(rstData, paras, i); @@ -252,6 +255,7 @@ int PerfDataRead(PWR_CPU_PerfData *perfData) unsigned long cycles = 0; while (fgets(buf, sizeof(buf) - 1, fp) != NULL) { if (buf == NULL) { + pclose(fp); return 1; } DeleteChar(buf, '\n'); @@ -459,6 +463,7 @@ static int FreqRead(PWR_CPU_CurFreq *rstData, char (*policys)[MAX_ELEMENT_NAME_L return 1; } if (fgets(buf, sizeof(buf) - 1, fp) == NULL) { + pclose(fp); return ERR_COMMON; } DeleteChar(buf, '\n'); @@ -707,6 +712,94 @@ void GetCpuFreqAbility(PwrMsg *req) SendRspToClient(req, rspCode, (char *)rstData, sizeof(PWR_CPU_FreqAbility) + step * poNum); } +static int FreqRangeRead(PWR_CPU_FreqRange *rstData) +{ + char buf[MAX_ELEMENT_NAME_LEN] = {0}; + const char minFreqInfo[] = "/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq"; + const char maxFreqInfo[] = "/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq"; + if (ReadFile(minFreqInfo, buf, MAX_ELEMENT_NAME_LEN) != 0) { + return 1; + } + rstData->minFreq = atoi(buf) / THOUSAND; + if (ReadFile(maxFreqInfo, buf, MAX_ELEMENT_NAME_LEN) != 0) { + return 1; + } + rstData->maxFreq = atoi(buf) / THOUSAND; + return 0; +} + +static int FreqRangeSet(PWR_CPU_FreqRange *rstData) +{ + char policys[MAX_CPU_LIST_LEN][MAX_ELEMENT_NAME_LEN] = {0}; + int poNum, i; + if (GetPolicys(policys, &poNum) != 0) { + return 1; + } + char buf[MAX_ELEMENT_NAME_LEN] = {0}; + + // set min freq + if (snprintf(buf, MAX_ELEMENT_NAME_LEN - 1, "%d", rstData->minFreq * THOUSAND) < 0) { + return 1; + } + + char minFreqFile[MAX_NAME_LEN] = {0}; + const char min1[] = "/sys/devices/system/cpu/cpufreq/"; + const char min2[] = "/scaling_min_freq"; + for (i = 0; i < poNum; i++) { + StrCopy(minFreqFile, min1, MAX_NAME_LEN); + strncat(minFreqFile, policys[i], strlen(policys[i])); + strncat(minFreqFile, min2, strlen(min2)); + if (WriteFileAndCheck(minFreqFile, buf, strlen(buf)) != 0) { + return 1; + } + } + + // set max freq + if (snprintf(buf, MAX_ELEMENT_NAME_LEN - 1, "%d", rstData->maxFreq * THOUSAND) < 0) { + return 1; + } + char maxFreqFile[MAX_NAME_LEN] = {0}; + const char max1[] = "/sys/devices/system/cpu/cpufreq/"; + const char max2[] = "/scaling_max_freq"; + for (i = 0; i < poNum; i++) { + StrCopy(maxFreqFile, max1, MAX_NAME_LEN); + strncat(maxFreqFile, policys[i], strlen(policys[i])); + strncat(maxFreqFile, max2, strlen(max2)); + if (WriteFileAndCheck(maxFreqFile, buf, strlen(buf)) != 0) { + return 1; + } + } + return 0; +} + +void GetCpuFreqRange(PwrMsg *req) +{ + if (!req) { + return; + } + Logger(DEBUG, MD_NM_SVR_CPU, "Get GetCpuFreqRange Req. seqId:%u, sysId:%d", req->head.seqId, req->head.sysId); + + PWR_CPU_FreqRange *rstData = malloc(sizeof(PWR_CPU_FreqRange)); + if (!rstData) { + return; + } + int rspCode = FreqRangeRead(rstData); + SendRspToClient(req, rspCode, (char *)rstData, sizeof(PWR_CPU_FreqRange)); +} + +void SetCpuFreqRange(PwrMsg *req) +{ + if (!req) { + return; + } + Logger(DEBUG, MD_NM_SVR_CPU, "Get SetCpuFreqRange Req. seqId:%u, sysId:%d", req->head.seqId, req->head.sysId); + + PWR_CPU_FreqRange *rstData = (PWR_CPU_FreqRange *)req->data; + + int rspCode = FreqRangeSet(rstData); + SendRspToClient(req, rspCode, (char *)rstData, sizeof(PWR_CPU_FreqRange)); +} + // 总CPU核数 int GetCpuCoreNumber(void) { diff --git a/pwrapis/src/server.c b/pwrapis/src/server.c index 88ec849..c47d7c7 100644 --- a/pwrapis/src/server.c +++ b/pwrapis/src/server.c @@ -378,6 +378,11 @@ static void ProcessReqMsg(PwrMsg *req) case CPU_GET_FREQ_ABILITY: GetCpuFreqAbility(req); break; + case CPU_GET_FREQ_RANGE: + GetCpuFreqRange(req); + break; + case CPU_SET_FREQ_RANGE: + SetCpuFreqRange(req); default: break; } diff --git a/pwrapis/src/utils.c b/pwrapis/src/utils.c index 108cad9..114c7c6 100644 --- a/pwrapis/src/utils.c +++ b/pwrapis/src/utils.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #define SUCCESS 0 @@ -907,3 +909,52 @@ int InIntRange(int *range, int len, int a) } return 1; } + +int ReadFile(const char *strInfo, char *buf, int bufLen) +{ + int fd = open(strInfo, O_RDONLY); + if (fd == -1) { + return 1; + } + if (read(fd, buf, bufLen - 1) <= 0) { + close(fd); + return 1; + } + close(fd); + DeleteChar(buf, '\n'); + buf[strlen(buf)] = '\0'; + return 0; +} + +int WriteFile(const char *strInfo, char *buf, int bufLen) +{ + FILE *fp = fopen(strInfo, "w+"); + if (fp == NULL) { + return 1; + } + if (fprintf(fp, "%s", buf) < 0) { + fclose(fp); + return 1; + } + if (fflush(fp) != 0) { + fclose(fp); + return 1; + } + (void)fclose(fp); + return 0; +} + +int WriteFileAndCheck(const char *strInfo, char *buf, int bufLen) +{ + if (WriteFile(strInfo, buf, bufLen) != 0) { + return 1; + } + char checkBuf[MAX_ELEMENT_NAME_LEN] = {0}; + if (ReadFile(strInfo, checkBuf, MAX_ELEMENT_NAME_LEN) != 0) { + return 1; + } + if (strcmp(buf, checkBuf) != 0) { + return 1; + } + return 0; +} \ No newline at end of file -- Gitee