香橙派每秒刷新一次OLED屏幕,显示CPU温度、CPU使用率、GPU使用率和NPU使用率

#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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值