-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevent_loop.c
93 lines (74 loc) · 2.04 KB
/
event_loop.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "event_loop.h"
#include "FreeRTOS.h"
#include "queue.h"
static QueueHandle_t event_queue;
static EventHandler event_handlers[MAX_EVENTS][MAX_HANDLERS_PER_EVENT] = { 0 };
static void event_loop_handle_task(void* pv_parameters);
int event_loop_init(void)
{
event_queue = xQueueCreate(MAX_EVENTS, sizeof(Event));
if (event_queue == NULL)
return -1;
int task_result = xTaskCreate(event_loop_handle_task, "event_loop_handle_task", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
if (task_result != 1)
return -1;
return 0;
}
int event_loop_register_handler(EventHandler event_handler, EventType event_type)
{
if (event_type >= MAX_EVENTS || event_handler == NULL)
return -1;
for (int i = 0; i < MAX_HANDLERS_PER_EVENT; i++)
{
if (event_handlers[event_type][i] == NULL)
{
event_handlers[event_type][i] = event_handler;
return 0;
}
}
return -1;
}
int event_loop_unregister_handler(EventHandler event_handler, EventType event_type)
{
for (int i = 0; i < MAX_HANDLERS_PER_EVENT; i++) {
if (event_handlers[event_type][i] == event_handler) {
event_handlers[event_type][i] = NULL;
return 0;
}
}
return -1;
}
int event_loop_send_event(Event event) {
// Check if the current context is ISR
if (xPortIsInsideInterrupt()) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (xQueueSendFromISR(event_queue, &event, &xHigherPriorityTaskWoken) != pdPASS) {
return -1;
}
// Optionally, request a context switch if needed
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
else {
if (xQueueSend(event_queue, &event, portMAX_DELAY) != pdPASS) {
return -1;
}
}
return 0;
}
static void event_loop_handle_task(void* pv_parameters)
{
Event event;
while (1)
{
if (xQueueReceive(event_queue, &event, portMAX_DELAY) == pdPASS)
{
for (int i = 0; i < MAX_HANDLERS_PER_EVENT; i++)
{
if (event_handlers[event.event_type][i] != NULL)
{
event_handlers[event.event_type][i](&event);
}
}
}
}
}