test_isr_latency.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include <esp_types.h>
  2. #include <stdio.h>
  3. #include "sdkconfig.h"
  4. #include "freertos/FreeRTOS.h"
  5. #include "freertos/task.h"
  6. #include "freertos/semphr.h"
  7. #include "freertos/queue.h"
  8. #include "esp_intr_alloc.h"
  9. #include "unity.h"
  10. #include "soc/cpu.h"
  11. #include "test_utils.h"
  12. #if CONFIG_IDF_TARGET_ARCH_XTENSA
  13. #include "xtensa/hal.h"
  14. #include "freertos/xtensa_api.h"
  15. #define TEST_SET_INT_MASK(mask) xt_set_intset(mask)
  16. #define TEST_CLR_INT_MASK(mask) xt_set_intclear(mask)
  17. #elif CONFIG_IDF_TARGET_ARCH_RISCV
  18. #include "riscv/interrupt.h"
  19. #define TEST_SET_INT_MASK(mask) esprv_intc_int_enable(mask)
  20. #define TEST_CLR_INT_MASK(mask) esprv_intc_int_disable(mask)
  21. #endif
  22. #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
  23. #define SW_ISR_LEVEL_1 7
  24. static SemaphoreHandle_t sync;
  25. static SemaphoreHandle_t end_sema;
  26. static uint32_t cycle_before_trigger;
  27. static uint32_t cycle_before_exit;
  28. static uint32_t delta_enter_cycles = 0;
  29. static uint32_t delta_exit_cycles = 0;
  30. static void software_isr_using_parameter_vportyield(void *arg) {
  31. (void)arg;
  32. BaseType_t yield;
  33. delta_enter_cycles += portGET_RUN_TIME_COUNTER_VALUE() - cycle_before_trigger;
  34. TEST_CLR_INT_MASK(1 << SW_ISR_LEVEL_1);
  35. xSemaphoreGiveFromISR(sync, &yield);
  36. portYIELD_FROM_ISR(yield);
  37. cycle_before_exit = portGET_RUN_TIME_COUNTER_VALUE();
  38. }
  39. static void software_isr_using_no_argument_vportyield(void *arg) {
  40. (void)arg;
  41. BaseType_t yield;
  42. delta_enter_cycles += portGET_RUN_TIME_COUNTER_VALUE() - cycle_before_trigger;
  43. TEST_CLR_INT_MASK(1 << SW_ISR_LEVEL_1);
  44. xSemaphoreGiveFromISR(sync, &yield);
  45. if(yield) {
  46. portYIELD_FROM_ISR();
  47. }
  48. cycle_before_exit = portGET_RUN_TIME_COUNTER_VALUE();
  49. }
  50. static void test_task(void *arg) {
  51. (void) arg;
  52. for(int i = 0;i < 10000; i++) {
  53. cycle_before_trigger = portGET_RUN_TIME_COUNTER_VALUE();
  54. TEST_SET_INT_MASK(1 << SW_ISR_LEVEL_1);
  55. xSemaphoreTake(sync, portMAX_DELAY);
  56. delta_exit_cycles += portGET_RUN_TIME_COUNTER_VALUE() - cycle_before_exit;
  57. }
  58. delta_enter_cycles /= 10000;
  59. delta_exit_cycles /= 10000;
  60. xSemaphoreGive(end_sema);
  61. vTaskDelete(NULL);
  62. }
  63. TEST_CASE("isr latency test vport-yield-from-isr with no parameter", "[freertos] [ignore]")
  64. {
  65. intr_handle_t handle;
  66. esp_err_t err = esp_intr_alloc(ETS_INTERNAL_SW0_INTR_SOURCE, ESP_INTR_FLAG_LEVEL1, &software_isr_using_no_argument_vportyield, NULL, &handle);
  67. TEST_ASSERT_EQUAL_HEX32(ESP_OK, err);
  68. sync = xSemaphoreCreateBinary();
  69. TEST_ASSERT(sync != NULL);
  70. end_sema = xSemaphoreCreateBinary();
  71. TEST_ASSERT(end_sema != NULL);
  72. xTaskCreatePinnedToCore(test_task, "tst" , 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0);
  73. vTaskDelay(100);
  74. BaseType_t result = xSemaphoreTake(end_sema, portMAX_DELAY);
  75. TEST_ASSERT_EQUAL_HEX32(pdTRUE, result);
  76. TEST_PERFORMANCE_LESS_THAN(ISR_ENTER_CYCLES, "%d cycles" ,delta_enter_cycles);
  77. TEST_PERFORMANCE_LESS_THAN(ISR_EXIT_CYCLES, "%d cycles" ,delta_exit_cycles);
  78. esp_intr_free(handle);
  79. }
  80. TEST_CASE("isr latency test vport-yield-from-isr with parameter", "[freertos][ignore]")
  81. {
  82. intr_handle_t handle;
  83. esp_err_t err = esp_intr_alloc(ETS_INTERNAL_SW0_INTR_SOURCE, ESP_INTR_FLAG_LEVEL1, &software_isr_using_parameter_vportyield, NULL, &handle);
  84. TEST_ASSERT_EQUAL_HEX32(ESP_OK, err);
  85. sync = xSemaphoreCreateBinary();
  86. TEST_ASSERT(sync != NULL);
  87. end_sema = xSemaphoreCreateBinary();
  88. TEST_ASSERT(end_sema != NULL);
  89. xTaskCreatePinnedToCore(test_task, "tst" , 4096, NULL, configMAX_PRIORITIES - 1, NULL, 0);
  90. BaseType_t result = xSemaphoreTake(end_sema, portMAX_DELAY);
  91. TEST_ASSERT_EQUAL_HEX32(pdTRUE, result);
  92. TEST_PERFORMANCE_LESS_THAN(ISR_ENTER_CYCLES, "%d cycles" ,delta_enter_cycles);
  93. TEST_PERFORMANCE_LESS_THAN(ISR_EXIT_CYCLES, "%d cycles" ,delta_exit_cycles);
  94. esp_intr_free(handle);
  95. }
  96. #endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)