When setting up the Test Harness, most Transform input port Signals can be configured to have a particular Initial Value. The Transform author must ensure the Transform is put in the correct initial state paying particular attention to these Initial Values.
For a D to A Transform or Relay Card Transform, for example, when the Test Harness is loaded (and no later), the Initial Values of the Signals on the ports should be written to the output pins of the D to A.
•This only applies to input ports.
•This information is available on the SignalInfo for the port. In most cases, the initial values should be passed to the hardware when the hardware is initialized or communication begins.
•The Transform author must decide whether the initial values need to be sent down to the hardware on a module reset during the Reset() function. Note, on Scenario start, the default is to call Reset prior to Arming the Transform. However, Transform authors should be aware that the user has the capability to disable this feature via the project settings so that the Harness is not reset between Scenarios. This default may change in future releases.
Device & I/O Enumeration
Use the available device APIs to list the available devices and create a drop-down property (using a custom Type Converter) to allow the user to select the device.
Selecting this device should set several configuration properties of the transforms so that it can uniquely identify the device on subsequent reloads and set-ups.
When the user selects the device, enumerate that device's I/O (using tables in code if necessary). Create a new list of ports according to the device's I/O and make them 'live' by calling the ReplacePorts method of BaseTransform.
The same "ResyncPorts" method should be invoked during setup to ensure the transform is consistent with the hardware.
During setup it may be possible to find the required device with more than one method; fall-back methods may be used if the primary method fails but this should issue a Warning to the transforms' integrity failures collection (myTransformFailures).
For example, Serial Number might be the primary method, but Device Name or ComPort could be a secondary location/identification method.
Provide properties for the user to enter the configuration manually without enumeration of the devices or I/O.
It needs to be possible to configure the transform without having the hardware plugged into the PC.
Also, do not assume you will have a valid device handle (an execution field!) for configuration properties - the device might not be in the PC and the configuration properties must still function 100% correctly without it (otherwise loading and saving the transform file without the hardware will break it).
Connector transforms should time-stamp their transitions based on the timing clock of their hardware. If the device supplies a time-stamp - use it!
The Start method is used to synchronize time so you may need to keep the simulation start time offset to add into your transition time (the simulation start time is NOT always 0).
If the model is paused and unpaused, the transform should account for this 'lost time' and subtract it out of the hardware time-stamps.
It is a transform-particular decision as to what to do with incoming data while the model is paused, but generally they should be dropped and ignored - pretend that slice of time never happened.
Most connector transforms should supply a scheduler to ensure they are ticked at an appropriate regular interval.
There are two scheduler implementations provided, PeriodicScheduler and AperiodicScheduler. The periodic scheduler should be used for steadily repeating events and the aperiodic scheduler should be used for sporadic events.
In all cases, the aperiodic scheduler must absolutely predict when the next event will happen when the previous event expires. If the actual time of some future event is not precisely known, you must fall-back to a polling strategy using a periodic scheduler.
Connector transforms should implement a Clock source based on their response stream of data. For example, set the clock time to the last received piece of data. This clock is used to throttle the MxVDev execution engine.
Whenever feasible, a signal-processing transform should preserve the simulation time-stamp of the incoming transitions. For example, an Add transform should not re-stamp new transitions it makes, they should be stamped with the time of the transition that is causing an update.
There is a Transition constructor that takes an existing ITransition and a new IDataType as parameters to implement this signal-processing transition behavior.
(Under a number of conditions, transitions can "pile-up" on the inports of the signal-processing transform and we do not want all of the them coming out with the same time-stamp.)
There are, however, certain signal-processing transforms that should re-time-stamp the transitions - in particular if the transform is waiting for some event to occur before processing or sending the transitions it should be time-stamped with time of that event not the original data.
For example, the Debounce transform sets the outgoing time-stamp to when the debounce timer expires (when the signal goes stable). If the debounce time is 50ms and a transition is received at 1.037s (an no further transitions are received) the outgoing time-stamp should be 1.087s even if the simulation tick-time is, say, 1.090s when this determination is made.
A signal processing transforms ought to provide a scheduler if it needs to make decisions based on time. For example, the CAN .dbc transform provides a scheduler so it can generate periodic CAN messages. The debounce transform provides a scheduler so it can assert a stable signal after some amount of time has passed. The sine-wave transform, however, does not provide a scheduler; it will calculate the position of the sine-wave at any and all times it is ticked.
Signal processing transforms should generally not provide a clock source.
Always consider adding a Signal to your Transform showing the internal operating state of the Transform. For example, if a Transform has states Armed, Connected, and Disconnected, add this state variable as an output port. If, for example, a disconnection occurs, the user can see that this happened in the TestCase.
Consider the situation where, when running a Scenario, an API call is made in a Transform and an unexpected / incorrect condition is detected by the Transform code. We will call this a Run-Time Error. It is NOT sufficient to post a notification to the Notification Window and maybe attempt to recover.
The risk is that the Scenario/Test runs to completion and passes. In the situation where any error condition is detected at run time, the Signal must be added to the running TestCase(s) and any message that details the condition must be attached to this event.
When implemented properly:
•The TestCase and Scenario fail.
•The issue is captured in Scenario/regression logs for later analysis.
•The user can see the cause description of the issue.