Skip to content

Commit 242543d

Browse files
sdwire3: initial implementation
Signed-off-by: Peter Johennecken <[email protected]>
1 parent 70f6150 commit 242543d

File tree

10 files changed

+203
-1
lines changed

10 files changed

+203
-1
lines changed

doc/configuration.rst

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,29 @@ NetworkUSBSDWireDevice
11031103
A :any:`NetworkUSBSDWireDevice` resource describes a `USBSDWireDevice`_
11041104
resource available on a remote computer.
11051105

1106+
USBSDWire3Device
1107+
~~~~~~~~~~~~~~~~
1108+
A :any:`USBSDWire3Device` resource describes a Tizen
1109+
`SD Wire device <https://web.archive.org/web/20240121081917/https://wiki.tizen.org/SDWire>`_.
1110+
1111+
.. code-block:: yaml
1112+
1113+
USBSDWire3Device:
1114+
match:
1115+
'@ID_PATH': 'pci-0000:00:14.0-usb-0:1.2'
1116+
1117+
Arguments:
1118+
- match (dict): key and value pairs for a udev match, see `udev Matching`_
1119+
1120+
Used by:
1121+
- `USBSDWire3Driver`_
1122+
- `USBStorageDriver`_
1123+
1124+
NetworkUSBSDWire3Device
1125+
~~~~~~~~~~~~~~~~~~~~~~~
1126+
A :any:`NetworkUSBSDWire3Device` resource describes a `USBSDWire3Device`_
1127+
resource available on a remote computer.
1128+
11061129
USBVideo
11071130
~~~~~~~~
11081131
A :any:`USBVideo` resource describes a USB video camera which is supported by a
@@ -3009,6 +3032,23 @@ Arguments:
30093032
The driver can be used in test cases by calling its ``set_mode()`` method with
30103033
argument being "dut", "host", "off", or "client".
30113034

3035+
USBSDWire3Driver
3036+
~~~~~~~~~~~~~~~~
3037+
The :any:`USBSDWire3Driver` uses a `USBSDWire3Device`_ resource to control a
3038+
USB-SD-Wire3 device via `sdwire <https://github.com/Badger-Embedded/sdwire-cli>`_
3039+
tool.
3040+
3041+
Binds to:
3042+
mux:
3043+
- `USBSDWire3Device`_
3044+
- `NetworkUSBSDWire3Device`_
3045+
3046+
Implements:
3047+
- None yet
3048+
3049+
Arguments:
3050+
- None
3051+
30123052
USBVideoDriver
30133053
~~~~~~~~~~~~~~
30143054
The :any:`USBVideoDriver` is used to show a video stream from a remote USB

labgrid/driver/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from .usbloader import MXSUSBDriver, IMXUSBDriver, BDIMXUSBDriver, RKUSBDriver, UUUDriver
2020
from .usbsdmuxdriver import USBSDMuxDriver
2121
from .usbsdwiredriver import USBSDWireDriver
22+
from .usbsdwire3driver import USBSDWire3Driver
2223
from .common import Driver
2324
from .qemudriver import QEMUDriver
2425
from .modbusdriver import ModbusCoilDriver, WaveShareModbusCoilDriver

labgrid/driver/usbsdwire3driver.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import subprocess
2+
3+
import attr
4+
5+
from .common import Driver
6+
from ..factory import target_factory
7+
from ..step import step
8+
from .exception import ExecutionError
9+
from ..util.helper import processwrapper
10+
11+
@target_factory.reg_driver
12+
@attr.s(eq=False)
13+
class USBSDWire3Driver(Driver):
14+
"""The USBSDWire3Driver uses the sdwire tool to control SDWire hardware
15+
16+
Args:
17+
bindings (dict): driver to use with usbsdmux
18+
"""
19+
bindings = {
20+
"mux": {"USBSDWire3Device", "NetworkUSBSDWire3Device"},
21+
}
22+
23+
def __attrs_post_init__(self):
24+
super().__attrs_post_init__()
25+
print(f"USBSDWire3Driver __attrs_post_init__ called for {self.mux}")
26+
if self.target.env:
27+
self.tool = self.target.env.config.get_tool('sdwire')
28+
else:
29+
self.tool = 'sdwire'
30+
if self.mux.control_serial is None:
31+
raise ExecutionError("USBSDWire3Driver requires 'control_serial' to be set in the resource")
32+
self.control_serial = self.match_control_serial()
33+
print(f"USBSDWire3Driver __attrs_post_init__ control_serial: {self.control_serial}")
34+
35+
@Driver.check_active
36+
@step(title='sdmux_set', args=['mode'])
37+
def set_mode(self, mode):
38+
if not mode.lower() in ['dut', 'host']:
39+
raise ExecutionError(f"Setting mode '{mode}' not supported by USBSDWire3Driver")
40+
cmd = self.mux.command_prefix + [
41+
self.tool,
42+
"switch",
43+
"-s",
44+
self.control_serial,
45+
"dut" if mode.lower() == "dut" else "ts",
46+
]
47+
print(f"USBSDWire3Driver set_mode executing: {' '.join(cmd)}")
48+
processwrapper.check_output(cmd)
49+
50+
def match_control_serial(self):
51+
cmd = self.mux.command_prefix + [
52+
self.tool,
53+
"list"
54+
]
55+
proc = subprocess.run(
56+
cmd,
57+
stdout=subprocess.PIPE,
58+
check=True
59+
)
60+
output = proc.stdout.strip().decode()
61+
for line in output.splitlines():
62+
if self.mux.control_serial is not None and line.find(self.mux.control_serial) >= 0:
63+
return line.split()[0]
64+
raise ExecutionError(f"Could not find control serial {self.mux.control_serial} in sdwire list output")
65+
66+
@Driver.check_active
67+
@step(title='sdmux_get')
68+
def get_mode(self):
69+
raise ExecutionError("Getting mode not supported by USBSDWire3Driver")

labgrid/driver/usbstoragedriver.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class USBStorageDriver(Driver):
3737
"NetworkUSBSDMuxDevice",
3838
"USBSDWireDevice",
3939
"NetworkUSBSDWireDevice",
40+
"USBSDWire3Device",
41+
"NetworkUSBSDWire3Device",
4042
},
4143
}
4244
image = attr.ib(

labgrid/remote/client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1206,7 +1206,7 @@ def sd_mux(self):
12061206
action = self.args.action
12071207
target = self._get_target(place)
12081208
name = self.args.name
1209-
from ..resource.remote import NetworkUSBSDMuxDevice, NetworkUSBSDWireDevice
1209+
from ..resource.remote import NetworkUSBSDMuxDevice, NetworkUSBSDWireDevice, NetworkUSBSDWire3Device
12101210

12111211
drv = None
12121212
for resource in target.resources:
@@ -1216,6 +1216,8 @@ def sd_mux(self):
12161216
drv = self._get_driver_or_new(target, "USBSDMuxDriver", name=name)
12171217
elif isinstance(resource, NetworkUSBSDWireDevice):
12181218
drv = self._get_driver_or_new(target, "USBSDWireDriver", name=name)
1219+
elif isinstance(resource, NetworkUSBSDWire3Device):
1220+
drv = self._get_driver_or_new(target, "USBSDWire3Driver", name=name)
12191221
if drv:
12201222
break
12211223

labgrid/remote/exporter.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,25 @@ def _get_params(self):
409409
class USBSDWireExport(USBGenericExport):
410410
"""ResourceExport for USB devices accessed directly from userspace"""
411411

412+
def __attrs_post_init__(self):
413+
super().__attrs_post_init__()
414+
415+
def _get_params(self):
416+
"""Helper function to return parameters"""
417+
return {
418+
"host": self.host,
419+
"busnum": self.local.busnum,
420+
"devnum": self.local.devnum,
421+
"path": self.local.path,
422+
"vendor_id": self.local.vendor_id,
423+
"model_id": self.local.model_id,
424+
}
425+
426+
427+
@attr.s(eq=False)
428+
class USBSDWire3Export(USBGenericExport):
429+
"""ResourceExport for USB devices accessed directly from userspace"""
430+
412431
def __attrs_post_init__(self):
413432
super().__attrs_post_init__()
414433

@@ -557,6 +576,7 @@ def __attrs_post_init__(self):
557576
exports["SigrokUSBSerialDevice"] = USBSigrokExport
558577
exports["USBSDMuxDevice"] = USBSDMuxExport
559578
exports["USBSDWireDevice"] = USBSDWireExport
579+
exports["USBSDWire3Device"] = USBSDWire3Export
560580
exports["USBDebugger"] = USBGenericExport
561581
exports["USBHub"] = USBGenericRemoteExport
562582
exports["USBMassStorage"] = USBGenericExport

labgrid/resource/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
USBPowerPort,
3030
USBSDMuxDevice,
3131
USBSDWireDevice,
32+
USBSDWire3Device,
3233
USBSerialPort,
3334
USBTMC,
3435
USBVideo,

labgrid/resource/remote.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,18 @@ def __attrs_post_init__(self):
250250
self.timeout = 10.0
251251
super().__attrs_post_init__()
252252

253+
@target_factory.reg_resource
254+
@attr.s(eq=False)
255+
class NetworkUSBSDWire3Device(RemoteUSBResource):
256+
"""The NetworkUSBSDWire3Device describes a remotely accessible USBSDWire3 device"""
257+
control_serial = attr.ib(
258+
default=None,
259+
validator=attr.validators.optional(attr.validators.instance_of(str))
260+
)
261+
def __attrs_post_init__(self):
262+
self.timeout = 10.0
263+
super().__attrs_post_init__()
264+
253265
@target_factory.reg_resource
254266
@attr.s(eq=False)
255267
class NetworkSiSPMPowerPort(RemoteUSBResource):

labgrid/resource/suggest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
DFUDevice,
1515
USBSDMuxDevice,
1616
USBSDWireDevice,
17+
USBSDWire3Device,
1718
AlteraUSBBlaster,
1819
RKUSBLoader,
1920
USBNetworkInterface,
@@ -48,6 +49,7 @@ def __init__(self, args):
4849
self.resources.append(USBMassStorage(**args))
4950
self.resources.append(USBSDMuxDevice(**args))
5051
self.resources.append(USBSDWireDevice(**args))
52+
self.resources.append(USBSDWire3Device(**args))
5153
self.resources.append(AlteraUSBBlaster(**args))
5254
self.resources.append(RKUSBLoader(**args))
5355
self.resources.append(USBNetworkInterface(**args))

labgrid/resource/udev.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,59 @@ def update(self):
526526
def path(self):
527527
return self.disk_path
528528

529+
@target_factory.reg_resource
530+
@attr.s(eq=False)
531+
class USBSDWire3Device(USBResource):
532+
"""The USBSDWire3Device describes an attached SDWire3 device,
533+
it is identified via USB using udev
534+
"""
535+
536+
control_serial = attr.ib(
537+
default=None,
538+
validator=attr.validators.optional(str)
539+
)
540+
disk_path = attr.ib(
541+
default=None,
542+
validator=attr.validators.optional(str)
543+
)
544+
545+
def __attrs_post_init__(self):
546+
self.match['ID_VENDOR_ID'] = '0bda'
547+
self.match['ID_MODEL_ID'] = '0316'
548+
self.match['@ID_VENDOR_ID'] = '1d6b'
549+
self.match['@ID_MODEL_ID'] = '0002'
550+
super().__attrs_post_init__()
551+
552+
# Overwrite the avail attribute with our internal property
553+
@property
554+
def avail(self):
555+
return bool(self.control_serial)
556+
557+
# Forbid the USBResource super class to set the avail property
558+
@avail.setter
559+
def avail(self, prop):
560+
pass
561+
562+
# Overwrite the poll function. Only mark the SDWire3 as available if both
563+
# paths are available.
564+
def poll(self):
565+
super().poll()
566+
if self.device is not None and not self.avail:
567+
for child in self.device.parent.children:
568+
if child.subsystem == 'block' and child.device_type == 'disk':
569+
self.disk_path = child.device_node
570+
self.control_serial = self.device.properties.get('ID_SERIAL_SHORT')
571+
572+
def update(self):
573+
super().update()
574+
if self.device is None:
575+
self.disk_path = None
576+
self.control_serial = None
577+
578+
@property
579+
def path(self):
580+
return self.disk_path
581+
529582
@target_factory.reg_resource
530583
@attr.s(eq=False)
531584
class USBSDMuxDevice(USBResource):

0 commit comments

Comments
 (0)