Skip to content

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]

Example: building a test suite on this API