Using LIN from Python and C
Applications communicate with the HAT through a local Unix socket – no custom I²C driver required.
Recommended application interface
Normal applications do not access I²C directly.
Python / C / custom application
|
| Unix SOCK_SEQPACKET
v
beiis-lind
|
| I²C
v
STM32
This ensures that only one process owns the I²C endpoint. Multiple applications do not need to know the hardware details.
Starting the daemon
For development:
source .venv/bin/activate
beiis-lind \
--bus 1 \
--address 0x42 \
--socket /tmp/beiis-lin.sock \
--lock-file /tmp/beiis-lind.lock
Check connectivity:
beiis-lin --socket /tmp/beiis-lin.sock info
On Raspberry Pi hardware, the daemon normally also uses the isolated GPIO6 interrupt as its wake-up signal.
Python
The simplest integration uses DaemonClient:
from beiis_lin.client import DaemonClient
c = DaemonClient("/run/beiis/lin-hat.sock")
c.set_active_instance(0) # master_tx_query
c.data_send(0, b"\x00") # Native PING
instance, channel, reply = c.data_recv(
instance=1, # master_rx_query
channel=0,
timeout=2.0,
)
print(reply.hex(" "))
c.close()
Expected response:
00 00
The first byte identifies the operation; the second is status 0 = OK.
Python: Send a LIN frame
from beiis_lin.client import DaemonClient
c = DaemonClient()
c.set_active_instance(0)
request = bytes.fromhex(
"02 12 01 04 11 22 33 44"
)
c.data_send(0, request)
_, _, reply = c.data_recv(
instance=1,
channel=0,
timeout=2.0,
)
assert reply == bytes.fromhex("02 00")
c.close()
C
The socket interface is a standard Unix-domain SOCK_SEQPACKET socket.
int fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
Default path:
/run/beiis/lin-hat.sock
Each request is one UTF-8 JSON packet.
Select the active master query:
{"v":1,"id":1,"type":"request","op":"set_active_instance","args":{"instance":0}}
Send a native PING:
{"v":1,"id":2,"type":"request","op":"data_send","args":{"channel":0,"data":"00"}}
Read a reply from master_rx_query:
{"v":1,"id":3,"type":"request","op":"data_recv","args":{"instance":1,"channel":0,"timeout":2.0}}
A complete minimal C example is included at:
examples/runtime/c_basic.c
Compile and run:
cc -O2 -Wall -Wextra examples/runtime/c_basic.c -o /tmp/beiis-runtime-c
/tmp/beiis-runtime-c
Why a socket instead of direct I²C access?
The socket abstracts away:
- I²C register details.
- Access synchronization.
- GPIO interrupt handling.
- STM32 runtime framing.
- Firmware recovery and mboot.
The same architecture is therefore accessible from Python, C or any other language supporting Unix sockets and JSON.
Important: One I²C owner
When beiis-lind is running, no second application should access the same I²C address concurrently using --direct.
For regular applications:
Use the socket. Reserve direct I²C access for bring-up, recovery and low-level debugging.