Host PC Interaction via Python API¶
This is what „just write tests in C, C++ or Python" means in practice: an ordinary Python library, no proprietary scripting language, no dedicated IDE.
The Python API talks to your C code running on CPU2. It does not drive the hardware directly — it starts test sequences, sets variables inside your C program, and reads back results and logs. The real-time work happens on the board; Python orchestrates it.
The LoopCheck class provides the high-level interface for test automation.
loopcheck = LoopCheck(ip="192.168.0.4", port=28000)
loopcheck.start(log_file="test_run.log")
# SPI peripheral will reply '500' on SDO on next request:
loopcheck.set_signal("Output Mocked DAC", 500)
# Do not acknowledge next I²C request from DUT
loopcheck.set_signal("I2C", NO_ACK)
# Stimulate DUT inputs:
timestamp_button = loopcheck.set_signal("Emergency Stop Button", 1)
# Verify DUT response with timing
timestamp_motor, value = loopcheck.get_gpio("Motor Trigger",
after_timestamp=timestamp_button)
assert value == 0
assert timestamp_motor - timestamp_button < 100
loopcheck.stop()
What the API handles¶
- UDP socket management and command serialization
- Background thread for continuous log reception
- Signal-name-to-hardware mapping (abstracting pin numbers)
- Blocking queries with configurable timeouts for response verification
- Parse logs for timing and value verifications
Signal names instead of pin numbers
Tests refer to signals by name ("Emergency Stop Button", "Motor Trigger"). The mapping to
concrete hardware pins lives in the API's configuration table, so retargeting to a new DUT
does not require touching the test scenarios.
Division of labour¶
Knowing which side to put a piece of behavior on is the main design decision when building a test suite on LoopCheck:
| Put it in C on CPU2 when… | Put it in Python on the host when… |
|---|---|
| Timing must be deterministic (µs-level) | Timing of triggers are in the millisecond range or looser |
| The sequence must run without host involvement | You are parameterizing, sequencing or reporting |
| You are modelling DUT environment behavior | You are asserting on results after the fact |
| A reaction must follow a DUT output immediately | You are reading logs and generating output |
A typical scenario sets up parameters from Python, triggers a sequence that executes in real time on CPU2, and then asserts against the timestamped log once the sequence completes.
Command format¶
Commands are sent as UDP data packets to the CM core, which routes them to the C code on CPU2:
| Field | Size | Description |
|---|---|---|
| Command ID | 4 bytes | e.g. SET_GPIO, GET_GPIO, SET_SIGNAL, SET_PERIPHERAL, GET_PERIPHERAL |
| Parameter 1 | 4 bytes | Target identifier (signal index, GPIO number, register) |
| Parameter 2 | 4 bytes | Value or sub-command |
Log format¶
Log responses are streamed by the board with timestamps:
[tick_count] [ID] [PARAM1] [PARAM2]