avatar

松果工作室

欢迎光临

  • 首页
  • ESP
  • LVGL
  • CubeMX
  • freeRTOS
  • 快速笔记
  • 个人收藏
  • 我的服务
  • 考察日志
Home ESP Event
文章

ESP Event

Posted 2026-06-2 Updated 2026-06- 2
By YCP
11~14 min read
#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);

ESP
License:  CC BY 4.0
Share

Further Reading

OLDER

ESP32c3 内存占用测试报告

NEWER

HTTP 快速刷新

Recently Updated

  • nimble
  • ESP32c3 内存占用测试报告
  • ESP Event
  • HTTP 快速刷新
  • [adb] 读取屏幕内容与点击,用于测试

Trending Tags

LVGL WCH Linux Elec ThatProject freeRTOS STM ESP Flutter Others

Contents

©2026 松果工作室. Some rights reserved.

Using the Halo theme Chirpy