2021-10-08
2. 1.2 Notes on Concurrent synchSMs
2.2. 1.2.2 Section 5.2
Figure 5.2.2
-
Task DetectMotion's (sole) purpose is to properly update the global variable
mtn
. Why is there an intermediate stateDM1
after inputA0
goes high before globalmtn
is updated? -
Translate task IllumiateLamp into words. Be sure to include description that differentiates states
IL1
fromIL2
.
A common mistake is to draw directed lines in a block diagram with the intention of describing flow of control, which makes no sense because all items in a block diagram execute concurrently.
-
the IlluminateLamp task could miss a 200 ms pulse on
mtn
, …
A common error is to not ensure that tasks communicate robustly, leading to a system that may sometimes work, but sometimes fails depending on the variations that can occur with "simultaneous" ticks.
What does "robustly" mean? How would you design the system to communicate robustly? (not have behavior that depends on the order that the tasks execute within a tick)
2.3. 1.2.3 Section 5.3
Recall the earlier requirement that a synchSM’s state actions should never include statements that wait, … if any of the tasks included a wait, the other tasks might not get a chance to execute before 1000 ms passes.
What happens if there is, in fact, a wait, and not all tasks get a chance to run before the next 1000{ms} interval?
(What is the sequence of code execution from time 0 to after the second TimerISR()
fires?)
Other task types: Converting a section of sequential code to a synchSM:
a single true-condition transition pointing back to itself
-
This is a confusing phrase that shows up several times. -> figure out a better description of the concept.
Participation Activity 5.3.1
Q3) The order in which the tick functions are called in C will not affect the system’s output.
-> False! It does affect the precise timing between actions in different tasks. This is because we still have only one CPU, it just appears that different tasks are running at the same time.
Q5) If an SM (no period) should execute along with the two synchSMs, the SM should be converted to a synchSM with a 1 ms period before converting to C.
This brings up the idea of "instantaneous". For a user’s perspective, the time between pushing a button and having an LED turn on need not be actually instantaneous. (In fact, it can’t be any faster than you can execute two instructions: read, then output). A useful number to know is what delay feels like instantaneous for a typical human.
You should have noticed that for your NAND gate that the gate delays were all over the place. Part of this is exactly when the input changed versus when the input was sampled by your code. It is possible to miss an input pulse if your sampling interval is longer than the pulse!
-
latency
-
reaction time
Q6) A synchSM with just one state, having just one transition with condition true and pointing back to that state, can have a tick function just having the state’s actions (and no switch statements).
This is another instance of the confusing phrase. -> a one-state state machine seems pointless. But when you are forced to describe everything in terms of state machines, then this is what you get.
2.4. 1.2.4 Section 5.4
A variable’s scope.
This is a C/C++
and general software thing.
When does this variable exist and when is it available to be read/written?
Keyword prefixes in C
:
-
static
-
volatile
Problem: your task needs to "remember" its current state in order to determine the correct next state.
Solutions:
-
Global variable named
BL_State
:enum BL_States { BL_SMStart, BL_LedOff, BL_LedOn } BL_State;
-
This is what RIBS and the zyBook do.
-
Ever heard that global variables are bad?
-
-
Use a local variable inside
void TickFct_BlinkLed()
switch statements:-
Create the enum using a typedef.
-
Declare
BL_State
variable inside the function -
AND use the
static
keyword. -
The prefix
static
tells the compiler to remember this variable across subsequent function calls. Like a global variable but only available to this function!
-
typedef enum {
BL_SMStart,
BL_LedOff,
BL_LedOn
} BL_State_t;
void TickFct_BlinkLed() {
static BL_State_t BL_State = BL_SMStart; // SMStart is the initial value
// Transitions
switch (BL_STATE) {
case BL_SMStart:
...
}
// Actions
switch (BL_State) {
...
}
}