@@ -12,6 +12,7 @@ void CCpuMonitorTenant::Startup() {
1212
1313 prevExecutionCycles = stats.execution_cycles ;
1414 prevTotalCycles = stats.total_cycles ;
15+ prevUptime = k_uptime_get_32 ();
1516}
1617
1718void CCpuMonitorTenant::PostStartup () {
@@ -55,17 +56,33 @@ uint32_t CCpuMonitorTenant::getUptime() {
5556uint8_t CCpuMonitorTenant::getUtilization () {
5657 k_thread_runtime_stats stats{0 };
5758 k_thread_runtime_stats_all_get (&stats);
59+ uint32_t currentUptime = k_uptime_get_32 ();
5860
59- uint64_t deltaExecution = stats.execution_cycles - prevExecutionCycles;
60- uint64_t deltaTotal = stats.total_cycles - prevTotalCycles;
61+ // Zephyr's naming is confusing! Based on kernel/thread.h comments:
62+ // execution_cycles = total # of cycles (cpu: non-idle + idle) = ALL cycles
63+ // total_cycles = total # of non-idle cycles = ACTIVE/BUSY cycles only
64+ uint64_t deltaAllCycles = stats.execution_cycles - prevExecutionCycles; // All cycles (active + idle)
65+ uint64_t deltaActiveCycles = stats.total_cycles - prevTotalCycles; // Active cycles only
66+ uint32_t deltaTime = currentUptime - prevUptime;
6167
6268 prevExecutionCycles = stats.execution_cycles ;
6369 prevTotalCycles = stats.total_cycles ;
70+ prevUptime = currentUptime;
6471
65- if (deltaExecution == 0 ) {
66- return 0 ; // Avoid division by zero
72+ if (deltaAllCycles == 0 || deltaTime == 0 ) {
73+ return 0 ; // Avoid division by zero or invalid measurements
6774 }
6875
69- // Utilization is the percentage of non-idle cycles in the interval
70- return static_cast <uint8_t >((deltaTotal * 100 ) / deltaExecution);
76+ // Validate that our cycle measurements make sense relative to time
77+ // If the time delta is very small (< 10ms), the measurement might not be reliable
78+ if (deltaTime < 10 ) {
79+ LOG_WRN_ONCE (" CPU utilization measurement interval too short for accuracy" );
80+ }
81+
82+ // CPU Utilization = (Active cycles / All cycles) × 100
83+ // This gives us the percentage of time the CPU was NOT idle
84+ uint64_t utilization = (deltaActiveCycles * 100 ) / deltaAllCycles;
85+
86+ // Clamp to 100% in case of any edge cases
87+ return static_cast <uint8_t >(utilization > 100 ? 100 : utilization);
7188}
0 commit comments