diff --git a/components/esp32/event.c b/components/esp32/event_default_handlers.c similarity index 84% rename from components/esp32/event.c rename to components/esp32/event_default_handlers.c index b26a4ea30..37ba63404 100644 --- a/components/esp32/event.c +++ b/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 diff --git a/components/esp32/event_loop.c b/components/esp32/event_loop.c new file mode 100644 index 000000000..be00e34be --- /dev/null +++ b/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 +#include +#include + +#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; +} + diff --git a/components/esp32/include/esp_event.h b/components/esp32/include/esp_event.h index 34358a267..86afab2c4 100644 --- a/components/esp32/include/esp_event.h +++ b/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 } diff --git a/components/esp32/include/esp_event_loop.h b/components/esp32/include/esp_event_loop.h new file mode 100644 index 000000000..97672aedf --- /dev/null +++ b/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 +#include + +#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__ */