In previous blog posts, I introduced two essential components of a simple and universally applicable software architecture: events with dispatchers, listeners, and data pools. These already make it easy to implement many simple use cases.
But it's rarely easy. When communicating with remote systems (e.g., with a second MCU communicating via UART), timeouts must be repeatedly responded to for safety reasons. This means you have to "wind up" a timer each time and respond accordingly in the timer callback function (which is called when the timer expires). Oh, and if the desired action was successful, don't forget to cancel the timer.
That means a lot of code, plus the necessary error handling and unit tests. And let's be honest: What software developer really wants to do that? I'm honestly way too lazy for that! But what could a minimally labor-intensive solution look like?
Planned delay
The solution is "Delayed Events." The necessary ingredients are:
- A delayed event that contains the event to be scheduled at a later time as a payload, along with the timeout time.
- A delayed event scheduler: It receives all delayed events and adds them to its internal queue in order of expiration time. A thread simply waits until the timeout of the next delayed event expires.
- The delayed event scheduler passes the payload event to the "normal" scheduler after the timeout period has expired.
- The delayed event scheduler gets a “cancel” function that removes corresponding timeout events from the queue.

We now have all the important components needed to model even complex, time-dependent processes.
Now some of you might be asking: “How on earth do you model it?” Well, that’s the topic of the next blog post, which deals with the modeling and generation of state machines.
outlook
But here's a (highly simplified) state machine for controlling a defibrillator MCU via a state machine running in the host MCU. The nice thing about this method is that the timeout handling is visualized along with the "good path."
The pattern is always the same: An event with a corresponding delay is "raised" along with the entry action, and it is canceled in the entry action. It doesn't matter whether the state transition occurs due to the Delayed event or another event. In this example, all timeout events lead from the root state to the DefiTimeoutOccured state. If necessary, individual timeouts could, of course, be responded to individually.

Do you need support with designing a software architecture or developing embedded software? Then please contact us. Our experienced MEDtech engineers will be happy to help you develop your medical device or clarify any outstanding questions.
