Comprehensive Project
Integrate a model and an observer with the same contract
This project combines the lesson 06 door/window model with a controlled sender and an independent observer. It is a repeatable teaching experiment, not a production ECU or a report of tests performed by this site.
The lesson 07 test module checks a different contract: an AA heartbeat on 0x200. Do not paste it unchanged into this project. Here, 0x200 is a lock command and 0x300 is status. Run the heartbeat exercise in a separate configuration, or adapt its bounded-wait and data-validation pattern to this contract.
Keep three responsibilities separate
| Participant | Sends | Observes | Responsibility |
|---|---|---|---|
| Controlled sender | 0x200, 0x201, 0x202 | Its input schedule | Send only the selected case |
| Lesson 06 model | 0x300 every nominal 500 ms | Commands on CAN1 | Own lock, position and movement state |
| Observer/test module | Nothing unless explicitly acting as the sender | Received 0x300 plus trace of commands | Validate new observations against expected state |
Use classical CAN, standard IDs and a single CAN1 mapping. Disable other senders of these IDs, check database conflicts and start each independent case from a fresh measurement. A CAPL test module requires the appropriate Test Feature Set and licensing; an ordinary simulation node is not a substitute for that execution context.
Variables belong to their own CAPL programs. A faultStatus declared in a test module does not read a simulation node's variable of the same name. Communicate through a defined message or configured system variable with explicit ownership. This project uses the status message already specified by lesson 06.
Freeze the protocol before connecting components
| ID | Payload | Model rule |
|---|---|---|
| 0x200 | Ignored; DLC 0 is enough for this exercise | Lock if stationary |
| 0x201 | Ignored; DLC 0 is enough for this exercise | Unlock if stationary |
| 0x202 | Exactly 1 byte: 01 down, 02 up | Reject when locked, moving or invalid; an endpoint request is a no-op |
| 0x300 | Exactly 3 bytes: lock, position, movement | Lock 0/1; position 0–100; movement 0 stationary, 1 up, 2 down |
At start: unlocked, position 0 (fully up), stationary. A full movement needs 20 increments of 5 at nominal 20 ms intervals: 400 ms, not two seconds. State reporting every 500 ms can miss the entire moving phase. A first status showing the endpoint does not prove that movement was instantaneous.
Execute the baseline before automating verdicts
- Compile the unchanged lesson 06 source in the installed CANoe version. Preserve compiler diagnostics; this site has not run that compiler on the example.
- Start measurement without commands and inspect received CAN1 0x300 data frames with DLC 3 and payload 00 00 00.
- Send one 0x202 data frame with DLC 1 and payload 01. Capture its arrival at the model and the following status frames.
- Inspect the model's internal event sequence separately from the periodic status. Expect an endpoint of 100 (hex 64) with stationary movement, but measure actual event times before claiming a duration.
- Repeat a negative case with the model disabled. The observer must time out rather than reuse the last status byte.
Do not infer a status response merely from an Interactive Generator row being configured. Verify that transmission occurred and the target node received the intended channel and frame kind.
Adapt the test pattern without creating stale-data passes
The 0x300 protocol has no transaction identifier. A newly received cyclic status can describe an old state; freshness alone does not prove that a particular command caused it. Use a known baseline, isolate other command sources and describe the result as an observed state transition, not an acknowledged transaction.
For an automated observer, follow this algorithm before writing CAPL:
Establish and record a valid baseline in a fresh measurement.
Start one fixed overall deadline for the case.
Send the selected command and record its trace time.
Wait for a NEW 0x300 event using only the remaining deadline.
Handle timeout, interruption and other wait errors separately.
Retrieve the triggering frame; stop on a retrieval error.
Validate channel, direction, standard data-frame context and DLC == 3.
Check ranges: lock 0..1, position 0..100, movement 0..2.
Compare the observed state with the case expectation.
Keep waiting only if the case permits intermediate states and time remains.
Report actual evidence or a bounded failure; never read a cached global as proof.
This is pseudocode, not a CAPL source file. The wait success code is 1, while TestGetWaitEventMsgData succeeds with 0; lesson 07 explains both. Repeatedly waiting a fresh full timeout silently extends the case deadline. Choose and document the total budget before execution, allowing for the 500 ms reporting phase and measured scheduling tolerance.
A finite acceptance matrix
These are expected checks to execute. No row below asserts PASSED.
| Case | Preparation and input | Expected observation | Additional evidence |
|---|---|---|---|
| Initial state | Restart, no commands | 00 00 00 status | Confirm no conflicting sender |
| Lock | Fresh stationary model; 0x200 | Lock byte changes 0 to 1 | Record baseline and command |
| Locked window | Establish lock, then 0x202 / 01 | Position stays 0 | Model rejection log; status alone does not identify rejection reason |
| Full down | Fresh unlocked model; 0x202 / 01 | Final position 100, stationary | Internal 20-step sequence and measured time |
| Endpoint request | At 100, request down again | Position stays 100 | No new movement timer starts |
| Invalid payload | Fresh model; DLC 0, DLC 2, or byte 03 on 0x202 | State unchanged | Rejection branch, no out-of-range read |
| Command during motion | Inject lock well inside a controlled movement | Lock stays 0; motion continues | Internal event order; 500 ms status may miss this interval |
| Missing model | Disable model; drain already-submitted traffic | Bounded timeout | No pass from a previous observation |
| Restart | Stop while moving, restart | Initial state restored | Pending old state is not reused |
Passing these rows would support only this teaching contract in the recorded configuration. It would not establish anti-pinch safety, diagnostics behavior, physical actuator timing or production ECU equivalence.
Record results, then investigate deviations
Use one record per case: source revision; tool version and license context; channel mapping; active nodes; initial state; commanded frame and time; received frames; expected result; actual result; evidence file; unresolved differences. Leave actual results empty until execution. Avoid synthetic reports with dates and PASSED labels that look like measurements.
Export only one status stream for the interval analyzer, using the stream-filtering procedure. Period statistics answer how that stream arrived; they cannot validate the lock or window state machine. For fault extensions, define a deterministic trigger and an observable failure state before considering randomized inputs.
The protocol is defined by lesson 06. This integration plan, stale-data counterexample and acceptance matrix are this site's independent analysis; they do not claim CANoe execution evidence.