ecu-tests/docs/08_babylin_internals.md

3.4 KiB

BabyLIN Adapter Internals (SDK Python wrapper)

This document describes how the real hardware adapter binds to the BabyLIN SDK via the official Python wrapper BabyLIN_library.py and how frames move across the boundary.

Overview

  • Location: ecu_framework/lin/babylin.py
  • Uses the SDK's BabyLIN_library.py (place under vendor/ or on PYTHONPATH)
  • Discovers and opens a BabyLIN device using BLC_getBabyLinPorts and BLC_openPort
  • Optionally loads an SDF via BLC_loadSDF(handle, sdf_path, 1) and starts a schedule with BLC_sendCommand("start schedule N;")
  • Converts between Python LinFrame and the wrapper's BLC_FRAME structure for receive

Mermaid: SDK connect sequence

sequenceDiagram
  autonumber
  participant T as Tests/Fixture
  participant A as BabyLinInterface (SDK)
  participant BL as BabyLIN_library (BLC_*)

  T->>A: connect()
  A->>BL: BLC_getBabyLinPorts(100)
  BL-->>A: [port0, ...]
  A->>BL: BLC_openPort(port0)
  A->>BL: BLC_loadSDF(handle, sdf_path, 1)
  A->>BL: BLC_getChannelHandle(handle, channelIndex)
  A->>BL: start schedule N
  A-->>T: connected

Mermaid: Binding and call flow

sequenceDiagram
  autonumber
  participant T as Test
  participant L as LinInterface (BabyLin)
  participant D as BabyLIN_library (BLC_*)

  T->>L: connect()
  L->>D: BLC_getBabyLinPorts()
  L->>D: BLC_openPort(port)
  D-->>L: handle/ok

  T->>L: send(frame)
  L->>D: BLC_mon_set_xmit(channelHandle, frameId, data, slotTime=0)
  D-->>L: code (0=ok)

  T->>L: receive(timeout)
  L->>D: BLC_getNextFrameTimeout(channelHandle, timeout_ms)
  D-->>L: code, frame
  L->>L: convert BLC_FRAME to LinFrame
  L-->>T: LinFrame or None

  T->>L: disconnect()
  L->>D: BLC_closeAll()

Master request behavior

When performing a master request, the adapter tries the SDK method in this order:

  1. BLC_sendRawMasterRequest(channel, id, length) — preferred
  2. BLC_sendRawMasterRequest(channel, id, dataBytes) — fallback
  3. Send a header with zeros and wait on receive() — last resort

Mock behavior notes:

  • The provided mock (vendor/mock_babylin_wrapper.py) synthesizes a deterministic response for the length signature (e.g., data[i] = (id + i) & 0xFF).
  • For the bytes-only signature, the adapter sends zero-filled bytes of the requested length and validates by length.

Wrapper usage highlights

from BabyLIN_library import create_BabyLIN

bl = create_BabyLIN()
ports = bl.BLC_getBabyLinPorts(100)
h = bl.BLC_openPort(ports[0])
bl.BLC_loadSDF(h, "Example.sdf", 1)
ch = bl.BLC_getChannelHandle(h, 0)
bl.BLC_sendCommand(ch, "start schedule 0;")

# Transmit and receive
bl.BLC_mon_set_xmit(ch, 0x10, bytes([1,2,3,4]), 0)
frm = bl.BLC_getNextFrameTimeout(ch, 100)
print(frm.frameId, list(frm.frameData)[:frm.lenOfData])

bl.BLC_closeAll()

Notes and pitfalls

  • Architecture: Ensure Python (x86/x64) matches the platform library bundled with the SDK
  • Timeouts: SDKs typically want milliseconds; convert Python seconds accordingly
  • Error handling: On non-zero return codes, use BLC_getDetailedErrorString (if available) for human-readable messages
  • Threading: If you use background receive threads, protect buffers with locks
  • Performance: Avoid excessive allocations in tight loops; reuse frame structs when possible

Extending

  • Add bitrate/channel setup functions as exposed by the SDK
  • Implement schedule tables or diagnostics passthrough if provided by the SDK
  • Wrap more SDK errors into typed Python exceptions for clarity