103 lines
3.4 KiB
Markdown
103 lines
3.4 KiB
Markdown
# 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
|
|
|
|
```mermaid
|
|
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
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
autonumber
|
|
participant T as Test
|
|
participant L as LinInterface (BabyLin)
|
|
participant D as BabyLIN_library (BLC_*)
|
|
|
|
T->>L: connect()
|
|
L->>D: BLC_getBabyLinPorts(); 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 → 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
|
|
|
|
```python
|
|
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
|