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
This commit is contained in:
parent
cc8dd46da2
commit
53de9f115f
4 changed files with 211 additions and 124 deletions
|
@ -19,6 +19,7 @@
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
|
#include "esp_event_loop.h"
|
||||||
#include "esp_task.h"
|
#include "esp_task.h"
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
|
@ -29,14 +30,7 @@
|
||||||
#include "tcpip_adapter.h"
|
#include "tcpip_adapter.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
#define ESP32_WORKAROUND 1
|
const char* TAG = "event";
|
||||||
|
|
||||||
#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;
|
|
||||||
|
|
||||||
#define WIFI_API_CALL_CHECK(info, api_call, ret) \
|
#define WIFI_API_CALL_CHECK(info, api_call, ret) \
|
||||||
do{\
|
do{\
|
||||||
|
@ -175,15 +169,6 @@ esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event)
|
||||||
return ESP_OK;
|
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)
|
static esp_err_t esp_system_event_debug(system_event_t *event)
|
||||||
{
|
{
|
||||||
if (event == NULL) {
|
if (event == NULL) {
|
||||||
|
@ -274,7 +259,7 @@ static esp_err_t esp_system_event_debug(system_event_t *event)
|
||||||
return ESP_OK;
|
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) {
|
if (event == NULL) {
|
||||||
ESP_LOGE(TAG, "Error: event is 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 {
|
} else {
|
||||||
ESP_LOGE(TAG, "mismatch or invalid event, id=%d", event->event_id);
|
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_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ESP_OK;
|
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
components/esp32/event_loop.c
Normal file
118
components/esp32/event_loop.c
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -105,30 +105,6 @@ typedef struct {
|
||||||
system_event_info_t event_info; /**< event information */
|
system_event_info_t event_info; /**< event information */
|
||||||
} system_event_t;
|
} 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
|
* @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);
|
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,
|
* This function performs default handling of system events.
|
||||||
* users can notice when WiFi has done something like scanning done, connected to AP or disconnected from AP.
|
* 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
81
components/esp32/include/esp_event_loop.h
Normal file
81
components/esp32/include/esp_event_loop.h
Normal file
|
@ -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__ */
|
Loading…
Reference in a new issue