ESP Event
#include <string.h>
#include "wls_event.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "esp_event.h"
static const char *TAG = "TASK_EVENT";
#define WLS_EVENT_QUEUE_SIZE 10
#define WLS_DELAY_EVENT_QUEUE_SIZE 10
#define WLS_EVENT_DATA_MAX_SIZE 512
ESP_EVENT_DEFINE_BASE(WLS_EVENT);
esp_event_loop_handle_t wlsevt_loop_handle = NULL;
typedef struct {
wlsevt_id_t wlsevt_id;
size_t event_data_size;
TickType_t target_time;
uint8_t event_data[WLS_EVENT_DATA_MAX_SIZE];
} wls_delayed_event_t;
static QueueHandle_t wls_delayed_event_queue = NULL;
static TaskHandle_t wls_delayed_event_task_handle = NULL;
static void wls_event_post_now(wlsevt_id_t wlsevt_id, const void *event_data, size_t event_data_size) {
if (!wlsevt_loop_handle) {
ESP_LOGW(TAG, "event loop not ready");
return;
}
esp_err_t err = esp_event_post_to(
wlsevt_loop_handle,
WLS_EVENT,
wlsevt_id,
event_data,
event_data_size,
pdMS_TO_TICKS(1000));
if (err != ESP_OK) {
ESP_LOGW(TAG, "post failed: %s", esp_err_to_name(err));
}
}
static void wls_delayed_event_task(void *arg) {
wls_delayed_event_t delayed_event;
for (;;) {
if (xQueueReceive(wls_delayed_event_queue, &delayed_event, pdMS_TO_TICKS(20)) != pdTRUE) {
continue;
}
TickType_t now = xTaskGetTickCount();
if ((int32_t)(now - delayed_event.target_time) >= 0) {
const void *event_data = delayed_event.event_data_size > 0 ? delayed_event.event_data : NULL;
wls_event_post_now(delayed_event.wlsevt_id, event_data, delayed_event.event_data_size);
} else {
xQueueSend(wls_delayed_event_queue, &delayed_event, portMAX_DELAY);
vTaskDelay(pdMS_TO_TICKS(50));
}
}
}
__attribute__((weak)) void wls_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data) {
}
void wls_event_init(void) {
esp_event_loop_args_t loop_args = {
.queue_size = WLS_EVENT_QUEUE_SIZE,
.task_name = "wlsevt_loop",
.task_priority = 5,
.task_stack_size = 4096,
.task_core_id = tskNO_AFFINITY
};
esp_event_loop_create(&loop_args, &wlsevt_loop_handle);
esp_event_handler_register_with(
wlsevt_loop_handle,
WLS_EVENT,
ESP_EVENT_ANY_ID,
wls_event_handler,
NULL);
wls_delayed_event_queue = xQueueCreate(WLS_DELAY_EVENT_QUEUE_SIZE, sizeof(wls_delayed_event_t));
if (!wls_delayed_event_queue) {
ESP_LOGW(TAG, "create delayed event queue failed");
return;
}
xTaskCreate(
wls_delayed_event_task,
"wlsevt_delay",
4096,
NULL,
5,
&wls_delayed_event_task_handle);
}
void wls_event_post(wlsevt_id_t wlsevt_id, const void *event_data, size_t event_data_size, uint32_t delayms) {
if (delayms == 0) {
wls_event_post_now(wlsevt_id, event_data, event_data_size);
return;
}
if (event_data_size > 0 && event_data == NULL) {
ESP_LOGW(TAG, "event data is NULL");
return;
}
if (!wls_delayed_event_queue) {
ESP_LOGW(TAG, "delayed event queue not ready");
return;
}
if (event_data_size > WLS_EVENT_DATA_MAX_SIZE) {
ESP_LOGW(TAG, "event data too large: %u", (unsigned int) event_data_size);
return;
}
wls_delayed_event_t delayed_event = {
.wlsevt_id = wlsevt_id,
.event_data_size = event_data_size,
.target_time = xTaskGetTickCount() + pdMS_TO_TICKS(delayms),
};
if (event_data_size > 0) {
memcpy(delayed_event.event_data, event_data, event_data_size);
}
if (xQueueSend(wls_delayed_event_queue, &delayed_event, pdMS_TO_TICKS(1000)) != pdTRUE) {
ESP_LOGW(TAG, "delayed event queue full");
}
}
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "esp_event.h"
/** 平台 → 产品:只描述「发生了什么」,不含业务策略 */
typedef enum {
WLSEVT_PWRON = 0,
WLSEVT_WIFI_CONNECT,
WLSEVT_WIFI_CONFIG_SAVE,
WLSEVT_WIFI_GOT_IP,
WLSEVT_MQTT_MESSAGE,
WLSEVT_HTTP_RESPONSE,
WLSEVT_BUTTON,
WLSEVT_OTA_START,
WLSEVT_DEBUG_LOG,
} wlsevt_id_t;
typedef struct {
char ssid[32 + 1];
char password[64 + 1];
} wls_wifi_config_t;
typedef struct {
char topic[128 + 1];
char payload[256 + 1];
} wls_mqtt_msg_t;
typedef enum {
WLS_HTTP_Q_DINGCFG = 0,
WLS_HTTP_Q_WEATHER,
WLS_HTTP_Q_QUALITY,
} wls_http_query_id_t;
typedef struct {
wls_http_query_id_t query_id;
char body[400 + 1];
} wls_http_response_t;
void wls_event_init(void);
void wls_event_post(wlsevt_id_t wlsevt_id, const void *event_data, size_t event_data_size, uint32_t delayms);
/** 各产品在 product.c 中实现,作为业务编排入口 */
__attribute__((weak)) void wls_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data);
License:
CC BY 4.0