perfmon.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. //source : https://github.com/Carbon225/esp32-perfmon
  2. #include "../../include/defines.h"
  3. /*
  4. ESP32 CPU usage monitor
  5. Gives you a rough idea of how the Xtensa cores are utilized.
  6. Works by attaching idle hooks and measuring how often they get called. The core usage is calculated: usage% = idle ticks since last measurement / expected idle ticks if core were idle * 100%. The expected idle tick count was measured by running an empty program.
  7. Limitations:
  8. Should only be used for user information, not in logic that needs accurate values
  9. New IDF versions could optimize performance and therefore introduce an error to usage estimation.
  10. When one core is at 100% the other might report a negative value
  11. Usage:
  12. #include "perfmon.h"
  13. Call perfmon_start() once
  14. */
  15. #ifdef DEBUG_ENABLE_PERFMON
  16. #include "perfmon.h"
  17. #include "freertos/FreeRTOS.h"
  18. #include "freertos/task.h"
  19. #include "esp_freertos_hooks.h"
  20. #include "sdkconfig.h"
  21. #include "esp_log.h"
  22. static const char *TAG = "perfmon";
  23. static uint64_t idle0Calls = 0;
  24. static uint64_t idle1Calls = 0;
  25. #if defined(CONFIG_ESP32_DEFAULT_CPU_FREQ_240)
  26. static const uint64_t MaxIdleCalls = 1855000;
  27. #elif defined(CONFIG_ESP32_DEFAULT_CPU_FREQ_160)
  28. static const uint64_t MaxIdleCalls = 1233100;
  29. #else
  30. #error "Unsupported CPU frequency"
  31. #endif
  32. static bool idle_task_0()
  33. {
  34. idle0Calls += 1;
  35. return false;
  36. }
  37. static bool idle_task_1()
  38. {
  39. idle1Calls += 1;
  40. return false;
  41. }
  42. static void perfmon_task(void *args)
  43. {
  44. while (1)
  45. {
  46. float idle0 = idle0Calls;
  47. float idle1 = idle1Calls;
  48. idle0Calls = 0;
  49. idle1Calls = 0;
  50. int cpu0 = 100.f - idle0 / MaxIdleCalls * 100.f;
  51. int cpu1 = 100.f - idle1 / MaxIdleCalls * 100.f;
  52. ESP_LOGI(TAG, "Core 0 at %d%%", cpu0);
  53. ESP_LOGI(TAG, "Core 1 at %d%%", cpu1);
  54. // TODO configurable delay
  55. vTaskDelay(5000 / portTICK_PERIOD_MS);
  56. }
  57. vTaskDelete(NULL);
  58. }
  59. esp_err_t perfmon_start()
  60. {
  61. ESP_ERROR_CHECK(esp_register_freertos_idle_hook_for_cpu(idle_task_0, 0));
  62. ESP_ERROR_CHECK(esp_register_freertos_idle_hook_for_cpu(idle_task_1, 1));
  63. // TODO calculate optimal stack size
  64. xTaskCreate(perfmon_task, "perfmon", 2048, NULL, 1, NULL);
  65. return ESP_OK;
  66. }
  67. #endif // DEBUG_ENABLE_PERFMON