Kaynağa Gözat

Event handling refactoring

This change separates definitions in esp_event.h and functions in event.c into several parts:
- event structure definitions (esp_event.h)
- default implementations of event handlers (event_default_handlers.c)
- default implementation of event loop (event_loop.c, esp_event_loop.h)

Purpose of this change is to allow applications choose their own poison:
- full control of event loop at the expense of more bootstrap code
- pre-defined event task firing event callbacks, but less code in app_main.c
Ivan Grokhotkov 9 yıl önce
ebeveyn
işleme
53de9f115f

+ 3 - 83
components/esp32/event.c → components/esp32/event_default_handlers.c

@@ -19,6 +19,7 @@
 #include "esp_err.h"
 #include "esp_wifi.h"
 #include "esp_event.h"
+#include "esp_event_loop.h"
 #include "esp_task.h"
 
 #include "freertos/FreeRTOS.h"
@@ -29,14 +30,7 @@
 #include "tcpip_adapter.h"
 #include "esp_log.h"
 
-#define ESP32_WORKAROUND 1
-
-#if CONFIG_WIFI_ENABLED
-static const char* TAG = "event";
-static bool event_init_flag = false;
-static xQueueHandle g_event_handler = NULL;
-static system_event_cb_t g_event_handler_cb;
-static void *g_event_ctx;
+const char* TAG = "event";
 
 #define WIFI_API_CALL_CHECK(info, api_call, ret) \
 do{\
@@ -175,15 +169,6 @@ esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event)
     return ESP_OK;
 }
 
-static esp_err_t esp_wifi_post_event_to_user(system_event_t *event)
-{
-    if (g_event_handler_cb) {
-        return (*g_event_handler_cb)(g_event_ctx, event);
-    }
-
-    return ESP_OK;
-}
-
 static esp_err_t esp_system_event_debug(system_event_t *event)
 {
     if (event == NULL) {
@@ -274,7 +259,7 @@ static esp_err_t esp_system_event_debug(system_event_t *event)
     return ESP_OK;
 }
 
-static esp_err_t esp_system_event_handler(system_event_t *event)
+esp_err_t esp_event_process_default(system_event_t *event)
 {
     if (event == NULL) {
         ESP_LOGE(TAG, "Error: event is null!");
@@ -290,72 +275,7 @@ static esp_err_t esp_system_event_handler(system_event_t *event)
         }
     } else {
         ESP_LOGE(TAG, "mismatch or invalid event, id=%d", event->event_id);
-    }
-
-    return esp_wifi_post_event_to_user(event);
-}
-
-static void esp_system_event_task(void *pvParameters)
-{
-    system_event_t evt;
-    esp_err_t ret;
-
-    while (1) {
-        if (xQueueReceive(g_event_handler, &evt, portMAX_DELAY) == pdPASS) {
-            ret = esp_system_event_handler(&evt);
-            if (ret == ESP_FAIL) {
-                ESP_LOGE(TAG, "post event to user fail!");
-            }
-        }
-    }
-}
-
-system_event_cb_t esp_event_set_cb(system_event_cb_t cb, void *ctx)
-{
-    system_event_cb_t old_cb = g_event_handler_cb;
-
-    g_event_handler_cb = cb;
-    g_event_ctx = ctx;
-
-    return old_cb;
-}
-
-esp_err_t esp_event_send(system_event_t *event)
-{
-    portBASE_TYPE ret;
-
-    ret = xQueueSendToBack((xQueueHandle)g_event_handler, event, 0);
-
-    if (pdPASS != ret) {
-        if (event) {
-            ESP_LOGE(TAG, "e=%d f", event->event_id);
-        } else {
-            ESP_LOGE(TAG, "e null");
-        }
-        return ESP_FAIL;
-    }
-
-    return ESP_OK;
-}
-
-void *esp_event_get_handler(void)
-{
-    return (void *)g_event_handler;
-}
-
-esp_err_t esp_event_init(system_event_cb_t cb, void *ctx)
-{
-    if (event_init_flag) {
         return ESP_FAIL;
     }
-
-    g_event_handler_cb = cb;
-    g_event_ctx = ctx;
-
-    g_event_handler = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t));
-
-    xTaskCreatePinnedToCore(esp_system_event_task, "eventTask", ESP_TASKD_EVENT_STACK, NULL, ESP_TASKD_EVENT_PRIO, NULL, 0);
     return ESP_OK;
 }
-
-#endif

+ 118 - 0
components/esp32/event_loop.c

@@ -0,0 +1,118 @@
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "esp_err.h"
+#include "esp_wifi.h"
+#include "esp_event.h"
+#include "esp_event_loop.h"
+#include "esp_task.h"
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "freertos/semphr.h"
+
+#include "tcpip_adapter.h"
+#include "esp_log.h"
+#include "sdkconfig.h"
+
+
+static const char* TAG = "event";
+static bool s_event_init_flag = false;
+static QueueHandle_t s_event_queue = NULL;
+static system_event_cb_t s_event_handler_cb = NULL;
+static void *s_event_ctx = NULL;
+
+static esp_err_t esp_wifi_post_event_to_user(system_event_t *event)
+{
+    if (s_event_handler_cb) {
+        return (*s_event_handler_cb)(s_event_ctx, event);
+    }
+    return ESP_OK;
+}
+
+static void esp_system_event_task(void *pvParameters)
+{
+    system_event_t evt;
+    esp_err_t ret;
+
+    while (1) {
+        if (xQueueReceive(s_event_queue, &evt, portMAX_DELAY) == pdPASS) {
+            ret = esp_event_process_default(&evt);
+            if (ret != ESP_OK) {
+                ESP_LOGE(TAG, "default event handler failed!");
+            }
+            ret = esp_wifi_post_event_to_user(&evt);
+            if (ret != ESP_OK) {
+                ESP_LOGE(TAG, "post event to user fail!");
+            }
+        }
+    }
+}
+
+system_event_cb_t esp_event_set_cb(system_event_cb_t cb, void *ctx)
+{
+    system_event_cb_t old_cb = s_event_handler_cb;
+
+    s_event_handler_cb = cb;
+    s_event_ctx = ctx;
+
+    return old_cb;
+}
+
+esp_err_t esp_event_send(system_event_t *event)
+{
+    portBASE_TYPE ret;
+
+    ret = xQueueSendToBack(s_event_queue, event, 0);
+
+    if (pdPASS != ret) {
+        if (event) {
+            ESP_LOGE(TAG, "e=%d f", event->event_id);
+        } else {
+            ESP_LOGE(TAG, "e null");
+        }
+        return ESP_FAIL;
+    }
+
+    return ESP_OK;
+}
+
+QueueHandle_t esp_event_loop_get_queue(void)
+{
+    return s_event_queue;
+}
+
+esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx)
+{
+    if (s_event_init_flag) {
+        return ESP_FAIL;
+    }
+
+    s_event_handler_cb = cb;
+    s_event_ctx = ctx;
+
+    s_event_queue = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t));
+
+    xTaskCreatePinnedToCore(esp_system_event_task, "eventTask",
+            ESP_TASKD_EVENT_STACK, NULL, ESP_TASKD_EVENT_PRIO, NULL, 0);
+
+    s_event_init_flag = true;
+    return ESP_OK;
+}
+

+ 9 - 41
components/esp32/include/esp_event.h

@@ -105,30 +105,6 @@ typedef struct {
     system_event_info_t   event_info;    /**< event information */
 } system_event_t;
 
-/**
-  * @brief  Application specified event callback function
-  *
-  * @param  void *ctx : reserved for user
-  * @param  system_event_t *event : event type defined in this file
-  *
-  * @return ESP_OK : succeed
-  * @return others : fail
-  */
-typedef esp_err_t (*system_event_cb_t)(void *ctx, system_event_t *event);
-
-/**
-  * @brief  Set application specified event callback function
-  *
-  * @attention 1. If cb is NULL, means application don't need to handle
-  *               If cb is not NULL, it will be call when an event is received, after the default event callback is completed
-  *
-  * @param  system_event_cb_t cb : callback
-  * @param  void *ctx : reserved for user
-  *
-  * @return system_event_cb_t : old callback
-  */
-system_event_cb_t esp_event_set_cb(system_event_cb_t cb, void *ctx);
-
 /**
   * @brief  Send a event to event task
   *
@@ -142,28 +118,20 @@ system_event_cb_t esp_event_set_cb(system_event_cb_t cb, void *ctx);
 esp_err_t esp_event_send(system_event_t *event);
 
 /**
-  * @brief  Get the event handler
+  * @brief  Default event handler for system events
   *
-  * @attention : currently this API returns event queue handler, by this event queue,
-  *              users can notice when WiFi has done something like scanning done, connected to AP or disconnected from AP.
+  * This function performs default handling of system events.
+  * When using esp_event_loop APIs, it is called automatically before invoking the user-provided
+  * callback function.
   *
-  * @param  null
+  * Applications which implement a custom event loop must call this function
+  * as part of event processing.
   *
-  * @return void * : event queue pointer
+  * @param  event pointer to event to be handled
+  * @return ESP_OK if an event was handled successfully
   */
-void *esp_event_get_handler(void);
+esp_err_t esp_event_process_default(system_event_t *event);
 
-/**
-  * @brief  Init the event module
-  *         Create the event handler and task
-  *
-  * @param  system_event_cb_t cb : application specified event callback, it can be modified by call esp_event_set_cb
-  * @param  void *ctx : reserved for user
-  *
-  * @return ESP_OK : succeed
-  * @return others : fail
-  */
-esp_err_t esp_event_init(system_event_cb_t cb, void *ctx);
 
 #ifdef __cplusplus
 }

+ 81 - 0
components/esp32/include/esp_event_loop.h

@@ -0,0 +1,81 @@
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __ESP_EVENT_LOOP_H__
+#define __ESP_EVENT_LOOP_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "esp_err.h"
+#include "esp_event.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+  * @brief  Application specified event callback function
+  *
+  * @param  void *ctx : reserved for user
+  * @param  system_event_t *event : event type defined in this file
+  *
+  * @return ESP_OK : succeed
+  * @return others : fail
+  */
+typedef esp_err_t (*system_event_cb_t)(void *ctx, system_event_t *event);
+
+/**
+  * @brief  Initialize event loop
+  *         Create the event handler and task
+  *
+  * @param  system_event_cb_t cb : application specified event callback, it can be modified by call esp_event_set_cb
+  * @param  void *ctx : reserved for user
+  *
+  * @return ESP_OK : succeed
+  * @return others : fail
+  */
+esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx);
+
+/**
+  * @brief  Set application specified event callback function
+  *
+  * @attention 1. If cb is NULL, means application don't need to handle
+  *               If cb is not NULL, it will be call when an event is received, after the default event callback is completed
+  *
+  * @param  system_event_cb_t cb : callback
+  * @param  void *ctx : reserved for user
+  *
+  * @return system_event_cb_t : old callback
+  */
+system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx);
+
+/**
+  * @brief  Get the queue used by event loop
+  *
+  * @attention : currently this API is used to initialize "q" parameter
+  * of wifi_init structure.
+  *
+  * @return QueueHandle_t : event queue handle
+  */
+QueueHandle_t esp_event_loop_get_queue(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ESP_EVENT_LOOP_H__ */