Skip to content

Commit a19d78d

Browse files
authored
Merge pull request #867 from Emantor/topic/exporter_sysfs_exports
2 parents bd0ede7 + a0ef872 commit a19d78d

3 files changed

Lines changed: 40 additions & 2 deletions

File tree

CHANGES.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ New Features in 0.5.0
1010
Bug fixes in 0.5.0
1111
~~~~~~~~~~~~~~~~~~
1212

13+
- The exporter now exports sysfsgpios during place acquire/release, fixing a
14+
race in the sysfspgio agent interface.
1315
- Fixed a bug where using ``labgrid-client io get`` always returned ``low``
1416
when reading a ``sysfsgpio``.
1517
- Fix labgrid-client exit code on keyboard interrupt.

labgrid/remote/exporter.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import shutil
1313
import subprocess
1414
import warnings
15+
from pathlib import Path
1516
from typing import Dict, Type
1617
from socket import gethostname, getfqdn
1718
import attr
@@ -556,7 +557,9 @@ def _get_params(self):
556557

557558

558559
@attr.s(eq=False)
559-
class GPIOGenericExport(ResourceExport):
560+
class GPIOSysFSExport(ResourceExport):
561+
_gpio_sysfs_path_prefix = '/sys/class/gpio'
562+
560563
"""ResourceExport for GPIO lines accessed directly from userspace"""
561564

562565
def __attrs_post_init__(self):
@@ -566,6 +569,9 @@ def __attrs_post_init__(self):
566569
from ..resource import base
567570
local_cls = getattr(base, local_cls_name)
568571
self.local = local_cls(target=None, name=None, **self.local_params)
572+
self.export_path = Path(GPIOSysFSExport._gpio_sysfs_path_prefix,
573+
f'gpio{self.local.index}')
574+
self.system_exported = False
569575

570576
def _get_params(self):
571577
"""Helper function to return parameters"""
@@ -574,7 +580,35 @@ def _get_params(self):
574580
'index': self.local.index,
575581
}
576582

577-
exports["SysfsGPIO"] = GPIOGenericExport
583+
def _get_start_params(self):
584+
return {
585+
'index': self.local.index,
586+
}
587+
588+
def _start(self, start_params):
589+
"""Start a GPIO export to userspace"""
590+
index = start_params['index']
591+
592+
if self.export_path.exists():
593+
self.system_exported = True
594+
return
595+
596+
export_sysfs_path = os.path.join(GPIOSysFSExport._gpio_sysfs_path_prefix, 'export')
597+
with open(export_sysfs_path, mode='wb') as export:
598+
export.write(str(index).encode('utf-8'))
599+
600+
def _stop(self, start_params):
601+
"""Disable a GPIO export to userspace"""
602+
index = start_params['index']
603+
604+
if self.system_exported:
605+
return
606+
607+
export_sysfs_path = os.path.join(GPIOSysFSExport._gpio_sysfs_path_prefix, 'unexport')
608+
with open(export_sysfs_path, mode='wb') as unexport:
609+
unexport.write(str(index).encode('utf-8'))
610+
611+
exports["SysfsGPIO"] = GPIOSysFSExport
578612

579613

580614
@attr.s

labgrid/util/agents/sysfsgpio.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class GpioDigitalOutput:
1414
def _assert_gpio_line_is_exported(index):
1515
gpio_sysfs_path = os.path.join(GpioDigitalOutput._gpio_sysfs_path_prefix,
1616
f'gpio{index}')
17+
# Deprecated: the exporter can export on acquire, we are leaving this
18+
# in for now to support exporters which have not been updated yet.
1719
if not os.path.exists(gpio_sysfs_path):
1820
export_sysfs_path = os.path.join(GpioDigitalOutput._gpio_sysfs_path_prefix, 'export')
1921
with open(export_sysfs_path, mode='wb') as export:

0 commit comments

Comments
 (0)