Skip to content

Commit d51fd5c

Browse files
committed
remote/exporter: export SysFS GPIOs during acquire
Use the _start/_stop infrastructure to export/unexport a GPIO using the sysfs interface to userspace during device acquire/release Fixes #856 Signed-off-by: Rouven Czerwinski <[email protected]>
1 parent 003d79f commit d51fd5c

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

CHANGES.rst

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ New Features in 0.4.1
77
Bug fixes in 0.4.1
88
~~~~~~~~~~~~~~~~~~
99

10+
- The exporter now exports sysfsgpios during place acquire/release, fixing a
11+
race in the sysfspgio agent interface.
1012
- Fixed a bug where using ``labgrid-client io get`` always returned ``low``
1113
when reading a ``sysfsgpio``.
1214
- Fixed ``labgrid-client forward --remote``/``-R``, which used either the LOCAL

labgrid/remote/exporter.py

+34
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
@@ -557,6 +558,8 @@ def _get_params(self):
557558

558559
@attr.s(eq=False)
559560
class GPIOGenericExport(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(GpioGenericExport._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,6 +580,34 @@ def _get_params(self):
574580
'index': self.local.index,
575581
}
576582

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(GpioGenericExport._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(GpioGenericExport._gpio_sysfs_path_prefix, 'unexport')
608+
with open(export_sysfs_path, mode='wb') as unexport:
609+
unexport.write(str(index).encode('utf-8'))
610+
577611
exports["SysfsGPIO"] = GPIOGenericExport
578612

579613

0 commit comments

Comments
 (0)