Previous: , Up: Possible Events Multiplexing Sensor Inputs   [Contents]


2.5.2 The Multiplexer Component

First let’s specify requirements for a multiplexer regardless of how many sensors it controls:

  1. A multiplexer can control any number of sensors, including zero.
  2. A multiplexer’s default state is Off.
  3. Turning on a multiplexer turns on all of its sensors, unless the multiplexer’s state is already Sensing or Triggered, in which case turning on is illegal (should never occur).
  4. Turning off a multiplexer turns off all of its sensors, unless the multiplexer’s state is already Off, in which case turning off is illegal.
  5. A trigger event from any of a multiplexer’s sensors sets the multiplexer’s state to Triggered and sends a triggered event to the multiplexer’s caller.
  6. If a multiplexer has triggered, it will not trigger again until its sensors have been turned off and turned back on.

The below component with zero sensors establishes the framework for multiplexing. Its behaviour is just a replica of the interface behaviour minus the optional trigger; hence, you can copy the interface’s whole behaviour block, remove the optional sub-block, reset State references to the local declaration of State, reset event (function) names to iSensor.<name>, and add parentheses to event (function) names. The Triggered state will remain dead code until the multiplexer is hooked up to at least one sensor that can be triggered (note that Dezyne verification does NOT notify you about dead code).

component SensorMultiplexer {
  provides ISensor iSensor;

  behaviour {
    enum State { Off, Sensing, Triggered };
    State state = State.Off;
    [state.Off] {
      on iSensor.turnOn(): state = State.Sensing;
      on iSensor.turnOff(): illegal; // tests caller's logic in model
    }
    [state.Sensing] {
      on iSensor.turnOn(): illegal;
      on iSensor.turnOff(): state = State.Off;
    }
    [state.Triggered] {
      on iSensor.turnOn(): illegal;
      on iSensor.turnOff(): state = State.Off;
    }
  }
}

In the below code sample we have added one sensor and highlighted all added source code.

Exercise: Will this component verify? Make a decision, then verify in Dezyne. The answer is below the code sample.

component SensorMultiplexer {
  provides ISensor iSensor;
  requires ISensor iSensor1;

  behaviour {
    enum State { Off, Sensing, Triggered };
    State state = State.Off;
    [state.Off] {
      on iSensor.turnOn(): {
        iSensor1.turnOn();
        state = State.Sensing;
      }
      on iSensor.turnOff(): illegal;
    }
    [state.Sensing] {
      on iSensor.turnOn(): illegal;
      on iSensor.turnOff(): {
        iSensor1.turnOff();
        state = State.Off;
      }
      on iSensor1.triggered(): {
        iSensor.triggered();
        iSensor1.turnOff();
        state = State.Triggered;
      }
    }
    [state.Triggered] {
      on iSensor.turnOn(): illegal;
      on iSensor.turnOff(): state = State.Off;
      on iSensor1.triggered(): illegal;
    }
  }
}

The above component does verify, in fact. One state-event case is not handled explicitly, “on iSensor1.triggered():” in [state.Off], but this is an allowed implicit illegal declared in the interface.

The below screen shot shows the simulated SensorMultiplexer’s Trace, Sequence and State Chart views. Notice that its State Chart is exactly the same as a plain sensor. Aggregated sensor behaviour and single sensor behaviour are identical from the caller’s point of view, provided that it doesn’t matter what kind of alarm happened – motion, vibration, magnetic effect, or other.

images/eclipse_3.75

In the below code we have added a second multiplexed sensor, with new code highlighted. But this code has a logic error. Exercise: Can you spot it? If you’re impatient, just verify in Dezyne to get a hint. The multiplexing logic is highly regular and really quite simple, yet you still might find the error hard to spot (you would not be alone by any means). Hint: count the instances of “1” versus instances of “2”. The answer is below the code sample.

component SensorMultiplexer {
  provides ISensor iSensor;
  requires ISensor iSensor1;
  requires ISensor iSensor2;

  behaviour {
    enum State { Off, Sensing, Triggered };
    State state = State.Off;
    [state.Off] {
      on iSensor.turnOn(): {
        iSensor1.turnOn(); iSensor2.turnOn();
        state = State.Sensing;
      }
      on iSensor.turnOff(): illegal;
      on iSensor1.triggered(), iSensor2.triggered(): illegal;
    }
    [state.Sensing] {
      on iSensor.turnOn(): illegal;
      on iSensor.turnOff(): {
        iSensor1.turnOff();
        state = State.Off;
      }
      on iSensor1.triggered(), iSensor2.triggered(): {
        iSensor.triggered();
        iSensor1.turnOff(); iSensor2.turnOff();
        state = State.Triggered;
      }
    }
    [state.Triggered] {
      on iSensor.turnOn(): illegal;
      on iSensor.turnOff(): state = State.Off;
      on iSensor1.triggered(), iSensor2.triggered(): illegal;
    }
  }
}

The defect is in [state.Sensing], on turnOff(), which turns off the first sensor but not the second.

Exercise: Repair the defect, verify and simulate, then optionally generate the C++ source and examine it.

Having gone through most Dezyne basics, we’re ready now to design, build, verify and simulate a somewhat less simple Burglar Alarm system.


Previous: , Up: Possible Events Multiplexing Sensor Inputs   [Contents]