Time Events in State Machines

In almost every embedded application, time-controlled activities are required. Examples of this are activities that are to run in a fixed cycle, or activities that are to be triggered in the event of a timeout, or also to implement certain signal patterns.

In UML state machines, a time event specifies an instance in time that triggers a transition to be taken when the specified time has elapsed. E.g. move from a state S1 to a state S2 after 1 second.

Time events might be relative and be used in the context of a trigger and the starting point is the time at which the trigger becomes active. A relative time trigger is specified with the keyword after followed by an expression that evaluates to a time value, such as “after (5 seconds).”

Alternatively an absolute time trigger is specified with the keyword at followed by an expression that evaluates to a time value, such as “Oct. 1, 2023, 12:00:00.”

UML specification of after / at time events

While this looks very clear at first sight, it is not sufficient for code generation.

The first major problem is that there is no standard way to specify a timer ID or timer name for the timeout event. However, this is required in practice to associate the timeout with an underlying timer service. In embedded systems, it is not practical to create a new timer from scratch every time an “after” or “at” trigger is encountered. Quite the opposite - you just want to create a timer and reuse it in multiple places in a diagram. Of course, you could specify a name or ID in a linked UML comment or similar, but that's not really a nice solution.

The other big problem is that not all UML tools allow the specification of time events.

Finally, the code generator should not introduce any restrictions or constraints on the system's time services. However, a meaningful use of time events would require the code generator to specify how the time services are to be implemented. And that would certainly not always meet your needs and would only force unnecessary restrictions.

So what is the proposed solution for implementing time events with the Sinelabore//RT// code generator?

Two aspects must be considered when using timed transitions.

All different ways of realizing timers in embedded systems must be possible, and no restrictions should be introduced by using the code generator.

All relevant information should be contained in the state diagram itself

The recommended way is not to use the time event specification of the UML tools, but to use regular signal events. Timers can be “manually”, created started or stopped in any action code. If static system initialization is required, timers can also be created at system startup. The underlying timer service of your choice (see below) simply sends the provided timeout events to the state machine input queue. To indicate in the diagram that an event is a timer, it is recommended to use a naming convention and start the name of the timeout event with, for example, evTout.

In the following figure a state machine uses two independent timers. One creates looping between S11 and S12 and is created as cyclic timer. The other second timeout stops this looping after some time (one shot timer) and stops timer1 at the transition to S2.

state machine diagram with cyclic and single-shot timer use

RTOS based Designs

Each RTOS offers the possibility to define software timers. If a timeout occurs, a user-defined timeout function is called. In this function, the timeout event is then placed in the state machine event queue. Examples can be found here, here or here for various real-time operating systems.

Mainloop Designs

In mainloop/foreground background designs, you need to provide some sort of timer service. Often there is a hardware timer that supplies the system tick. Within the system tick, a software timer service can be implemented. This software timer service checks each tick to see if a timeout has occurred, and then places the corresponding timeout event in the state machine's event queue. An example of such a system is available here. And an example of a simple timer service that can be invoked by a timer irq can be found at github.

Conclusions

The use of timed transitions can be realized with signal events in a very flexible way for any kind of system architecture. All relevant information is available and represented in the state diagram so that 100% of the state machine code can be generated without requiring hidden specifications and introducing constraints on the design of your system.