默認的事件循環是一個事件循環的系統應用發布和處理事件(例如,Wi-Fi無線事件)。
基於ESP-IDF4.1
1 #include "esp_log.h" 2 #include "freertos/FreeRTOS.h" 3 #include "freertos/task.h" 4 #include "event_source.h" 5 6 static const char* TAG = "default_event_loop"; 7 8 static char* get_id_string(esp_event_base_t base, int32_t id) { 9 char* event = ""; 10 if (base == TIMER_EVENTS) { 11 switch(id) { 12 case TIMER_EVENT_STARTED: 13 event = "TIMER_EVENT_STARTED"; 14 break; 15 case TIMER_EVENT_EXPIRY: 16 event = "TIMER_EVENT_EXPIRY"; 17 break; 18 case TIMER_EVENT_STOPPED: 19 event = "TIMER_EVENT_STOPPED"; 20 break; 21 } 22 } else { 23 event = "TASK_ITERATION_EVENT"; 24 } 25 return event; 26 } 27 28 //事件源周期定時器相關的定義 29 ESP_EVENT_DEFINE_BASE(TIMER_EVENTS); 30 31 esp_timer_handle_t TIMER; 32 33 //計時器周期過期時執行回調,將計時器到期事件發布到默認事件循環 34 static void timer_callback(void* arg) 35 { 36 ESP_LOGI(TAG, "%s:%s: posting to default loop", TIMER_EVENTS, get_id_string(TIMER_EVENTS, TIMER_EVENT_EXPIRY)); 37 ESP_ERROR_CHECK(esp_event_post(TIMER_EVENTS, TIMER_EVENT_EXPIRY, NULL, 0, portMAX_DELAY)); 38 } 39 40 // 當計時器啟動事件被循環執行時,執行的處理程序 41 static void timer_started_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data) 42 { 43 ESP_LOGI(TAG, "%s:%s: timer_started_handler", base, get_id_string(base, id)); 44 } 45 46 //當計時器到期時間被循環執行時,執行的處理程序。處理程序跟蹤計時器過期次數,當達到設置的過期次數,處理程序停止計時器並發送計時器停止事件 47 static void timer_expiry_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data) 48 { 49 static int count = 0; 50 count++; 51 52 if (count >= TIMER_EXPIRIES_COUNT) { 53 // 停止計時器 54 ESP_ERROR_CHECK(esp_timer_stop(TIMER)); 55 ESP_LOGI(TAG, "%s:%s: posting to default loop", base, get_id_string(base, TIMER_EVENT_STOPPED)); 56 57 //發送計時器停止事件 58 ESP_ERROR_CHECK(esp_event_post(TIMER_EVENTS, TIMER_EVENT_STOPPED, NULL, 0, portMAX_DELAY)); 59 } 60 61 ESP_LOGI(TAG, "%s:%s: timer_expiry_handler, executed %d out of %d times", base, get_id_string(base, id), count, TIMER_EXPIRIES_COUNT); 62 } 63 64 //任何計時器事件(啟動/到期/停止)被循環執行時,執行的處理程序 65 static void timer_any_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data) 66 { 67 ESP_LOGI(TAG, "%s:%s: timer_any_handler", base, get_id_string(base, id)); 68 } 69 70 //計時器停止事件被循環執行時,執行的處理程序。由於計時器已經停止,可以安全的刪除它。 71 static void timer_stopped_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data) 72 { 73 ESP_LOGI(TAG, "%s:%s: timer_stopped_handler", base, get_id_string(base, id)); 74 75 // 刪除計時器 76 esp_timer_delete(TIMER); 77 78 ESP_LOGI(TAG, "%s:%s: deleted timer event source", base, get_id_string(base, id)); 79 } 80 81 //事件源任務相關的定義 82 ESP_EVENT_DEFINE_BASE(TASK_EVENTS); 83 84 //任務迭代處理 85 static void task_iteration_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data) 86 { 87 int iteration = *((int*) event_data); 88 ESP_LOGI(TAG, "%s:%s: task_iteration_handler, executed %d times", base, get_id_string(base, id), iteration); 89 } 90 91 //任務時間源 92 static void task_event_source(void* args) 93 { 94 for(int iteration = 1; iteration <= TASK_ITERATIONS_COUNT; iteration++) { 95 96 ESP_LOGI(TAG, "%s:%s: posting to default loop, %d out of %d", TASK_EVENTS, 97 get_id_string(TASK_EVENTS, TASK_ITERATION_EVENT), iteration, TASK_ITERATIONS_COUNT); 98 99 //發布該循環已迭代。注意,迭代計數已傳遞給處理程序。事件發布期間傳遞的數據是原始數據的深層副本。 100 ESP_ERROR_CHECK(esp_event_post(TASK_EVENTS, TASK_ITERATION_EVENT, &iteration, sizeof(iteration), portMAX_DELAY)); 101 102 if (iteration == TASK_ITERATIONS_UNREGISTER) { 103 ESP_LOGI(TAG, "%s:%s: unregistering task_iteration_handler", TASK_EVENTS, get_id_string(TASK_EVENTS, TASK_ITERATION_EVENT)); 104 ESP_ERROR_CHECK(esp_event_handler_unregister(TASK_EVENTS, TASK_ITERATION_EVENT, task_iteration_handler)); 105 } 106 107 vTaskDelay(pdMS_TO_TICKS(TASK_PERIOD)); 108 } 109 110 vTaskDelay(pdMS_TO_TICKS(TASK_PERIOD)); 111 112 ESP_LOGI(TAG, "%s:%s: deleting task event source", TASK_EVENTS, get_id_string(TASK_EVENTS, TASK_ITERATION_EVENT)); 113 114 vTaskDelete(NULL); 115 } 116 117 //所有時間的處理程序 118 static void all_event_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data) 119 { 120 ESP_LOGI(TAG, "%s:%s: all_event_handler", base, get_id_string(base, id)); 121 } 122 123 //入口 124 void app_main(void) 125 { 126 ESP_LOGI(TAG, "setting up"); 127 128 //創建默認的事件循環 129 ESP_ERROR_CHECK(esp_event_loop_create_default()); 130 131 // 注冊特定計時器事件處理程序 132 ESP_ERROR_CHECK(esp_event_handler_register(TIMER_EVENTS, TIMER_EVENT_STARTED, timer_started_handler, NULL)); 133 ESP_ERROR_CHECK(esp_event_handler_register(TIMER_EVENTS, TIMER_EVENT_EXPIRY, timer_expiry_handler, NULL)); 134 ESP_ERROR_CHECK(esp_event_handler_register(TIMER_EVENTS, TIMER_EVENT_STOPPED, timer_stopped_handler, NULL)); 135 136 //注冊所有計時器系列事件處理程序。將在計時器啟動、到期或者停止時執行 137 ESP_ERROR_CHECK(esp_event_handler_register(TIMER_EVENTS, ESP_EVENT_ANY_ID, timer_any_handler, NULL)); 138 139 //注冊任務迭代事件的處理程序 140 ESP_ERROR_CHECK(esp_event_handler_register(TASK_EVENTS, TASK_ITERATION_EVENT, task_iteration_handler, NULL)); 141 142 //為所有事件注冊處理程序。如果計時器事件或者任務迭代事件發布到默認循環則執行此操作。 143 ESP_ERROR_CHECK(esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, all_event_handler, NULL)); 144 145 //創建並啟動事件源 146 esp_timer_create_args_t timer_args = { 147 .callback = &timer_callback, 148 }; 149 ESP_ERROR_CHECK(esp_timer_create(&timer_args, &TIMER)); 150 ESP_LOGI(TAG, "starting event sources"); 151 152 // 創建與當前任務具有相同優先級的事件源任務 153 xTaskCreate(task_event_source, "task_event_source", 2048, NULL, uxTaskPriorityGet(NULL), NULL); 154 155 ESP_ERROR_CHECK(esp_timer_start_periodic(TIMER, TIMER_PERIOD)); 156 157 //發布計時器啟動事件 158 ESP_LOGI(TAG, "%s:%s: posting to default loop", TIMER_EVENTS, get_id_string(TIMER_EVENTS, TIMER_EVENT_STARTED)); 159 ESP_ERROR_CHECK(esp_event_post(TIMER_EVENTS, TIMER_EVENT_STARTED, NULL, 0, portMAX_DELAY)); 160 }
原文:https://gitee.com/EspressifSystems/esp-idf/tree/master/examples/system/esp_event/default_event_loop