On the state machine below, let us suppose I am in "StateE". Then comes Sig1, so the transition is takes place. First I exit "StateE", then assume that the "Grd1" guard lets me throuh.
Now I enter "StateH", execute the entry action ("Act2"). Then I put a signal into the queue to execute the "do" action of the "StateH". This means that the "StateH" "do" action will be not necessary execute right after the enter action, but some other already scheduled signals may be served first.
Then I procees to "StateG". In "StateG" again, the entry action is executed ("Act2") and the "do" action is scheduled as a signal.
The signal dispatcher reaches the point in the signal queue where the StateH do action signal is.
The question is: Do we exit from StateG back to StateH before executing the do action of StateH or we can say: Being in StateG is also being in StateH, so no state transition is necessary, let us execute the StateH do action right away.
According to the UML Specification (formal-15-03-01, Sect. 14.2.3.4.3)
A State may also have an associated doActivity Behavior. This Behavior
commences execution when the State is entered (but only after the
State entry Behavior has completed) and executes concurrently with any
other Behaviors that may be associated with the State, until: • it
completes (in which case a completion event is generated) or • the
State is exited, in which case execution of the doActivity Behavior is
aborted.
This means that 1) doActivity is executed as soon as the state is entered (as opposed to your understanding) and 2) the doActivity keeps running while the State is active.
In your case, StateH is active while StateG is active (see definition of active state configuration), therefore, the doActivity of StateH keeps running while you are in StateG
In OMG Unified Modeling Language 2.5.1, this statement is a little stronger:
Also, if a doActivity Behavior is defined for the State, this Behavior
commences execution immediately after the entry Behavior is executed.
It executes concurrently with any subsequent Behaviors associated with
entering the State, such as the entry Behaviors of substates entered
as part of the same compound transition.
I do not believe this implies that the state machine must be multi-threaded. Suppose you had a multi-threaded state machine on a single core processor. The various behaviors and activities would still execute sequentially, event though they might be executed by separate threads.
Related
I have a state machine diagram for an application that has a UI and a thread that runs parallel. I model this using a state with 2 parallel regions. Now I want when that thread gives some message, for example an error, that the state of the UI changes, for example to an error screen state.
I was wondering what the correct method to do this is, as I was not able to find any example of this situation online.
The options that I thought of were creating a transition from every state to this error state when the error state is called, which in a big diagram would mean a lot of transitions. Or by just creating a transition from the thread to the error state (As shown in the image), which could possible be unclear.
Example of second option
You don't need a transition from every state. Just use a transition from the State State to the Error window state. It will then fire no matter what states are currently active.
Such a transition will also leave the Some process state. Since you didn't define initial states in the orthogonal regions, the right region of the state machine will then be in an undefined state. Some people allow this to happen, but for me it is not good practice. So, I suggest to add initial states to both regions. Then it is clear, which sub state will become active, when the State state is entered for any reason. The fork would also not be necessary then.
How you have done it in your example would also be Ok. However, since the Some process state is left by this transition, this region is now in an undefined state. Again, the solution to this is to have an initial state here. I would only use such a transition between regions, when it contains more than one state and the On error event shall not trigger a transition in all of the states.
If the Some process state is only there to allow for concurrent execution, there is an easier way to achieve this: The State state can have a do behavior, that is running while the sub states are active. Orthogonal regions should be used wisely, since they add a lot complexity.
I am not 100% sure what 'do' does in an UML statechart diagram.
Is my thinking correct:
If a transition happens, 'entry' will be executed first and then 'do' will be executed.
And if we are leaving the state only 'exit' will be executed.
Does this logic apply to reflexive transitions as well?
And what if a trigger happens, that does not set off a transition? Does this only execute 'do'?
The UML Specification tells us:
14.2.3.4.3 State entry, exit, and doActivity Behaviors
. . .
A State may also have an associated doActivity Behavior. This Behavior commences execution when the State is entered (but only after the State entry Behavior has completed) and executes concurrently with any other Behaviors that may be associated with the State, until:
it completes (in which case a completion event is generated) or
the State is exited, in which case execution of the doActivity Behavior is aborted.
The execution of a doActivity Behavior of a State is not affected by the firing of an internal transition of that State.
You :
Does this logic apply to reflexive transitions as well?
As said by the last sentence above that depends if the reflexive transition is internal or external.
To add to bruno's answer something more specific.
As stated in the UML specification (and quoted by bruno in his answer) the do activity is performed while the system is in a certain state (after entry activities were completed). It is performed during the whole time the system is in the state. The do activities cease to be performed only in two situations:
The transition taking you out of the State is triggered; in such case, the do activities are interrupted, exit activities if any, are performed and then the transition occurs. The transition can be reflexive (i.e. once completed the system returns to the same state), in which case first entry activities will be carried out and once they are completed, the do activities will start again.
The do activities finish on its own; in such case, once the do activities finish it's time to leave the state. So the eventual exit activities are performed and the transition is performed. A valid system should have one or more transitions without a triggering event (if more than one then they should have conditions allowing to uniquely determine which one will be used) that would be followed once the exit activities (or do if there was no exit) completes.
Let's have a more tangible example. Consider a washing machine. There are two interesting states in it, one is filling with water, the other one is drum rolling.
For the filling with water state, one can expect the following activities:
entry: open water valve
do: monitor water level
exit: close water valve
Now, once the washing machine gets into the state, the valve is being open (entry) and immediately afterwards the machine starts the do: to monitor the level of water (as water now flows in freely). Once the set water level for the current program and step is reached, the event "water level reached" is sent, initiating next transition. As a result the do activity is stopped (there is no more point in monitoring the water level) and the exit is carried out (valve is being closed), followed by the transition to the next state (e.g. heating or drum rolling depending on the program stage).
As you can clearly see, in such case the do activity is interrupted once the transition trigger is captured.
For the drum rolling the situation is quite different though. For the sake of simplicity we will have just one *do( activity, with no entry or exit activities:
do: rotate the drum for n seconds with n speed
When the washing machine enters this state, it immediately starts rolling the drum and (unless interrupted by some exceptional event) keeps doing it for the predefined amount of time. Once that time elapses, the do activity interrupts immediately and the transition to the next state happens. In such case, it is the do activity that controls when the next state transition occurs, at least in the typical scenario.
Following on the discussion at State machine program design in FreeRTOS - vTaskStartScheduler in a switch statement, I have a state machine with 4 states, each of them with different tasks reading sensor data.
When a sensor data reaches a threshold, its task has to cause a state change.
The idea is to have a superior task which controls the states (and suspends/resumes corresponding tasks) with a switch statement. My question is: how should the sensor tasks communicate the STATE with the superior task?
One proposed solution is to have a set_state function which is called by the event generating task, but I read that having global variables in FreeRTOS is discouraged. I thought to implement it through Queues:
1- Task1 detects sensor threshold, and sends STATE to a Queue.
2- Superior task is blocked waiting to receive data from Queue. When it receives STATE, the switch statement processes the state change.
If this approach is correct, my doubt relates on how and where should be STATE defined (global, or just existing in the stack of each task, or the superior task...)
STATE should exist only where it needs to, 'in' the superior task. I'm presuming you're using C, so declare STATE as a static variable in "superior_task.c" (or whatever it's called). This means it can then only be affected within that file - the C equivalent to a private member variable in C++.
Then, if your inferior tasks need to affect a state change, they post a state change event to a queue managed by the superior task. When the queue is processed, the superior state makes the change to the private STATE variable.
If other tasks need to know what the state is for their own processing, they can use an accessor for the private variable, e.g., State get_state() { return STATE; }. As Martin says though, the other tasks shouldn't need to know the state, as otherwise there's inter-dependencies between tasks that shouldn't exist.
How can the following be expressed in UML:
I have a class, whose behavior is modeled as a state machine. On entry
to a particular state in that state machine, I want to invoke an
operation (method) of the class instance.
I'm trying to figure out the formal way to capture the relationship described above. I know that entry behaviors of a state can be of different types (e.g., FunctionBehavior). Classes can have Operations which are essentially specifications for a function (like a function typedef). I'm confused as to how to specify a function as implementing a particular Operation, and then have it be invoked from potentially multiple state entry behaviors.
Citing Superstructure for 2.5 (chap. 14.2.3.4.3 p. 307):
State entry, exit, and doActivity Behaviors
A State may have an associated entry Behavior. This Behavior, if defined, is executed whenever the State is entered through an external Transition. In addition, a State may also have an associated exit Behavior, which, if defined, is executed whenever the State is exited.
A State may also have an associated doActivity Behavior. This Behavior commences execution when the State is entered (but only after the State entry Behavior has completed) and executes concurrently with any other Behaviors that may be associated with the State, until:
it completes (in which case a completion event is generated) or
the State is exited, in which case execution of the doActivity Behavior is aborted.
The execution of a doActivity Behavior of a State is not affected by the firing of an internal Transition of that State.
That means you can define an operation in the class which is executed when the state is entered. You show it this way:
Edit: Just copying Geert's comment below to make it water proof :-)
The UML specs are quite specific saying that the state has an associated Behavior. The Behavior might be the method of an operation but it doesn't have to be. Since Behavior itself is an abstract meta-class it can be any of Activity, OpaqueBehavior, FunctionBehavior, Interaction, StateMachine or ProtocolStateMachine
As a newbie am trying to develop a state machine using Visio for a cd writer. below are the device operations/transactions and attached, is a diagram of what I've done so far, am unsure if its accurately represented.
Device operation
Load button- causes the drawer to open and to shut if open(load an empty cdr)
Burn button- starts recording document on the cdr, green light comes on in the burning process
and goes off when completed. Once cdr is burned writer stops.
Verify button- verifies the document previously recorded on the cdr, green light comes on in the
process and goes off when completed, then device stops
Cancel button- stops process anytime during recording or verifying
Cancel button- no effect if cd writer is empty or not busy verifying or recording When powered up- CD Writer will ensure the drawer is closed
Burn button – has no effect when cd writer is empty and during recording or verifying process.
Verifying can only be started when the CD Writer is not busy recording.
Visually your diagram looks like a state machine and states have good-sounding names - it's a good start. :)
The first issue I see there is the transition specification. It is definitelly not correct. State transitions in UML are specify in the folowing format:
event [guard] /action
where:
event (or trigger) is an external on internal "signal" that starts the transition. It can be a button activated by a user, an elapsed timer, a detected error, etc. It can even be omitted.
guard is a logical condition that should be fulfilled in order to start the transition. It is usually an expression returning a boolean value of tru or false. It can also be omitted.
action is a kind of side-effect, something that is executed when the transition is triggered. Ic can also be omitted.
Getting back to your diagram I would say that...
most of the labels on your transitions should not carrry "/" as it indicates an action. There are mostly manual triggers, like "load" (pressing the button to open the drawer), "Cancel", "butn", etc.
Consider some events that are triggered internally, like "burning done", or "CD loaded"
You can add some guard conditions in the situations where possible
I would remove all the triggers with no effect (like cancel with no CD in). It makes the diagram simplier with no loss of information
States LOADED and IDLE in your case are kind of strange, weak. It is not clear what makes them different (see the example below)
Here is a diagram that I find a bit more acurate (see notes for additional comments):
You need to specify explicit events as triggers of the transitions.
In the current state machine, each transition (except the one leaving the initial vertex) has an effect, but not a trigger. More accurately, they are triggered by the default completion event, and are therefore automatic.
Moreover, since all transitions react to the same event, your state machine is non-deterministic. For instance, in the state loaded, the transitions to Recording, empty, and loaded all react to the completion event. When the completion event is dispatched, these transitions are said to be conflicting, and one of them is selected non-deterministically. I am sure this is no what you want.
Read the UML Specification, and define triggers for your transitions.
You don't need to depict the transitions from "empty" to "empty" as transitions without any actions or state transitions would not need to be drawn in the Statemachine diagrams. (State Transition tables are often used for the checks of any missing transitions for such cases.)
"loaded" and "Idle" can be represented in one as a same state
To represent the "green light", I would write "turn on the green light" as entry action in Recording and "turn off the green light" as exit
Here's the diagram I drew. The status of tray (whether its opened or closed) should be considered in the actual model, but its not on my sample diagram below.