-
Notifications
You must be signed in to change notification settings - Fork 1
CPU utilization #208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
CPU utilization #208
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| #include <driver/timer.h> | ||
| #include <freertos/FreeRTOS.h> | ||
| #include <freertos/timers.h> | ||
|
|
||
| #include <stdio.h> | ||
|
|
||
| #define TIMER_DIVIDER 80 // Divide Base by 80 | ||
|
|
||
|
|
||
| // Timer group 0, timer 0 configuration | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See how these comments are redundant? Even the last field wouldn't need a comment if you use a descriptive constant name. |
||
| timer_config_t timer_config = { | ||
| .alarm_en = TIMER_ALARM_DIS, // Disable alarm | ||
| .intr_type = TIMER_INTR_DISABLE, // No timer interrupts | ||
| .counter_dir = TIMER_COUNT_UP, // Count up | ||
| .auto_reload = TIMER_AUTORELOAD_EN, // Auto-reload | ||
| .divider = TIMER_DIVIDER // Set divider for 1ms (assumption that base | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you do expand this into a proper |
||
| // runs at 80Mhz) | ||
| }; | ||
|
|
||
| // Initialization | ||
| void init_timer0() | ||
| { | ||
| timer_init(TIMER_GROUP_0, TIMER_0, &timer_config); | ||
| timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); | ||
| timer_start(TIMER_GROUP_0, TIMER_0); | ||
| } | ||
|
|
||
| volatile uint64_t core0_idle_cycles = 0; | ||
| volatile uint64_t core1_idle_cycles = 0; | ||
|
|
||
| // When idle | ||
| void vAppliocationIdleHook(void) | ||
| { | ||
| // For ISR to handle (?) | ||
| BaseType_t xHigherPriorityTaskWoken = pdFALSE; | ||
|
|
||
| // Which core? (assumption 1 cycle == 1 tick) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The FreeRTOS tick is triggered by some kind of SysTick timer (in our case I believe it's |
||
| // Can ccheck by creating vApplicationTickHook and comparing # tick and | ||
| // # idle cycles << todo | ||
|
|
||
| if (xPortGetCoreID() == 0) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it'd be cleaner to make the variable an array and index into it with the output of the function to increment the variable. Just make sure it always succeeds or else you need to add error checking. |
||
| core0_idle_cycles++; | ||
| } else if (xPortGetCoreID() == 1) { | ||
| core1_idle_cycles++; | ||
| } | ||
| } | ||
|
|
||
| void print_cpu_utilization(void *pvParameters) | ||
| { | ||
| while (1) { | ||
| uint64_t start_time = 0, end_time = 0; | ||
|
|
||
| timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &start_time); | ||
|
|
||
| // Let run for 5 sec | ||
| // Interrupts can be called here to run other tasks | ||
| // What if interrupt task runs for more than 5 secs? | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Watchdog should trip. |
||
| vTaskDelay(pdMS_TO_TICKS(5000)); | ||
|
|
||
| timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &end_time); | ||
|
|
||
| // Calculate total ticks/cycles in 1 sec | ||
| uint64_t ticks_elapsed = end_time - start_time; | ||
|
|
||
| float core0_utilization = 100.0 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you should use ticks to calculate this over cpu cycles since that's much harder to keep track of. There is a FreeRTOS config |
||
| - ((float) core0_idle_cycles / ticks_elapsed) * 100.0; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's also try to keep the CPU utilization similar to how Linux reports it (as a float between 0 and 1 per core). |
||
| float core1_utilization = 100.0 | ||
| - ((float) core1_idle cycles / ticks_elapsed) * 100.0; | ||
|
|
||
| // Print CPU utilization | ||
| printf("Core 0 CPU Utilization: %.2f\n", core0_utilization); | ||
| printf("Core 1 CPU Utilization: %.2f\n", core1_utilization); | ||
|
|
||
| // Reset idle cycles | ||
| core0_idle_cycles = 0; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the reason for discarding these? Ideally we keep a global running count and a sliding window which we would average so that we have current stats and stats for the duration of the power cycle. |
||
| core1_idle_cycles = 0; | ||
|
|
||
| // Might need to handle overflow if it does occur | ||
| } | ||
| } | ||
|
|
||
| void app_main() | ||
| { | ||
| init_timer0(); | ||
|
|
||
| xTaskCreate(print_cpu_utilization, | ||
| "Print CPU Utilization", | ||
| 2048, | ||
| NULL, | ||
| 1, | ||
| NULL); | ||
|
|
||
| vTaskStartScheduler(); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is self-evident, would you mind
#defineing constants for an expression as to how you arrived to this value?