#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
#include <unistd.h>
#include "oled.h"
#include "font.h"
char npu_load[50];
int npu_usage[3];
struct cpu_usage
{
unsigned long user;
unsigned long nice;
unsigned long system;
unsigned long idle;
unsigned long iowait;
unsigned long irq;
unsigned long softirq;
};
void get_cpu_usage(struct cpu_usage *usage)
{
FILE *fp = fopen("/proc/stat", "r");
if (fp == NULL)
{
perror("Failed to open /proc/stat");
exit(EXIT_FAILURE);
}
char buffer[256];
fgets(buffer, sizeof(buffer), fp);
sscanf(buffer, "cpu %lu %lu %lu %lu %lu %lu %lu",
&usage->user, &usage->nice, &usage->system,
&usage->idle, &usage->iowait, &usage->irq, &usage->softirq);
fclose(fp);
}
float calculate_cpu_usage(struct cpu_usage *prev, struct cpu_usage *curr)
{
unsigned long prev_total = prev->user + prev->nice + prev->system + prev->idle +
prev->iowait + prev->irq + prev->softirq;
unsigned long curr_total = curr->user + curr->nice + curr->system + curr->idle +
curr->iowait + curr->irq + curr->softirq;
unsigned long total_diff = curr_total - prev_total;
unsigned long idle_diff = curr->idle - prev->idle;
if (total_diff == 0)
return 0.0;
return (float)(total_diff - idle_diff) / total_diff * 100;
}
int get_cpu_temp()
{
FILE *fp = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
if (fp == NULL)
{
perror("Failed to read CPU temperature");
return -1;
}
int temp;
fscanf(fp, "%d", &temp);
fclose(fp);
return temp / 1000;
}
int get_gpu_usage()
{
FILE *fp = fopen("/sys/devices/platform/fb000000.gpu/devfreq/fb000000.gpu/load", "r");
if (fp == NULL)
{
perror("Failed to read GPU usage");
return -1;
}
int usage;
fscanf(fp, "%d", &usage);
fclose(fp);
return usage;
}
// int get_npu_usage() {
// FILE *fp = fopen("/sys/kernel/debug/rknpu/load", "r");
// if (fp == NULL) {
// perror("Failed to read NPU usage");
// return -1;
// }
// int usage;
// fscanf(fp, "%d", &usage);
// fclose(fp);
// return usage;
// }
int get_npu_usage(int core)
{
FILE *fp = fopen("/sys/kernel/debug/rknpu/load", "r");
if (fp == NULL)
{
perror("Failed to read NPU load");
return -1;
}
fgets(npu_load, sizeof(npu_load), fp);
fclose(fp);
// 分割字符串并提取占用率
char *token = strtok(npu_load, ",");
int i = 0;
while (token != NULL && i < 3)
{
sscanf(token, "Core%d: %d%%", &i, &npu_usage[i]);
token = strtok(NULL, ",");
}
}
int get_memory_usage()
{
FILE *fp = fopen("/proc/meminfo", "r");
if (fp == NULL)
{
perror("Failed to open /proc/meminfo");
return -1;
}
unsigned long total_memory = 0;
unsigned long free_memory = 0;
unsigned long available_memory = 0;
char buffer[256];
while (fgets(buffer, sizeof(buffer), fp))
{
if (sscanf(buffer, "MemTotal: %lu kB", &total_memory) == 1)
{
continue;
}
if (sscanf(buffer, "MemAvailable: %lu kB", &available_memory) == 1)
{
continue;
}
}
fclose(fp);
if (total_memory == 0)
return -1;
int usage = 100 - (available_memory * 100 / total_memory);
return usage;
}
int oled_show(struct display_info *disp, int cpu_temp, float cpu_usage, int gpu_usage, int npu0_usage, int npu1_usage, int npu2_usage, int mem_usage)
{
char buf[100];
// oled_clear(disp);
oled_putstrto(disp, 0, 9 + 1, "System Info");
snprintf(buf, sizeof(buf), "CPU Temp: %dC", cpu_temp);
oled_putstrto(disp, 0, 9 + 9, buf);
snprintf(buf, sizeof(buf), "CPU Usage: %.2f%%", cpu_usage);
oled_putstrto(disp, 0, 9 + 17, buf);
snprintf(buf, sizeof(buf), "GPU Usage: %d%%", gpu_usage);
oled_putstrto(disp, 0, 9 + 25, buf);
// snprintf(buf, sizeof(buf), "NPU Usage: %d%%", npu_usage);
// oled_putstrto(disp, 0, 9+33, buf);
snprintf(buf, sizeof(buf), "NPU Load :%d %d %d%%", npu0_usage, npu1_usage, npu2_usage);
oled_putstrto(disp, 0, 9 + 33, buf);
snprintf(buf, sizeof(buf), "Mem Usage: %d%%", mem_usage);
oled_putstrto(disp, 0, 9 + 41, buf);
oled_send_buffer(disp);
return 0;
}
void show_usage(char *progname)
{
printf("\nUsage:\n%s <I2C bus device node>\n", progname);
}
int main(int argc, char **argv)
{
int e;
char filename[32];
struct display_info disp;
struct cpu_usage prev_usage, curr_usage;
if (argc < 2)
{
show_usage(argv[0]);
return -1;
}
memset(&disp, 0, sizeof(disp));
sprintf(filename, "%s", argv[1]);
disp.address = OLED_I2C_ADDR;
disp.font = font2;
e = oled_open(&disp, filename);
if (e != 0)
{
return -1;
}
e = oled_init(&disp);
if (e != 0)
{
return -1;
}
get_cpu_usage(&prev_usage);
while (1)
{
sleep(1);
get_cpu_usage(&curr_usage);
int cpu_temp = get_cpu_temp();
float cpu_usage = calculate_cpu_usage(&prev_usage, &curr_usage);
int gpu_usage = get_gpu_usage();
// int npu_usage = get_npu_usage();
// int npu0_usage = get_npu_usage(0);
// int npu1_usage = get_npu_usage(1);
// int npu2_usage = get_npu_usage(2);
int mem_usage = get_memory_usage();
oled_show(&disp, cpu_temp, cpu_usage, gpu_usage, npu_usage[0], npu_usage[1], npu_usage[2], mem_usage);
prev_usage = curr_usage;
}
return 0;
}
香橙派每秒刷新一次OLED屏幕,显示CPU温度、CPU使用率、GPU使用率和NPU使用率
最新推荐文章于 2024-07-09 14:55:17 发布