ecu-tests/docs/08_babylin_internals.md
Hosam-Eldin Mostafa 582764d410 Mark legacy BabyLIN adapter as deprecated across code and docs
The MUM (Melexis Universal Master) adapter is the current default; the
BabyLIN SDK adapter is retained only for backward compatibility with
existing rigs.

Code:
- Emit DeprecationWarning when BabyLinInterface is instantiated and
  when tests/conftest.py routes interface.type=='babylin' to it.
- Update module/class docstrings in ecu_framework/{__init__,config,
  lin/__init__,lin/babylin}.py to label BabyLIN-specific fields and
  paths as deprecated.

Config / scripts / pytest:
- pytest.ini: relabel the babylin marker as deprecated.
- config/{babylin.example,examples,test_config}.yaml: add deprecation
  banners and field comments.
- scripts/99-babylin.rules and scripts/pi_install.sh: annotate the
  udev-rule install block as legacy-only.

Documentation:
- TESTING_FRAMEWORK_GUIDE.md, docs/08_babylin_internals.md, and
  vendor/README.md: prepend explicit "DEPRECATED" banners.
- docs/{README,01,02,04,05,07,09,10,12,13,14,15,18,DEVELOPER_COMMIT_
  GUIDE}.md: relabel "legacy" to "deprecated" where babylin is
  mentioned, present MUM as the primary path, and steer new work
  toward the MUM examples.

No tests, configs, or modules were deleted; existing BabyLIN setups
keep working but now produce a clear DeprecationWarning at runtime.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:32:24 +02:00

3.8 KiB

BabyLIN Adapter Internals (SDK Python wrapper)

Status: DEPRECATED. The BabyLIN adapter is retained for backward compatibility only. New tests and deployments should target the MUM (Melexis Universal Master) adapter — see 16_mum_internals.md. This document is kept so existing BabyLIN setups can still be maintained.

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