- initial
This commit is contained in:
commit
df1d6a9f1c
20
.vscode/launch.json
vendored
Normal file
20
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Debug",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/test_main.py",
|
||||
"python": ".venv/bin/python",
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"/dev/ttyACM0",
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
84
DeviceInterface.py
Normal file
84
DeviceInterface.py
Normal file
@ -0,0 +1,84 @@
|
||||
import serial
|
||||
import re
|
||||
|
||||
class DeviceInterface:
|
||||
"""
|
||||
Helper class for interfacing the device running flexPTP.
|
||||
"""
|
||||
|
||||
def __init__(self, url: str, options: dict = {}) -> None:
|
||||
"""
|
||||
Initialize the interface.
|
||||
|
||||
:param str url: url of the device (tty, socket etc.)
|
||||
:param dict options: collection of several options (baudrate, bytesize, parity, stopbits etc.)
|
||||
:rtype: None
|
||||
"""
|
||||
|
||||
self.device = serial.serial_for_url(url, timeout=0.05) # open remote device
|
||||
|
||||
# set serial port options if applicable
|
||||
if "baudrate" in options:
|
||||
self.device.baudrate = options["baudrate"]
|
||||
if "bytesize" in options:
|
||||
self.device.bytesize = options["bytesize"]
|
||||
if "parity" in options:
|
||||
self.device.parity = options["parity"]
|
||||
if "stopbits" in options:
|
||||
self.device.stopbits = options["stopbits"]
|
||||
|
||||
def read_until(self, expected: bytes = serial.LF) -> bytes:
|
||||
"""
|
||||
Read from the device until a specific sequence is found.
|
||||
|
||||
:param bytes expected: delimiter sequence
|
||||
:return: bytes read
|
||||
:rtype: bytes
|
||||
"""
|
||||
|
||||
return self.device.read_until(expected=expected)
|
||||
|
||||
|
||||
def write(self, data: bytes) -> None:
|
||||
"""
|
||||
Write data onto the device
|
||||
|
||||
:param bytes data: data to transfer
|
||||
"""
|
||||
|
||||
self.device.write(data)
|
||||
|
||||
|
||||
def execute_command(self, cmd: str, expect_results: bool = True, separate_results: bool = False) -> str | dict[str, str] | None:
|
||||
"""
|
||||
Execute command on the device
|
||||
|
||||
:param str cmd: command to launch
|
||||
:param bool expect_results: is there any return values expected and awaited?
|
||||
:param bool separate_results: if True a key-value separation attempted on the results
|
||||
:return: results (if requested)
|
||||
:rtype: str | None
|
||||
"""
|
||||
|
||||
self.device.write((cmd.strip("\r\n") + "\r\n").encode()) # sanitize commands
|
||||
self.device.read_until(cmd.encode()) # flush echo
|
||||
if expect_results: # store results if required
|
||||
timeout = False
|
||||
results = ""
|
||||
while not timeout: # store continuous chunks
|
||||
data = self.device.read(32)
|
||||
if len(data) > 0:
|
||||
results += data.decode()
|
||||
else:
|
||||
timeout = True
|
||||
|
||||
if separate_results: # separation requested
|
||||
records = re.findall("^[ ]*([^:]+)[ ]*:[ ]*(.+)[ ]*$", results.strip(), flags=re.MULTILINE)
|
||||
results = dict[str, str]()
|
||||
for rec in records:
|
||||
results[rec[0]] = rec[1].strip()
|
||||
return results
|
||||
else:
|
||||
return results
|
||||
else:
|
||||
return None
|
||||
4
LinuxPtpController.py
Normal file
4
LinuxPtpController.py
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
class LinuxPtpObserver:
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
45
TestController.py
Normal file
45
TestController.py
Normal file
@ -0,0 +1,45 @@
|
||||
from DeviceInterface import DeviceInterface
|
||||
from LinuxPtpController import LinuxPtpObserver
|
||||
|
||||
class TestController:
|
||||
def __reset_flexptp(self) -> None:
|
||||
self.__di.execute_command("ptp reset")
|
||||
|
||||
def __start_e2e_l4(self) -> None:
|
||||
self.__di.execute_command("ptp profile preset default")
|
||||
|
||||
def __start_p2p_l4(self) -> None:
|
||||
self.__di.execute_command("ptp profile preset defp2p")
|
||||
|
||||
def __start_e2e_l2(self) -> None:
|
||||
self.__di.execute_command("ptp profile preset default")
|
||||
self.__di.execute_command("ptp transport 802.3")
|
||||
self.__reset_flexptp()
|
||||
|
||||
def __start_p2p_l2(self) -> None:
|
||||
self.__di.execute_command("ptp profile preset defp2p")
|
||||
self.__di.execute_command("ptp transport 802.3")
|
||||
self.__reset_flexptp()
|
||||
|
||||
def __start_gPTP(self) -> None:
|
||||
self.__di.execute_command("ptp profile preset gPTP")
|
||||
|
||||
def __set_priority(self, priority1: int, priority2: int) -> None:
|
||||
self.__di.execute_command("ptp priority {:d} {:d}".format(priority1, priority2))
|
||||
|
||||
def __set_domain(self, domain: int) -> None:
|
||||
self.__di.execute_command("ptp domain {:d}".format(domain))
|
||||
|
||||
def __disable_all_logging(self) -> None:
|
||||
logging_types = [ "def", "corr", "ts", "info", "locked", "bmca" ]
|
||||
for lt in logging_types:
|
||||
self.__di.execute_command("ptp log " + lt + " off", expect_results=False)
|
||||
|
||||
def __set_servo_offset(self, offset: int) -> None:
|
||||
self.__di.execute_command("ptp servo offset {:d}".format(offset))
|
||||
|
||||
|
||||
def __init__(self, di: DeviceInterface, lptp_observer: LinuxPtpObserver) -> None:
|
||||
self.__di = di
|
||||
self.__lptp_observer = lptp_observer
|
||||
pass
|
||||
BIN
__pycache__/DeviceInterface.cpython-313.pyc
Normal file
BIN
__pycache__/DeviceInterface.cpython-313.pyc
Normal file
Binary file not shown.
6
linuxptp_configs/E2E_L2.cfg
Normal file
6
linuxptp_configs/E2E_L2.cfg
Normal file
@ -0,0 +1,6 @@
|
||||
[global]
|
||||
logAnnounceInterval 0
|
||||
logSyncInterval 0
|
||||
syncReceiptTimeout 3
|
||||
network_transport L2
|
||||
delay_mechanism E2E
|
||||
6
linuxptp_configs/E2E_UDP.cfg
Normal file
6
linuxptp_configs/E2E_UDP.cfg
Normal file
@ -0,0 +1,6 @@
|
||||
[global]
|
||||
logAnnounceInterval 0
|
||||
logSyncInterval 0
|
||||
syncReceiptTimeout 3
|
||||
network_transport UDPv4
|
||||
delay_mechanism E2E
|
||||
6
linuxptp_configs/P2P_L2.cfg
Normal file
6
linuxptp_configs/P2P_L2.cfg
Normal file
@ -0,0 +1,6 @@
|
||||
[global]
|
||||
logAnnounceInterval 0
|
||||
logSyncInterval 0
|
||||
syncReceiptTimeout 3
|
||||
network_transport L2
|
||||
delay_mechanism P2P
|
||||
6
linuxptp_configs/P2P_UDP.cfg
Normal file
6
linuxptp_configs/P2P_UDP.cfg
Normal file
@ -0,0 +1,6 @@
|
||||
[global]
|
||||
logAnnounceInterval 0
|
||||
logSyncInterval 0
|
||||
syncReceiptTimeout 3
|
||||
network_transport UDPv4
|
||||
delay_mechanism P2P
|
||||
10
linuxptp_configs/gPTP.cfg
Normal file
10
linuxptp_configs/gPTP.cfg
Normal file
@ -0,0 +1,10 @@
|
||||
[global]
|
||||
logAnnounceInterval 0
|
||||
logSyncInterval -3
|
||||
syncReceiptTimeout 3
|
||||
path_trace_enabled 1
|
||||
follow_up_info 1
|
||||
transportSpecific 0x1
|
||||
ptp_dst_mac 01:80:C2:00:00:0E
|
||||
network_transport L2
|
||||
delay_mechanism P2P
|
||||
5
start_linuxptp.sh
Executable file
5
start_linuxptp.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
COMMON_FLAGS=--priority1=127 --priority2=255 --gmCapable=1 --neighborPropDelayThresh=100000 --min_neighbor_prop_delay=-20000000 --assume_two_step=1 --ptp_minor_version=0
|
||||
|
||||
ptp4l -i "$1" -f "linuxptp_configs/$2.cfg" -m -l 6 $COMMON_FLAGS
|
||||
32
test_main.py
Normal file
32
test_main.py
Normal file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import optparse
|
||||
|
||||
import DeviceInterface
|
||||
|
||||
# ----------------------------------
|
||||
|
||||
usage = "<device/url> [-s <baudrate>]"
|
||||
|
||||
parser = optparse.OptionParser(usage=usage)
|
||||
parser.add_option("-s", dest="baudrate", default=115200)
|
||||
opts, args = parser.parse_args()
|
||||
|
||||
missing = (
|
||||
len(args) < 1
|
||||
)
|
||||
if missing:
|
||||
print("Something is missing! Usage:", usage)
|
||||
exit(0)
|
||||
|
||||
di = DeviceInterface.DeviceInterface(url=args[0], options={"baudrate": opts.baudrate })
|
||||
#results = di.execute_command("osinfo")
|
||||
#print(results)
|
||||
|
||||
# get device clock identity
|
||||
OWN_CLOCK_ID_KEY = "Own clock ID"
|
||||
clock_id = di.execute_command("ptp info", separate_results=True)
|
||||
if type(clock_id) == dict[str, str] and OWN_CLOCK_ID_KEY in clock_id:
|
||||
print("Own clock ID:", clock_id[OWN_CLOCK_ID_KEY])
|
||||
else:
|
||||
print("Could not retrieve device clock ID!")
|
||||
Loading…
x
Reference in New Issue
Block a user