forked from gary/ems
2
0
Fork 0
sun_ems/ems_c/kernel/kit_core.c

223 lines
6.9 KiB
C
Raw Permalink Normal View History

2025-05-13 17:49:49 +08:00
/*****************************************************************************
* @copyright 1997-2050, . POWER SUPPLY CO., LTD.
* @file kit_core.c
* @brief xx功能
* @author Gary
* @date 2024-09-21
* @remark
*****************************************************************************/
#include <errno.h>
#include "kit_core.h"
/*****************************************************************************
* @brief shell命令 (使 system)
* @param[in] cmdshell命令
* @param[in] buffer
* @param[in] buffer_size
* @return 1- 0-
*****************************************************************************/
int kit_popen_exec(const char *cmd, char* buffer, size_t buffer_size)
{
#if IF_RUNIN_VM == RUNIN_VM // 虚拟机环境,返回默认值
return 0;
#endif
FILE *fp = popen(cmd, "r");
if (fp == NULL)
{
KITLOG(LOG_KIT_EN, ERROR_EN, "popen failed");
return 1;
}
// 读取执行结果
size_t bytes_read = fread(buffer, 1, buffer_size - 1, fp); // 最多只读取buffer_size比特数据
if (ferror(fp))
{
KITLOG(LOG_KIT_EN, ERROR_EN, "文件读取失败: %s\n", strerror(errno));
pclose(fp);
return 1;
}
buffer[bytes_read] = '\0'; // 字符串要以NULL结束
int status = pclose(fp);
if (status == -1)
{
KITLOG(LOG_KIT_EN, ERROR_EN, "pclose failed");
return 1;
}
else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
{
KITLOG(LOG_KIT_EN, ERROR_EN, "CMD命令 '%s' 执行失败,失败的编号: %d\n", cmd, WEXITSTATUS(status));
return 1;
}
return 0;
}
/*****************************************************************************
* @brief
* @param[in] cmdshell命令
* @return 1- 0-
*****************************************************************************/
int kit_get_net_status(void)
{
FILE *fp = popen("ping -c 1 -W 1 www.baidu.com > /dev/null 2>&1", "r");
if (fp == NULL)
{
perror("popen failed");
return 1; // 如果popen失败认为网络不可用
}
// 等待命令执行完毕,获取返回状态
int status = pclose(fp);
// WEXITSTATUS获取子进程返回的状态码ping成功返回0
if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
{
return 0; // 网络可用
}
else
{
return 1; // 网络不可用
}
}
/*****************************************************************************
* @brief EMS的SN号
* @param[in] serialSN号
* @return 1- 0-
*****************************************************************************/
int kit_get_ems_sn(char serial[128])
{
char buffer[3000]; // 接收执行返回值
char buffer_copy[3000]; // 用于 strtok 的副本
char *line = NULL;
char *serialStart = NULL;
// 使用 kit_popen_exec 执行"cat /proc/cpuinfo"
if (kit_popen_exec("cat /proc/cpuinfo", buffer, sizeof(buffer)) != 0)
{
KITLOG(LOG_DRIVER_EN, ERROR_EN, "cat /proc/cpuinfo 命令执行失败\n");
return 1; // 返回错误
}
strcpy(buffer_copy, buffer); // 复制 buffer 到 buffer_copy
// 使用 strtok 按行分割 buffer_copy
line = strtok(buffer_copy, "\n");
while (line != NULL)
{
// 查找 "Serial" 字符串
if ((serialStart = strstr(line, "Serial")) != NULL)
{
// 提取序列号
serialStart += strlen("Serial\t\t: "); // 跳过 "Serial : "
char *endOfSerial = strchr(serialStart, '\n'); // 查找换行符
if (endOfSerial != NULL)
{
*endOfSerial = '\0'; // 将换行符替换为字符串终止符
}
strncpy(serial, serialStart, 127); // 复制序列号到 serial限制长度防止溢出
serial[127] = '\0'; // 添加字符串终止符
return 0; // 返回成功
}
line = strtok(NULL, "\n");
}
KITLOG(LOG_DRIVER_EN, ERROR_EN, "未找到序列号\n");
return 1; // 返回错误
}
// 获取系统 CPU 时间
void getSysCpuTime(cpu_time_t *time)
{
FILE *file = fopen("/proc/stat", "r");
if (file == NULL)
{
perror("Error opening /proc/stat");
exit(EXIT_FAILURE);
}
fscanf(file, "cpu %lu %lu %lu %lu %lu %lu %lu %lu",
&time->user, &time->nice, &time->system, &time->idle,
&time->iowait, &time->irq, &time->softirq, &time->steal);
fclose(file);
}
// 获取指定进程的 CPU 时间
void getProCpuTime(cpu_time_t *time, pid_t pid)
{
char filename[32];
sprintf(filename, "/proc/%d/stat", pid);
FILE *file = fopen(filename, "r");
if (file == NULL)
{
perror("Error opening process stat file");
exit(EXIT_FAILURE);
}
uint64_t utime, stime;
fscanf(file, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu", &utime, &stime);
time->user = utime;
time->system = stime;
fclose(file);
}
// 获取内存信息的函数
void getMemInfo(memory_info_t *info)
{
FILE *file = fopen("/proc/meminfo", "r"); // 打开 /proc/meminfo 文件
if (file == NULL)
{
perror("Error opening /proc/meminfo"); // 如果打开失败,打印错误信息并退出
return;
}
// 从文件中读取内存信息,包括总内存、空闲内存、可用内存、缓冲区内存和缓存内存
fscanf(file, "MemTotal: %lu kB\nMemFree: %lu kB\nMemAvailable: %lu kB\nBuffers: %lu kB\nCached: %lu kB",
&info->total, &info->free, &info->available, &info->buffers, &info->cached);
fclose(file); // 关闭文件
}
// 函数用于提取指定关键字后的整数值
int extractValue(const char *line, const char *keyword)
{
char *pos = strstr(line, keyword);
if (pos == NULL)
{
return -1;
}
pos += strlen(keyword);
int value;
sscanf(pos, "%d", &value);
return value;
}
// 计算当前进程内存占用
double calculateProcMemUsage(memory_info_t info, pid_t pid)
{
char filename[32];
sprintf(filename, "/proc/%d/status", pid);
FILE *file = fopen(filename, "r");
if (file == NULL)
{
// perror("Error opening process status file");
return 0.0;
}
char line[256];
int rss = -1;
while (fgets(line, sizeof(line), file))
{
if (rss == -1 && strstr(line, "VmRSS") != NULL)
{
rss = extractValue(line, "VmRSS:");
}
}
fclose(file);
if (rss != -1)
{
// printf("Current process resident memory size: %d kB\n", rss);
return (double)rss / info.total * 100.0;
}
else
{
// printf("Failed to get process memory usage.\n");
return 0.0;
}
}