#include "os_event.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/task.h" #include "esp_log.h" static const char *TAG = "SYS_EVENT"; #define MAX_SUBSCRIBERS 16 #define EVENT_QUEUE_LEN 32 typedef struct { sys_event_cb_t callback; void *user_arg; } subscriber_entry_t; static subscriber_entry_t s_subscribers[MAX_SUBSCRIBERS]; static size_t s_subscriber_count = 0; static QueueHandle_t s_event_queue = NULL; static void sys_event_dispatch_task(void *pvParameters) { sys_event_t event; while (1) { if (xQueueReceive(s_event_queue, &event, portMAX_DELAY) == pdTRUE) { for (size_t i = 0; i < s_subscriber_count; i++) { if (s_subscribers[i].callback) { s_subscribers[i].callback(&event, s_subscribers[i].user_arg); } } } } } esp_err_t sys_event_init(void) { if (s_event_queue != NULL) { return ESP_OK; } s_event_queue = xQueueCreate(EVENT_QUEUE_LEN, sizeof(sys_event_t)); if (!s_event_queue) { ESP_LOGE(TAG, "Failed to create event queue"); return ESP_ERR_NO_MEM; } BaseType_t ret = xTaskCreate(sys_event_dispatch_task, "sys_event_task", 3072, NULL, 10, NULL); if (ret != pdPASS) { ESP_LOGE(TAG, "Failed to create event dispatcher task"); return ESP_FAIL; } ESP_LOGI(TAG, "System Event Bus initialized"); return ESP_OK; } esp_err_t sys_event_post(sys_event_id_t id, int32_t data, void *ptr_data) { if (!s_event_queue) { return ESP_ERR_INVALID_STATE; } sys_event_t event = { .id = id, .data = data, .ptr_data = ptr_data }; if (xQueueSend(s_event_queue, &event, 0) != pdTRUE) { ESP_LOGW(TAG, "Event queue full, dropped event %d", (int)id); return ESP_ERR_NO_MEM; } return ESP_OK; } esp_err_t sys_event_subscribe(sys_event_cb_t callback, void *user_arg) { if (!callback) return ESP_ERR_INVALID_ARG; if (s_subscriber_count >= MAX_SUBSCRIBERS) { ESP_LOGE(TAG, "Max subscribers reached"); return ESP_ERR_NO_MEM; } s_subscribers[s_subscriber_count].callback = callback; s_subscribers[s_subscriber_count].user_arg = user_arg; s_subscriber_count++; return ESP_OK; }