I have a question on how to structure an event driven firmware using Zephyr RTOS. It's a general question which way should be used. Or maybe I am completely wrong? The application isn't time critical.
Case A:
- Using features as k_work, k_timer, k_poll/k_sem as much as possible
- Since these function require a c-style callback a lot of free functions will be used
- A dispatcher/subscriber event queue for posting events (like button pressed, turn led on, ...), these events will be handled inside the main loop (similar to Case B)
- LED animation can be handled by the module itself (k_work)
// wait for something to happen
k_poll(...);
dispatcher.process();
Case B:
- Own implementation of dispatcher/subscriber system
- Classes can be used for all elements (Button, LED, ...)
- All events are processed inside the main loop
- Interrupts can wakeup the main thread if it sleeps
- LED object can send an event when they need a wakeup (for animation, ...)
- Main is using the lowest value for sleep time from the above events
- LED subscribes to
LoopEvent
to do the animations
dispatcher.post(std::make_unique<LoopEvent>());
dispatcher.process();
k_msleep(powermanager.getSleepTime());
I think Case B
is more structured and clear how what happens. Everything is controlled from the main loop and everything is using the same dispatch/subscribe system.