From: Renz Christian Bagaporo Date: Tue, 12 Mar 2019 13:53:39 +0000 (+0800) Subject: esp_event: test posting from interrupt handler X-Git-Tag: v4.0-beta1~421^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=659f1a12532132dd42046325d9451f09da38cd72;p=esp-idf esp_event: test posting from interrupt handler --- diff --git a/components/esp_event/test/test_event.c b/components/esp_event/test/test_event.c index 9805bd2e0b..b26877342a 100644 --- a/components/esp_event/test/test_event.c +++ b/components/esp_event/test/test_event.c @@ -7,7 +7,11 @@ #include "freertos/FreeRTOS.h" #include "esp_event_loop.h" #include "freertos/task.h" +#include "freertos/portmacro.h" #include "esp_log.h" +#include "soc/timer_group_struct.h" +#include "driver/periph_ctrl.h" +#include "driver/timer.h" #include "esp_event.h" #include "esp_event_private.h" @@ -268,6 +272,48 @@ static void test_teardown() TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_delete_default()); } +#define TIMER_DIVIDER 16 // Hardware timer clock divider +#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds +#define TIMER_INTERVAL0_SEC (2.0) // sample test interval for the first timer + +#if CONFIG_POST_EVENTS_FROM_ISR +static void test_handler_post_from_isr(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + SemaphoreHandle_t *sem = (SemaphoreHandle_t*) event_handler_arg; + // Event data is just the address value (maybe have been truncated due to casting). + int *data = (int*) event_data; + TEST_ASSERT_EQUAL(*data, (int) (*sem)); + xSemaphoreGive(*sem); +} +#endif + +#if CONFIG_POST_EVENTS_FROM_ISR +void IRAM_ATTR test_event_on_timer_alarm(void* para) +{ + /* Retrieve the interrupt status and the counter value + from the timer that reported the interrupt */ + TIMERG0.hw_timer[TIMER_0].update = 1; + uint64_t timer_counter_value = + ((uint64_t) TIMERG0.hw_timer[TIMER_0].cnt_high) << 32 + | TIMERG0.hw_timer[TIMER_0].cnt_low; + + TIMERG0.int_clr_timers.t0 = 1; + timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE); + TIMERG0.hw_timer[TIMER_0].alarm_high = (uint32_t) (timer_counter_value >> 32); + TIMERG0.hw_timer[TIMER_0].alarm_low = (uint32_t) timer_counter_value; + + int data = (int) para; + // Posting events with data more than 4 bytes should fail. + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_event_isr_post(s_test_base1, TEST_EVENT_BASE1_EV1, &data, 5, NULL)); + // This should succeedd, as data is int-sized. The handler for the event checks that the passed event data + // is correct. + BaseType_t task_unblocked; + TEST_ASSERT_EQUAL(ESP_OK, esp_event_isr_post(s_test_base1, TEST_EVENT_BASE1_EV1, &data, sizeof(data), &task_unblocked)); + if (task_unblocked == pdTRUE) { + portYIELD_FROM_ISR(); + } +} +#endif //CONFIG_POST_EVENTS_FROM_ISR TEST_CASE("can create and delete event loops", "[event]") { @@ -1102,6 +1148,44 @@ TEST_CASE("events are dispatched in the order they are registered", "[event]") TEST_TEARDOWN(); } +#if CONFIG_POST_EVENTS_FROM_ISR +TEST_CASE("can post events from interrupt handler", "[event]") +{ + SemaphoreHandle_t sem = xSemaphoreCreateBinary(); + + /* Select and initialize basic parameters of the timer */ + timer_config_t config; + config.divider = TIMER_DIVIDER; + config.counter_dir = TIMER_COUNT_UP; + config.counter_en = TIMER_PAUSE; + config.alarm_en = TIMER_ALARM_EN; + config.intr_type = TIMER_INTR_LEVEL; + config.auto_reload = false; + timer_init(TIMER_GROUP_0, TIMER_0, &config); + + /* Timer's counter will initially start from value below. + Also, if auto_reload is set, this value will be automatically reload on alarm */ + timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL); + + /* Configure the alarm value and the interrupt on alarm. */ + timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_INTERVAL0_SEC * TIMER_SCALE); + timer_enable_intr(TIMER_GROUP_0, TIMER_0); + timer_isr_register(TIMER_GROUP_0, TIMER_0, test_event_on_timer_alarm, + (void *) sem, ESP_INTR_FLAG_IRAM, NULL); + + timer_start(TIMER_GROUP_0, TIMER_0); + + TEST_SETUP(); + + TEST_ASSERT_EQUAL(ESP_OK, esp_event_handler_register(s_test_base1, TEST_EVENT_BASE1_EV1, + test_handler_post_from_isr, &sem)); + + xSemaphoreTake(sem, portMAX_DELAY); + + TEST_TEARDOWN(); +} +#endif + #ifdef CONFIG_EVENT_LOOP_PROFILING TEST_CASE("can dump event loop profile", "[event]") {