Optimize timer callbacks

It turned out that esp_event was adding extra complexity to the code base and it was completely unnecessary. So it has been removed from the component completely. The actions are now executed directly in the `relay_chn_distpacth_cmd()` and `relay_chn_tilt_dispatch_cmd()` functions.
This change has simplified the component as well as reduced the memory footprint.

Fixes #1084, refs #1083
This commit is contained in:
2025-08-22 17:41:08 +03:00
parent e73c205e3d
commit 7a0f9b1420
6 changed files with 34 additions and 148 deletions

View File

@@ -22,31 +22,9 @@
#include "relay_chn_core.h"
/*
Determine the event loop's queue and task stack sizes depending on
the configuration and memory requirements
*/
#if RELAY_CHN_ENABLE_TILTING == 1
#define EVENT_QUEUE_BASE_SIZE 32
#define EVENT_QUEUE_SIZE_BY_CHN 24
#define TASK_STACK_BASE_SIZE 4096
#else
#define EVENT_QUEUE_BASE_SIZE 16
#define EVENT_QUEUE_SIZE_BY_CHN 12
#define TASK_STACK_BASE_SIZE 2048
#endif
#define RELAY_CHN_EVENT_LOOP_QUEUE_SIZE \
(EVENT_QUEUE_BASE_SIZE + (EVENT_QUEUE_SIZE_BY_CHN * RELAY_CHN_COUNT))
#define RELAY_CHN_EVENT_LOOP_TASK_STACK_SIZE \
(TASK_STACK_BASE_SIZE + (RELAY_CHN_EVENT_LOOP_QUEUE_SIZE * RELAY_CHN_COUNT))
static const char *TAG = "RELAY_CHN_CORE";
ESP_EVENT_DEFINE_BASE(RELAY_CHN_CMD_EVENT);
// Structure to hold a listener entry in the linked list.
typedef struct relay_chn_listener_entry_type {
@@ -57,15 +35,6 @@ typedef struct relay_chn_listener_entry_type {
// The list that holds references to the registered listeners.
static List_t relay_chn_listener_list;
// Define the event loop for global access both for this module and tilt module.
esp_event_loop_handle_t relay_chn_event_loop = NULL;
// Private function declarations
// Event handler for the relay channel command event
static void relay_chn_event_handler(void* handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
/*
* Run limit timer callback immediately dispatches a STOP command for the
@@ -116,24 +85,6 @@ esp_err_t relay_chn_init_timer(relay_chn_ctl_t *chn_ctl)
return esp_timer_create(&timer_args, &chn_ctl->inertia_timer);
}
static esp_err_t relay_chn_create_event_loop()
{
esp_event_loop_args_t loop_args = {
.queue_size = RELAY_CHN_EVENT_LOOP_QUEUE_SIZE,
.task_name = "relay_chn_event_loop",
.task_priority = ESP_TASKD_EVENT_PRIO - 1,
.task_stack_size = RELAY_CHN_EVENT_LOOP_TASK_STACK_SIZE,
.task_core_id = tskNO_AFFINITY
};
esp_err_t ret = esp_event_loop_create(&loop_args, &relay_chn_event_loop);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create event loop for relay channel");
ret = esp_event_handler_register_with(relay_chn_event_loop,
RELAY_CHN_CMD_EVENT,
ESP_EVENT_ANY_ID,
relay_chn_event_handler, NULL);
return ret;
}
esp_err_t relay_chn_create(const uint8_t* gpio_map, uint8_t gpio_count)
{
ESP_RETURN_ON_FALSE(gpio_map != NULL, ESP_ERR_INVALID_ARG, TAG, "gpio_map cannot be NULL");
@@ -163,10 +114,6 @@ esp_err_t relay_chn_create(const uint8_t* gpio_map, uint8_t gpio_count)
ret = relay_chn_ctl_init(outputs, run_infos);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize relay channel control");
// Create relay channel command event loop
ret = relay_chn_create_event_loop();
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create relay channel event loop");
#if RELAY_CHN_ENABLE_TILTING == 1
// Initialize the tilt feature
#if RELAY_CHN_COUNT > 1
@@ -196,10 +143,6 @@ void relay_chn_destroy(void)
relay_chn_nvs_deinit();
#endif
// Destroy the event loop
esp_event_loop_delete(relay_chn_event_loop);
relay_chn_event_loop = NULL;
// Free the listeners
while (listCURRENT_LIST_LENGTH(&relay_chn_listener_list) > 0) {
ListItem_t *pxItem = listGET_HEAD_ENTRY(&relay_chn_listener_list);
@@ -283,31 +226,6 @@ void relay_chn_unregister_listener(relay_chn_state_listener_t listener)
}
// Dispatch relay channel command to its event loop
void relay_chn_dispatch_cmd(relay_chn_ctl_t *chn_ctl, relay_chn_cmd_t cmd) {
if (cmd == RELAY_CHN_CMD_NONE) {
return;
}
// Since the event_loop library creates a deep copy of the event data,
// and we need to pass the pointer of the relevant channel, here we need
// to pass the pointer to the pointer of the channel (&chn_ctl) so that
// the pointer value is preserved in the event data.
esp_event_post_to(relay_chn_event_loop,
RELAY_CHN_CMD_EVENT,
cmd,
&chn_ctl,
sizeof(chn_ctl),
portMAX_DELAY);
#if RELAY_CHN_ENABLE_TILTING == 1
// Reset the tilt counter when the command is either FORWARD or REVERSE
if (cmd == RELAY_CHN_CMD_FORWARD || cmd == RELAY_CHN_CMD_REVERSE) {
relay_chn_tilt_reset_count(chn_ctl->tilt_ctl);
}
#endif
}
esp_err_t relay_chn_start_esp_timer_once(esp_timer_handle_t esp_timer, uint32_t time_ms)
{
esp_err_t ret = esp_timer_start_once(esp_timer, time_ms * 1000);
@@ -498,6 +416,14 @@ bool relay_chn_is_channel_id_valid(uint8_t chn_id)
#endif // RELAY_CHN_COUNT > 1
static void relay_chn_execute_idle(relay_chn_ctl_t *chn_ctl)
{
chn_ctl->pending_cmd = RELAY_CHN_CMD_NONE;
// Invalidate the channel's timer if it is active
esp_timer_stop(chn_ctl->inertia_timer);
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_IDLE);
}
static void relay_chn_execute_stop(relay_chn_ctl_t *chn_ctl)
{
if (relay_chn_output_stop(chn_ctl->output) != ESP_OK) {
@@ -525,7 +451,8 @@ static void relay_chn_execute_stop(relay_chn_ctl_t *chn_ctl)
relay_chn_start_esp_timer_once(chn_ctl->inertia_timer, RELAY_CHN_OPPOSITE_INERTIA_MS);
} else {
// If the channel was not running one of the run or fwd, issue a free command immediately
relay_chn_dispatch_cmd(chn_ctl, RELAY_CHN_CMD_IDLE);
// relay_chn_dispatch_cmd(chn_ctl, RELAY_CHN_CMD_IDLE);
relay_chn_execute_idle(chn_ctl);
}
}
@@ -565,21 +492,11 @@ static void relay_chn_execute_flip(relay_chn_ctl_t *chn_ctl)
relay_chn_start_esp_timer_once(chn_ctl->inertia_timer, RELAY_CHN_OPPOSITE_INERTIA_MS);
}
void relay_chn_execute_idle(relay_chn_ctl_t *chn_ctl)
{
chn_ctl->pending_cmd = RELAY_CHN_CMD_NONE;
// Invalidate the channel's timer if it is active
esp_timer_stop(chn_ctl->inertia_timer);
relay_chn_update_state(chn_ctl, RELAY_CHN_STATE_IDLE);
}
// Dispatch relay channel command
void relay_chn_dispatch_cmd(relay_chn_ctl_t *chn_ctl, relay_chn_cmd_t cmd) {
ESP_LOGD(TAG, "relay_chn_dispatch_cmd: Command: %d", cmd);
static void relay_chn_event_handler(void* handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
relay_chn_ctl_t* chn_ctl = *(relay_chn_ctl_t**) event_data;
ESP_RETURN_VOID_ON_FALSE(chn_ctl != NULL, TAG, "event_data is NULL");
ESP_LOGD(TAG, "relay_chn_event_handler: Command: %s", relay_chn_cmd_str(event_id));
switch (event_id) {
switch (cmd) {
case RELAY_CHN_CMD_STOP:
relay_chn_execute_stop(chn_ctl);
break;
@@ -598,6 +515,13 @@ static void relay_chn_event_handler(void* handler_arg, esp_event_base_t event_ba
default:
ESP_LOGD(TAG, "Unknown relay channel command!");
}
#if RELAY_CHN_ENABLE_TILTING == 1
// Reset the tilt counter when the command is either FORWARD or REVERSE
if (cmd == RELAY_CHN_CMD_FORWARD || cmd == RELAY_CHN_CMD_REVERSE) {
relay_chn_tilt_reset_count(chn_ctl->tilt_ctl);
}
#endif
}
char *relay_chn_cmd_str(relay_chn_cmd_t cmd)

View File

@@ -39,8 +39,6 @@ static const char *TAG = "RELAY_CHN_TILT";
* 100 / (RELAY_CHN_TILT_RUN_MAX_MS - RELAY_CHN_TILT_RUN_MIN_MS) )
/**@}*/
ESP_EVENT_DEFINE_BASE(RELAY_CHN_TILT_CMD_EVENT_BASE);
/// @brief Tilt steps.
typedef enum {
@@ -78,21 +76,6 @@ static relay_chn_tilt_ctl_t tilt_ctl;
#endif
esp_err_t relay_chn_tilt_dispatch_cmd(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_tilt_cmd_t cmd)
{
if (cmd == RELAY_CHN_TILT_CMD_NONE) return ESP_ERR_INVALID_ARG;
// Since the event_loop library creates a deep copy of the event data,
// and we need to pass the pointer of the relevant tilt control, here we need
// to pass the pointer to the pointer of the tilt_control (&tilt_ctl) so that
// the pointer value is preserved in the event data.
return esp_event_post_to(relay_chn_event_loop,
RELAY_CHN_TILT_CMD_EVENT_BASE,
cmd,
&tilt_ctl,
sizeof(tilt_ctl), portMAX_DELAY);
}
// Returns the required timing before tilting depending on the last run.
static uint32_t relay_chn_tilt_get_required_timing_before_tilting(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_tilt_cmd_t cmd)
{
@@ -561,13 +544,11 @@ static void relay_chn_tilt_execute_pause(relay_chn_tilt_ctl_t *tilt_ctl)
tilt_ctl->step = RELAY_CHN_TILT_STEP_MOVE;
}
static void relay_chn_tilt_event_handler(void *handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
esp_err_t relay_chn_tilt_dispatch_cmd(relay_chn_tilt_ctl_t *tilt_ctl, relay_chn_tilt_cmd_t cmd)
{
relay_chn_tilt_ctl_t* tilt_ctl = *(relay_chn_tilt_ctl_t**) event_data;
ESP_RETURN_VOID_ON_FALSE(tilt_ctl != NULL, TAG, "event_data is NULL");
ESP_LOGD(TAG, "relay_chn_event_handler: Command: %s", relay_chn_cmd_str(event_id));
ESP_LOGD(TAG, "relay_chn_tilt_dispatch_cmd: Command: %d", cmd);
switch(event_id) {
switch(cmd) {
case RELAY_CHN_TILT_CMD_STOP:
relay_chn_tilt_execute_stop(tilt_ctl);
break;
@@ -582,8 +563,9 @@ static void relay_chn_tilt_event_handler(void *handler_arg, esp_event_base_t eve
relay_chn_update_state(tilt_ctl->chn_ctl, RELAY_CHN_STATE_TILT_REVERSE);
break;
default:
ESP_LOGW(TAG, "Unexpected relay channel tilt command: %ld!", event_id);
ESP_LOGW(TAG, "Unexpected relay channel tilt command: %d!", cmd);
}
return ESP_OK;
}
// Timer callback for the relay_chn_tilt_control_t::tilt_timer
@@ -693,8 +675,10 @@ esp_err_t relay_chn_tilt_init(relay_chn_ctl_t *chn_ctls)
sensitivity = RELAY_CHN_TILT_DEFAULT_SENSITIVITY;
tilt_count = 0;
#endif // RELAY_CHN_ENABLE_NVS == 1
relay_chn_tilt_ctl_init(&tilt_ctls[i], &chn_ctls[i], tilt_count, sensitivity);
ret = relay_chn_tilt_ctl_init(&tilt_ctls[i], &chn_ctls[i], tilt_count, sensitivity);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to init tilt control for channel %d", i);
}
return ESP_OK;
#else
sensitivity = RELAY_CHN_TILT_DEFAULT_SENSITIVITY;
tilt_count = 0;
@@ -704,13 +688,8 @@ esp_err_t relay_chn_tilt_init(relay_chn_ctl_t *chn_ctls)
ret = relay_chn_tilt_load_tilt_count(0, &tilt_count);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to load tilt count for channel %d", 0);
#endif // RELAY_CHN_ENABLE_NVS == 1
relay_chn_tilt_ctl_init(&tilt_ctl, chn_ctls, tilt_count, sensitivity);
return relay_chn_tilt_ctl_init(&tilt_ctl, chn_ctls, tilt_count, sensitivity);
#endif // RELAY_CHN_COUNT > 1
return esp_event_handler_register_with(relay_chn_event_loop,
RELAY_CHN_TILT_CMD_EVENT_BASE,
ESP_EVENT_ANY_ID,
relay_chn_tilt_event_handler, NULL);
}
void relay_chn_tilt_ctl_deinit(relay_chn_tilt_ctl_t *tilt_ctl)
@@ -736,8 +715,4 @@ void relay_chn_tilt_deinit()
#else
relay_chn_tilt_ctl_deinit(&tilt_ctl);
#endif // RELAY_CHN_COUNT > 1
esp_event_handler_unregister_with(relay_chn_event_loop,
RELAY_CHN_TILT_CMD_EVENT_BASE,
ESP_EVENT_ANY_ID,
relay_chn_tilt_event_handler);
}