mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-28 16:46:31 +03:00
feat(esp_event): Allow an event carry more data without malloc
This is both a feature and an optimization. Feature: Adjustable size of the internal storage in esp_event queue, currently used by ISR posting, as they wont be able to make a malloc. Optimization: When non-isr is posting an event, use the inernal storage in the struct instead of always allocating a new heap for the data. Most events in esp-idf only contains a few bytes event information, and we have that allocation payed for anyway. This solved in a big part our memory fragmentation issue, as events happens freqvently and used to create small memory allocations for just 4 bytes, and then in the event handler we usually allocated a bigger chunk of heap for our feature. When returning from the event handler, the 4 byte allocation was freed, leaving a hole in the heap. Merges: https://github.com/espressif/esp-idf/pull/17797
This commit is contained in:
committed by
Konstantin Kondrashov
parent
d1b91b79b5
commit
e2a6653680
@@ -5,7 +5,7 @@ menu "Event Loop Library"
|
||||
default n
|
||||
help
|
||||
Enables collections of statistics in the event loop library such as the number of events posted
|
||||
to/recieved by an event loop, number of callbacks involved, number of events dropped to to a full event
|
||||
to/received by an event loop, number of callbacks involved, number of events dropped to to a full event
|
||||
loop queue, run time of event handlers, and number of times/run time of each event handler.
|
||||
|
||||
config ESP_EVENT_POST_FROM_ISR
|
||||
@@ -14,6 +14,28 @@ menu "Event Loop Library"
|
||||
help
|
||||
Enable posting events from interrupt handlers.
|
||||
|
||||
config ESP_EVENT_POST_FROM_ISR_SIZE
|
||||
int "Max size of data from events (bytes)"
|
||||
default 4
|
||||
depends on ESP_EVENT_POST_FROM_ISR
|
||||
range 4 256
|
||||
help
|
||||
Maximum size (in bytes) of event data that will be kept in the inline event
|
||||
storage.
|
||||
|
||||
When ESP_EVENT_POST_FROM_ISR is enabled, event data with size less
|
||||
than or equal to this value is copied into the fixed-size inline storage.
|
||||
If event's data is larger than this limit, a heap allocation is performed
|
||||
and the data is copied into the allocated buffer before posting.
|
||||
|
||||
When ESP_EVENT_POST_FROM_ISR is disabled, event data is always
|
||||
copied to a heap-allocated buffer to ensure the data remains valid until the
|
||||
event is processed.
|
||||
|
||||
Choose this value to trade static RAM footprint of the inline storage
|
||||
against the frequency of heap allocations: smaller values reduce static
|
||||
memory usage; larger values reduce heap allocations and fragmentation.
|
||||
|
||||
config ESP_EVENT_POST_FROM_IRAM_ISR
|
||||
bool "Support posting events from ISRs placed in IRAM"
|
||||
default y
|
||||
|
||||
@@ -924,6 +924,19 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t
|
||||
memset((void*)(&post), 0, sizeof(post));
|
||||
|
||||
if (event_data != NULL && event_data_size != 0) {
|
||||
#if CONFIG_ESP_EVENT_POST_FROM_ISR
|
||||
if (event_data_size > sizeof(post.data.val)) {
|
||||
post.data.ptr = calloc(1, event_data_size);
|
||||
if (post.data.ptr == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
post.data_allocated = true;
|
||||
memcpy(post.data.ptr, event_data, event_data_size);
|
||||
} else {
|
||||
memcpy((void*)(&(post.data.val)), event_data, event_data_size);
|
||||
}
|
||||
post.data_set = true;
|
||||
#else // !CONFIG_ESP_EVENT_POST_FROM_ISR
|
||||
// Make persistent copy of event data on heap.
|
||||
void* event_data_copy = calloc(1, event_data_size);
|
||||
|
||||
@@ -933,10 +946,7 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop, esp_event_base_t
|
||||
|
||||
memcpy(event_data_copy, event_data, event_data_size);
|
||||
post.data.ptr = event_data_copy;
|
||||
#if CONFIG_ESP_EVENT_POST_FROM_ISR
|
||||
post.data_allocated = true;
|
||||
post.data_set = true;
|
||||
#endif
|
||||
#endif // !CONFIG_ESP_EVENT_POST_FROM_ISR
|
||||
}
|
||||
post.base = event_base;
|
||||
post.id = event_id;
|
||||
|
||||
@@ -92,7 +92,11 @@ typedef struct esp_event_remove_handler_context_t {
|
||||
} esp_event_remove_handler_context_t;
|
||||
|
||||
typedef union esp_event_post_data {
|
||||
uint32_t val;
|
||||
#if CONFIG_ESP_EVENT_POST_FROM_ISR_SIZE
|
||||
uint8_t val[CONFIG_ESP_EVENT_POST_FROM_ISR_SIZE];
|
||||
#else
|
||||
uint8_t val[4];
|
||||
#endif
|
||||
void *ptr;
|
||||
} esp_event_post_data_t;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user