LIN aus Python und C verwenden
Anwendungen sprechen über einen lokalen Unix-Socket mit dem HAT – ohne eigenen I²C-Treiber.
Empfohlener Anwendungsweg
Normale Anwendungen greifen nicht direkt auf I²C zu.
Python / C / eigene Anwendung
|
| Unix SOCK_SEQPACKET
v
beiis-lind
|
| I²C
v
STM32
Dadurch besitzt nur ein Prozess den I²C-Endpunkt und mehrere Anwendungen müssen die Hardwaredetails nicht selbst kennen.
Daemon starten
Für Entwicklung:
source .venv/bin/activate
beiis-lind \
--bus 1 \
--address 0x42 \
--socket /tmp/beiis-lin.sock \
--lock-file /tmp/beiis-lind.lock
Verbindung prüfen:
beiis-lin --socket /tmp/beiis-lin.sock info
Auf Raspberry Pi Hardware verwendet der Daemon standardmäßig zusätzlich den isolierten GPIO6-Interrupt als Wakeup-Signal.
Python
Die einfachste Integration verwendet 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()
Erwartete Antwort:
00 00
Das erste Byte ist die Operation, das zweite der Status 0 = OK.
Python: LIN-Frame senden
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
Die Socket-Schnittstelle ist ein normaler Unix-Domain-SOCK_SEQPACKET-Socket.
int fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
Standardpfad:
/run/beiis/lin-hat.sock
Ein Request ist genau ein UTF-8-JSON-Paket.
Aktive Master-Query wählen:
{"v":1,"id":1,"type":"request","op":"set_active_instance","args":{"instance":0}}
Native PING senden:
{"v":1,"id":2,"type":"request","op":"data_send","args":{"channel":0,"data":"00"}}
Antwort von master_rx_query lesen:
{"v":1,"id":3,"type":"request","op":"data_recv","args":{"instance":1,"channel":0,"timeout":2.0}}
Ein vollständiges minimales C-Beispiel liegt unter:
examples/runtime/c_basic.c
Kompilieren:
cc -O2 -Wall -Wextra examples/runtime/c_basic.c -o /tmp/beiis-runtime-c
/tmp/beiis-runtime-c
Warum Socket statt direktem I²C?
Der Socket trennt die Anwendung von:
- I²C-Registerdetails,
- Zugriffssynchronisation,
- GPIO-IRQ-Behandlung,
- STM32-Runtime-Framing,
- Firmware-Recovery und mboot.
Damit kann dieselbe Architektur aus Python, C oder jeder anderen Sprache verwendet werden, die Unix-Sockets und JSON beherrscht.
Wichtig: nur ein I²C-Besitzer
Wenn beiis-lind läuft, sollte keine zweite Anwendung gleichzeitig mit --direct auf dieselbe I²C-Adresse zugreifen.
Für normale Anwendungen gilt deshalb:
Socket benutzen. Direkten I²C-Zugriff nur für Bring-up, Recovery und Low-Level-Debugging verwenden.