Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • teichman/ebpfcat
1 result
Show changes
Commits on Source (3)
version: 2 version: 2
build:
os: ubuntu-22.04
tools:
python: "3.12"
sphinx: sphinx:
configuration: conf.py configuration: conf.py
...@@ -389,6 +389,27 @@ class Tests(TestCase): ...@@ -389,6 +389,27 @@ class Tests(TestCase):
Instruction(opcode=O.OR, dst=0, src=0, off=0, imm=32), Instruction(opcode=O.OR, dst=0, src=0, off=0, imm=32),
Instruction(opcode=O.B+O.STX, dst=10, src=0, off=-1, imm=0)]) Instruction(opcode=O.B+O.STX, dst=10, src=0, off=-1, imm=0)])
def test_bits_and_or(self):
class Local(EBPF):
a = LocalVar((5, 1))
e = Local(ProgType.XDP, "GPL")
with e.stmp:
with (e.a != 0) & (e.stmp > 0) | (e.a == 0) & (e.stmp < 0):
e.stmp = 0
self.assertEqual(e.opcodes, [
Instruction(opcode=O.LD+O.B, dst=2, src=10, off=-1, imm=0),
Instruction(opcode=O.JSET, dst=2, src=0, off=1, imm=32),
Instruction(opcode=O.JMP, dst=0, src=0, off=1, imm=0),
Instruction(opcode=O.JSGT, dst=0, src=0, off=3, imm=0),
Instruction(opcode=O.LD+O.B, dst=2, src=10, off=-1, imm=0),
Instruction(opcode=O.JSET, dst=2, src=0, off=2, imm=32),
Instruction(opcode=O.JSGE, dst=0, src=0, off=1, imm=0),
Instruction(opcode=O.MOV+O.LONG, dst=0, src=0, off=0, imm=0),
])
def test_local_subprog(self): def test_local_subprog(self):
class Local(EBPF): class Local(EBPF):
a = LocalVar('I') a = LocalVar('I')
......
.. currentmodule:: ebpfcat
The EtherCAT master The EtherCAT master
=================== ===================
...@@ -32,18 +34,19 @@ second argument is the absolute address this terminal should be assigned to:: ...@@ -32,18 +34,19 @@ second argument is the absolute address this terminal should be assigned to::
The terminals are usually controlled by devices, where one terminal may be The terminals are usually controlled by devices, where one terminal may be
controlled by several devices, or one device controls several terminals. The controlled by several devices, or one device controls several terminals. The
devices are represented by `Device` objects. Upon instantiation, they are devices are represented by :class:`~ebpfcat.Device` objects. Upon
connected to the terminals:: instantiation, they are connected to the terminals::
from ebpfcat.devices import AnalogOutput from ebpfcat.devices import AnalogOutput
ao = AnalogOutput(out.ch1_value) ao = AnalogOutput(out.ch1_value)
Devices are grouped into `SyncGroup`, which means that their terminals are Devices are grouped into :class:`~ebpfcat.SyncGroup`, which means that their
always read and written at the same time. A device can only belong to one terminals are always read and written at the same time. A device can only
`SyncGroup`, but a terminal may be part of several devices or sync groups. belong to one :class:`~ebpfcat.SyncGroup`, but a terminal may be part of
The sync group is also responsible to constantly transfer data to and from several devices or sync groups. The sync group is also responsible to
the terminals such that they do not time out and go into a safe state:: constantly transfer data to and from the terminals such that they do not time
out and go into a safe state::
from ebpfcat.ebpfcat import SyncGroup from ebpfcat.ebpfcat import SyncGroup
...@@ -51,7 +54,7 @@ the terminals such that they do not time out and go into a safe state:: ...@@ -51,7 +54,7 @@ the terminals such that they do not time out and go into a safe state::
sg.start() # start operating the terminals sg.start() # start operating the terminals
The `AnalogOutput` in the examples is a pretty boring device, it can only The ``AnalogOutput`` in the examples is a pretty boring device, it can only
output a value like so:: output a value like so::
ao.value = 5 # set the value on the terminal ao.value = 5 # set the value on the terminal
...@@ -61,24 +64,26 @@ Writing a device ...@@ -61,24 +64,26 @@ Writing a device
---------------- ----------------
Equipment controlled via the EtherCAT terminals often requires that a dedicated Equipment controlled via the EtherCAT terminals often requires that a dedicated
device is written for it. Devices inherit from `ebpfcat.Device`. They declare device is written for it. Devices inherit from :class:`ebpfcat.Device`. They
which kind of data they want to communicate to the terminals as a `TerminalVar` declare which kind of data they want to communicate to the terminals as a
like so:: :class:`ebpfcat.TerminalVar` like so::
from ebpfcat.ebpfcat import Device from ebpfcat.ebpfcat import Device, TerminalVar
class Motor(Device): class Motor(Device):
speed = TerminalVar() speed = TerminalVar()
position = TerminalVar() position = TerminalVar()
Before they can be used, their `TerminalVar`\ s need to be initialized:: Before they can be used, their :class:`~ebpfcat.TerminalVar`\ s need to be
initialized::
motor = Motor() motor = Motor()
motor.speed = outputTerminal.speed motor.speed = outputTerminal.speed
motor.position = encoderTerminal.value motor.position = encoderTerminal.value
whenever new data is read from the loop, the `update` method of the device is whenever new data is read from the loop, the :meth:`~ebpfcat.Device.update`
called, in which one can evaluate the `TerminalVar`\ s, or set them:: method of the device is called, in which one can evaluate the
:class:`~ebpfcat.TerminalVar`\ s, or set them::
def update(self): def update(self):
"""a idiotic speed controller""" """a idiotic speed controller"""
...@@ -107,11 +112,13 @@ simply terminals, we call them such. ...@@ -107,11 +112,13 @@ simply terminals, we call them such.
Everything in a terminal is controlled by reading or writing parameters in the Everything in a terminal is controlled by reading or writing parameters in the
CoE address space. These addresses are a pair of a 16 bit and an 8 bit number, CoE address space. These addresses are a pair of a 16 bit and an 8 bit number,
usually seperated by a colon, as in 6010:13. Most terminals allow these usually seperated by a colon, as in ``6010:13``. Most terminals allow these
parameters to be set asynchronously. Some of the parameters may be read or parameters to be set asynchronously. Some of the parameters may be read or
written synchronously, so with every communication cycle. written synchronously, so with every communication cycle.
The meaning of all these parameters can usually be found in the documentation of the terminal. Additionally, terminals often have a self-description, which can be read with the command line tool `ec-info`:: The meaning of all these parameters can usually be found in the documentation
of the terminal. Additionally, terminals often have a self-description, which
can be read with the command line tool ``ec-info``::
$ ec-info eth0 --terminal -1 --sdo $ ec-info eth0 --terminal -1 --sdo
...@@ -120,21 +127,21 @@ this reads the first (-1th) terminal's self description (``--sdo``). Add a ...@@ -120,21 +127,21 @@ this reads the first (-1th) terminal's self description (``--sdo``). Add a
all known self descriptions of CoE parameters. all known self descriptions of CoE parameters.
Once we know the meaning of parameters, they may be read or written Once we know the meaning of parameters, they may be read or written
asynchronously using :meth:`~ebpfcat.ethercat.Terminal.sdo_read` and asynchronously using :meth:`~ethercat.Terminal.sdo_read` and
:meth:`~ebpfcat.ethercat.Terminal.sdo_write`. :meth:`~ethercat.Terminal.sdo_write`.
For synchronous data access, a class needs to be defined that defines the For synchronous data access, a class needs to be defined that defines the
parameters one want to use synchronously. The parameters available for parameters one want to use synchronously. The parameters available for
synchronous operations can be found with the ``--pdo`` parameter of the synchronous operations can be found with the ``--pdo`` parameter of the
``ec-info`` command. The class should inherit from ``ec-info`` command. The class should inherit from
:class:`~ebpfcat.ebpfcat.EBPFTerminal` and define a set of tuples called :class:`~ebpfcat.EBPFTerminal` and define a set of tuples called
``comptibility``. The tuples should be the pairs of Ethercat product and vendor ``comptibility``. The tuples should be the pairs of Ethercat product and vendor
id for all terminals supported by this class. Those can be found out with the id for all terminals supported by this class. Those can be found out with the
``--ids`` parameter of the ``ec-info`` command. ``--ids`` parameter of the ``ec-info`` command.
Within the class, the synchronous parameters are defined via Within the class, the synchronous parameters are defined via
:class:`~ebpfcat.ebpfcat.ProcessDesc`. This descriptor takes the two parts of :class:`~ebpfcat.ProcessDesc`. This descriptor takes the two parts of the CoE
the CoE address as parameters, plus an optional size parameter. This is usually address as parameters, plus an optional size parameter. This is usually
determined automatically, but this sometimes fails, in which case it may either determined automatically, but this sometimes fails, in which case it may either
be defined via a format string like in the :mod:`python:struct` module, or it be defined via a format string like in the :mod:`python:struct` module, or it
is an integer which is then a reference to the position of the bit in the is an integer which is then a reference to the position of the bit in the
......