Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FL-3846] Event Loop Timers #3721

Merged
merged 52 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
dfe17f5
Implement POC event loop tmers (not all edge cases are handled)
gsurkov Jun 14, 2024
5dd2a27
Use a separate ready list to allow for (re)starting and stopping of t…
gsurkov Jun 14, 2024
a7cdc2d
Improve the test application
gsurkov Jun 14, 2024
ed0837c
Improve timer API and test application
gsurkov Jun 14, 2024
e85b126
Merge remote-tracking branch 'origin/dev' into gsurkov/3846_event_loo…
gsurkov Jun 14, 2024
7b01f77
Improve timeout calculation logic
gsurkov Jun 15, 2024
7ead695
Improve timer API, update documentation
gsurkov Jun 15, 2024
09aef56
Fix API usage error
gsurkov Jun 15, 2024
8c05da6
Update doxygen comments
gsurkov Jun 15, 2024
8fcc2b2
Revert the old (correct) check
gsurkov Jun 15, 2024
95d6c9c
Improve function naming
gsurkov Jun 15, 2024
21ab696
Check whether a timer was on the expired list before processing it
gsurkov Jun 15, 2024
3de2de0
Merge remote-tracking branch 'origin' into gsurkov/3846_event_loop_ti…
gsurkov Jun 16, 2024
9b9ec6b
Implement tick callback
gsurkov Jun 16, 2024
6da5ee4
Add critical sections to improve timer consistency
gsurkov Jun 16, 2024
ee1df8f
Simplify event loop timer API
gsurkov Jun 16, 2024
85b0176
Remove redundant search
gsurkov Jun 17, 2024
518d767
Refactor timer logic, use message queue
gsurkov Jun 18, 2024
73e4c64
Simplify FuriEventLoopTimer API
gsurkov Jun 18, 2024
6d8076d
Improve event loop timer logic
gsurkov Jun 18, 2024
3386ff1
Update the f18 target
gsurkov Jun 18, 2024
e7a8e95
Merge remote-tracking branch 'origin/dev' into gsurkov/3846_event_loo…
gsurkov Jun 18, 2024
8829b76
Remove superfluous clears
gsurkov Jun 18, 2024
4388408
Correct f18 api symbols
gsurkov Jun 18, 2024
86f4394
Fix doxygen comments
gsurkov Jun 18, 2024
db916cd
Update .pvsconfig
gsurkov Jun 18, 2024
81f56c1
Merge branch 'dev' into gsurkov/3846_event_loop_timers
gsurkov Jun 18, 2024
9823882
Use a double push list instead of deque
gsurkov Jun 19, 2024
509f3a9
Update .pvsconfig
gsurkov Jun 19, 2024
ce1f432
Add pending callback functionality
gsurkov Jun 19, 2024
33325a9
Restore unprocessed flags when applicable
gsurkov Jun 19, 2024
d693b1f
Refactor Dolphin app to use FuriEventLoop
gsurkov Jun 19, 2024
21d0c24
Improve naming
gsurkov Jun 19, 2024
8bfb74f
Update naming some more
gsurkov Jun 19, 2024
90baeb6
Merge branch 'dev' into gsurkov/3846_event_loop_timers
skotopes Jun 20, 2024
9c98f46
Fix a typo
gsurkov Jun 20, 2024
a255a82
Fix wait time in example
gsurkov Jun 20, 2024
23cc4ce
Bump API version
gsurkov Jun 21, 2024
b95a0b7
Merge remote-tracking branch 'origin/dev' into gsurkov/3846_event_loo…
skotopes Jun 22, 2024
68d281d
Debug: multiple of 25 timings in event loop blink test
skotopes Jun 22, 2024
7a466bb
Separate FuriEventLoopTimer to its own set of files
gsurkov Jun 23, 2024
2318435
Improve start time calculation for periodic timers
gsurkov Jun 24, 2024
e323a4b
Merge branch 'dev' into gsurkov/3846_event_loop_timers
gsurkov Jun 27, 2024
fb3448a
Merge remote-tracking branch 'origin/dev' into gsurkov/3846_event_loo…
skotopes Jun 30, 2024
6dca1df
Do not use dynamic allocations for timer requests
gsurkov Jul 1, 2024
eaa708d
Split the tick functionality in separate files, rearrange code
gsurkov Jul 1, 2024
364c6ff
Improve timer queue handling
gsurkov Jul 1, 2024
3b16af3
Properly reset GPIO pins in the test app
gsurkov Jul 1, 2024
fe5582d
Properly initialise GPIO pins in the test app too
gsurkov Jul 1, 2024
9cf5242
Merge branch 'dev' into gsurkov/3846_event_loop_timers
gsurkov Jul 2, 2024
938581c
Furi: variable naming in event loop
skotopes Jul 2, 2024
f324d87
Furi: fix spelling in event loop
skotopes Jul 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .pvsconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
//-V:M_EACH:1048,1044
//-V:ARRAY_DEF:760,747,568,776,729,712,654,1103
//-V:LIST_DEF:760,747,568,712,729,654,776,1103
//-V:LIST_DUAL_PUSH_DEF:524,760,774
//-V:BPTREE_DEF2:779,1086,557,773,512
//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685,1103
//-V:ALGO_DEF:1048,747,1044
//-V:TUPLE_DEF2:524,590,1001,760
//-V:DEQUE_DEF:658,747,760

# Non-severe malloc/null pointer deref warnings
//-V::522:2,3
Expand Down Expand Up @@ -43,4 +45,4 @@
//-V:with_view_model:1044,1048

# Examples
//V_EXCLUDE_PATH applications/examples/
//V_EXCLUDE_PATH applications/examples/
10 changes: 10 additions & 0 deletions applications/debug/event_loop_blink_test/application.fam
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
App(
appid="event_loop_blink_test",
name="Event Loop Blink Test",
apptype=FlipperAppType.DEBUG,
entry_point="event_loop_blink_test_app",
requires=["input"],
stack_size=1 * 1024,
order=20,
fap_category="Debug",
)
165 changes: 165 additions & 0 deletions applications/debug/event_loop_blink_test/event_loop_blink_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#include <furi.h>
#include <furi_hal_resources.h>

#include <gui/gui.h>
#include <gui/elements.h>
#include <gui/view_port.h>

#include <input/input.h>

#define TAG "EventLoopBlinkTest"

#define TIMER_COUNT (6U)

typedef struct {
FuriEventLoop* event_loop;
FuriMessageQueue* input_queue;
FuriEventLoopTimer* timers[TIMER_COUNT];
} EventLoopBlinkTestApp;

static const GpioPin* blink_gpio_pins[] = {
&gpio_ext_pa7,
&gpio_ext_pa6,
&gpio_ext_pa4,
&gpio_ext_pb3,
&gpio_ext_pb2,
&gpio_ext_pc3,
};

static_assert(COUNT_OF(blink_gpio_pins) == TIMER_COUNT);

static const uint32_t timer_intervals[] = {
320,
750,
1000,
500,
150,
210,
};

static_assert(COUNT_OF(timer_intervals) == TIMER_COUNT);

static void blink_gpio_init(void) {
for(size_t i = 0; i < TIMER_COUNT; ++i) {
furi_hal_gpio_init_simple(blink_gpio_pins[i], GpioModeOutputPushPull);
}

furi_hal_gpio_init_simple(&gpio_ext_pc0, GpioModeOutputPushPull);
}

static void blink_gpio_deinit(void) {
for(size_t i = 0; i < TIMER_COUNT; ++i) {
furi_hal_gpio_init_simple(blink_gpio_pins[i], GpioModeAnalog);
}

furi_hal_gpio_init_simple(&gpio_ext_pc0, GpioModeAnalog);
}

static void view_port_draw_callback(Canvas* canvas, void* context) {
UNUSED(context);
canvas_clear(canvas);
elements_text_box(
canvas,
0,
0,
canvas_width(canvas),
canvas_height(canvas),
AlignCenter,
AlignCenter,
"\e#Event Loop Timers Test\e#\n"
"Press buttons\n"
"to enable or disable timers\n"
"\e#Exit\e# = long press \e#Back\e#",
false);
}

static void view_port_input_callback(InputEvent* input_event, void* context) {
EventLoopBlinkTestApp* app = context;
furi_message_queue_put(app->input_queue, input_event, 0);
}

static bool input_queue_callback(FuriMessageQueue* queue, void* context) {
EventLoopBlinkTestApp* app = context;

InputEvent event;
FuriStatus status = furi_message_queue_get(queue, &event, FuriWaitForever);
skotopes marked this conversation as resolved.
Show resolved Hide resolved
furi_assert(status == FuriStatusOk);

if(event.type == InputTypeShort) {
const size_t timer_idx = event.key;
furi_assert(timer_idx < TIMER_COUNT);

FuriEventLoopTimer* timer = app->timers[timer_idx];

if(furi_event_loop_timer_is_running(timer)) {
furi_event_loop_timer_stop(timer);
} else {
furi_event_loop_timer_restart(timer);
}

} else if(event.type == InputTypeLong) {
if(event.key == InputKeyBack) {
furi_event_loop_stop(app->event_loop);
}
}

return true;
}

static void blink_timer_callback(void* context) {
const GpioPin* gpio = blink_gpio_pins[(size_t)context];
furi_hal_gpio_write(gpio, !furi_hal_gpio_read(gpio));
}

static void event_loop_tick_callback(void* context) {
UNUSED(context);
furi_hal_gpio_write(&gpio_ext_pc0, !furi_hal_gpio_read(&gpio_ext_pc0));
}

int32_t event_loop_blink_test_app(void* arg) {
UNUSED(arg);

blink_gpio_init();

EventLoopBlinkTestApp app;

app.event_loop = furi_event_loop_alloc();
app.input_queue = furi_message_queue_alloc(3, sizeof(InputEvent));

for(size_t i = 0; i < TIMER_COUNT; ++i) {
app.timers[i] = furi_event_loop_timer_alloc(
app.event_loop, blink_timer_callback, FuriEventLoopTimerTypePeriodic, (void*)i);
furi_event_loop_timer_start(app.timers[i], timer_intervals[i]);
}

ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, view_port_draw_callback, &app);
view_port_input_callback_set(view_port, view_port_input_callback, &app);

Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);

furi_event_loop_tick_set(app.event_loop, 500, event_loop_tick_callback, &app);
furi_event_loop_message_queue_subscribe(
app.event_loop, app.input_queue, FuriEventLoopEventIn, input_queue_callback, &app);

furi_event_loop_run(app.event_loop);

gui_remove_view_port(gui, view_port);
view_port_free(view_port);

furi_record_close(RECORD_GUI);

furi_event_loop_message_queue_unsubscribe(app.event_loop, app.input_queue);
furi_message_queue_free(app.input_queue);

for(size_t i = 0; i < TIMER_COUNT; ++i) {
furi_event_loop_timer_free(app.timers[i]);
}

furi_event_loop_free(app.event_loop);

blink_gpio_deinit();

return 0;
}
Loading
Loading