From e3f6b3b1814d1468053bc9b91d67ff67617c43d2 Mon Sep 17 00:00:00 2001
From: Martin Teichmann <martin.teichmann@xfel.eu>
Date: Mon, 15 Apr 2024 08:57:03 +0000
Subject: [PATCH] write more documentation

---
 ebpfcat/ebpfcat.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/ebpfcat/ebpfcat.py b/ebpfcat/ebpfcat.py
index c3ddf2d..e7a52fb 100644
--- a/ebpfcat/ebpfcat.py
+++ b/ebpfcat/ebpfcat.py
@@ -37,6 +37,18 @@ from .bpf import (
 
 
 class PacketDesc:
+    """A single value in a process data
+
+    This describes some data in the process data coming from or sent to
+    a terminal. This is the low-level version of :class:`ProcessDesc`, which
+    can be used if the terminal's self-desciption is lacking.
+
+    :param sm: the sync manager, either :attr:`SyncManager.IN` or
+        :attr:`SyncManager.OUT`.
+    :param position: the byte position in the process data
+    :param size: either a :mod:`python:struct` definition of a data type,
+        or an integer denoting the bit within a byte to be adressed.
+    """
     def __init__(self, sm, position, size):
         self.sm = sm
         self.position = position
@@ -147,6 +159,27 @@ class PacketVar(MemoryDesc):
 
 
 class TerminalVar:
+    """a device variable to be linked to a process variable
+
+    Whithin a :class:`Device`, one can refer to process variables that should
+    later be linked to process variables of a terminal. Within the device, one
+    can access the process variable generically. Upon instantiation one would
+    then assign a :class:`ProcessDesc` (or :class:`PacketDesc`) to it to link
+    the variable to an actual terminal.
+
+    For example::
+
+        class MyDevice(Device):
+            the_output = TerminalVar()
+
+            def program(self):
+                self.the_output = 5  # write 5 to whatever variable linked
+
+        terminal = MyTerminal()
+        device = MyDevice()
+        device.the_output = terminal.output5  # link the_output to output5
+    """
+
     def __set__(self, instance, value):
         if isinstance(value, PacketVar):
             instance.__dict__[self.name] = value
@@ -172,6 +205,28 @@ class TerminalVar:
 
 
 class DeviceVar(ArrayGlobalVarDesc):
+    """A variable in a device for higher-level use
+
+    define a variable within a device which the device's user can
+    access. This is especially important for fast devices, this is the
+    way data is communicated to and from the EBPF program.
+
+    For non-fast devices, this acts like normal Python variables.
+
+    :param size: the size of a variable in :mod:`python:struct` letters
+    :param write: whether the variable will be written to by the user
+
+    For example::
+
+        class MyDevice(Device):
+            my_data = DeviceVar()
+
+            def program(self):
+                self.my_data = 7
+
+        device = MyDevice()
+        print(self.my_data)  # should print 7 once the program is running
+    """
     def __init__(self, size="I", write=False):
         super().__init__(FastSyncGroup.properties, size)
         self.write = write
@@ -287,6 +342,23 @@ class EBPFTerminal(Terminal):
 
 
 class EtherXDP(XDP):
+    """The EtherCat packet dispatcher
+
+    This class creates an EBPF program that receives EtherCAT packet
+    from the network and dispatches them to the sync group they belong
+    to, or passes them on to user space if they do not belong to them.
+
+    For each sync group, there are always two packets on the wire, one
+    that only reads value from the terminals, the other one also writes.
+    Usually only the read-write packet is handed over to the sync group's
+    program. If, however, that packet gets lost, the next read-only
+    packet is handed over.
+
+    User space is supposed to constantly feed in new packets, and the
+    then-superfluous packets are sent back to user space. This way user
+    space can constantly read data independent of the EBPF program. It
+    cannot write, however, as this would cause priority issues.
+    """
     license = "GPL"
     minimumPacketSize = 30
 
@@ -336,6 +408,7 @@ class SimpleEtherCat(EtherCat):
 
 
 class FastEtherCat(SimpleEtherCat):
+    """An EtherCAT driver class for fast and slow sync groups"""
     MAX_PROGS = 64
 
     def __init__(self, network):
-- 
GitLab