#include #include #include #include #include #include #include #include #include #include // ========================================== // CPU 监控类 (保持不变) // ========================================== class CpuMonitor { public: CpuMonitor() { get_usage(); } float get_usage() { std::ifstream file("/proc/stat"); std::string line; if (!std::getline(file, line)) return 0.0f; std::istringstream ss(line.substr(3)); unsigned long long user, nice, system, idle, iowait, irq, softirq, steal; ss >> user >> nice >> system >> idle >> iowait >> irq >> softirq >> steal; unsigned long long current_idle = idle + iowait; unsigned long long current_non_idle = user + nice + system + irq + softirq + steal; unsigned long long current_total = current_idle + current_non_idle; unsigned long long total_diff = current_total - prev_total; unsigned long long idle_diff = current_idle - prev_idle; prev_idle = current_idle; prev_total = current_total; if (total_diff == 0) return 0.0f; return (float)(total_diff - idle_diff) * 100.0f / total_diff; } private: unsigned long long prev_idle = 0; unsigned long long prev_total = 0; }; // ========================================== // NPU 读取函数 (修改为读取所有核心) // ========================================== std::string get_npu_usage_str() { std::ifstream file("/sys/kernel/debug/rknpu/load"); if (!file.is_open()) return "N/A (No Perm)"; std::string line; if (std::getline(file, line)) { // RK3588 通常格式: "NPU load: Core0: 0%, Core1: 0%, Core2: 0%," // 我们去掉前面的 "NPU load:" 前缀,只保留 Core 信息 size_t pos = line.find("NPU load:"); if (pos != std::string::npos) { line = line.substr(pos + 9); } // 简单的字符串清理:去掉多余空格,去掉结尾逗号 std::string clean_line; bool last_space = false; for (char c : line) { if (c == ',') continue; // 去掉逗号 if (isspace(c)) { if (!last_space) { clean_line += ' '; last_space = true; } } else { clean_line += c; last_space = false; } } return clean_line; } return "Idle"; } // ========================================== // RGA 读取函数 (根据你找到的路径修改) // ========================================== std::string get_rga_usage_str() { std::ifstream file("/sys/kernel/debug/rkrga/load"); if (!file.is_open()) return "N/A"; std::string line; std::stringstream ss; bool found_any = false; int core_idx = 0; while (std::getline(file, line)) { // 忽略第一行 "num of scheduler" if (line.find("scheduler") != std::string::npos && line.find("=") != std::string::npos && line.find("%") == std::string::npos) { continue; } // 寻找包含 "%" 的行,通常负载都在这些行里 if (line.find("%") != std::string::npos) { // 尝试提取这一行里的最后一个数字 // 假设格式类似: "scheduler[0]: full_load = 0.0%, load = 12.5%" // 或者简单点: "load = 12%" // 简单粗暴法:找到 "%" 前面的数字 size_t percent_pos = line.rfind('%'); // 找最后一个 % if (percent_pos != std::string::npos && percent_pos > 0) { // 向前回溯找到数字起始位置 size_t num_end = percent_pos; size_t num_start = num_end; while (num_start > 0 && (isdigit(line[num_start-1]) || line[num_start-1] == '.')) { num_start--; } if (num_start < num_end) { std::string num_str = line.substr(num_start, num_end - num_start); try { float load = std::stof(num_str); ss << "C" << core_idx++ << ":" << std::fixed << std::setprecision(0) << load << "% "; found_any = true; } catch (...) {} } } } } if (!found_any) return "Idle (fmt err)"; return ss.str(); } // ========================================== // 主函数 // ========================================== int main() { CpuMonitor cpu_mon; std::cout << "=== RK3588 System Monitor ===" << std::endl; // 打印更宽的表头 std::cout << "----------------------------------------------------------------------------------" << std::endl; std::cout << "| CPU | NPU (3 Cores) | RGA (Cores) |" << std::endl; std::cout << "----------------------------------------------------------------------------------" << std::endl; while (true) { float cpu = cpu_mon.get_usage(); std::string npu = get_npu_usage_str(); std::string rga = get_rga_usage_str(); // 格式化输出 // CPU: 占用 6 格 // NPU: 占用 38 格 (预留给 Core0: xx% Core1: xx% Core2: xx%) // RGA: 占用 28 格 std::cout << "\r| " << std::fixed << std::setprecision(1) << std::setw(5) << cpu << "% | " << std::left << std::setw(38) << npu << " | " << std::setw(28) << rga << " |" << std::flush; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } return 0; }