85 lines
2.3 KiB
C
85 lines
2.3 KiB
C
#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;
|
|
}
|