Skip to content

Commit

Permalink
first commit: found a pdb bug
Browse files Browse the repository at this point in the history
  • Loading branch information
Garrett Berg committed Mar 10, 2015
1 parent 0439aa8 commit 60a04da
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 93 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Linux [sysfs](https://www.kernel.org/doc/Documentation/gpio/sysfs.txt) gpio access

This library provides gpio access via the standard linux [sysfs interface](https://www.kernel.org/doc/Documentation/gpio/sysfs.txt)

It is intended to mimick [RPIO](http://pythonhosted.org/RPIO/) as much as possible for all features,
while also supporting additional (and better named) functionality to the same methods.

## Supported Features
**sysfs** is still under development, and so only supports minimal features

- get pin values with `read(pin)` or `input(pin)`
- set pin values with `set(pin, value)` or `output(pin)`
- get the pin mode with `mode(pin)`
- set the pin mode with `setup(pin, mode)`
- `mode` can currently equal `sysfs.IN` or `sysfs.OUT`

# Future Features
- setting pullup / pulldown values for pins
- setting pins as pwm
209 changes: 116 additions & 93 deletions gpio.py
Original file line number Diff line number Diff line change
@@ -1,93 +1,116 @@

import functools
import threading
import os

path = os.path
pjoin = os.path.join

gpio_root = '/sys/class/gpio'
gpiopath = lambda pin: os.path.join(gpio_root, 'gpio{}'.format(pin))
_export_lock = threading.Lock()

_pyset = set

_open = dict()
FMODE = 'w+'

IN, OUT = 'in', 'out'


def _write(f, v):
f.write(str(v))


def _read(f):
f.seek(0)
return f.read()


def _verify(function):
"""decorator to ensure pin is properly set up"""
@functools.wraps
def wrapped(pin, *args, **kwargs):
pin = int(pin)
if pin not in _open:
ppath = gpiopath(pin)
if not os.path.exists(ppath):
with _export_lock:
with open(pjoin(gpio_root, 'export'), 'w') as f:
_write(f, pin)
_open[pin] = {
'value': open(pjoin(ppath, 'value'), FMODE),
'direction': open(pjoin(ppath, 'direction'), FMODE),
'drive': open(pjoin(ppath, 'drive'), FMODE)
}
return function(pin, *args, **kwargs)
return wrapped


@_verify
def setup(pin, mode, pullup=None):
if mode not in {IN, OUT}:
raise ValueError(mode)
f = _open[pin]['direction']
_write(f, mode)


@_verify
def mode(pin):
'''get the pin mode'''
f = _open[pin]['direction']
return _read(f)


@_verify
def read(pin):
'''read the pin value
Returns:
bool: 0 or 1
'''
f = _open[pin]['value']
return _read(f)


@_verify
def set(pin, value):
'''set the pin value to 0 or 1'''
value = int(value)
f = _open[pin]['value']
_write(f, value)


@_verify
def input(pin):
'''read the pin. Same as read'''
return read(pin)


@_verify
def output(pin, value):
'''set the pin. Same as set'''
return set(pin)
# -*- coding: utf-8 -*-
import functools
import threading
import os
import sys
import traceback
import pdb

def except_hook(exctype, value, tb):
traceback.print_tb(tb)
print(repr(value))
pdb.post_mortem(tb)

sys.excepthook = except_hook

path = os.path
pjoin = os.path.join

gpio_root = '/sys/class/gpio'
gpiopath = lambda pin: os.path.join(gpio_root, 'gpio{}'.format(pin))
_export_lock = threading.Lock()

_pyset = set

_open = dict()
FMODE = 'w+'

IN, OUT = 'in', 'out'


def _write(f, v):
print("writing: {}: {}".format(f, v))
f.write(str(v))


def _read(f):
f.seek(0)
return f.read()


def _verify(function):
"""decorator to ensure pin is properly set up"""
# @functools.wraps
def wrapped(pin, *args, **kwargs):
pin = int(pin)
if pin not in _open:
ppath = gpiopath(pin)
if not os.path.exists(ppath):
with _export_lock:
with open(pjoin(gpio_root, 'export'), 'w') as f:
_write(f, pin)
_open[pin] = {
'value': open(pjoin(ppath, 'value'), FMODE),
'direction': open(pjoin(ppath, 'direction'), FMODE),
'drive': open(pjoin(ppath, 'drive'), FMODE),
}
return function(pin, *args, **kwargs)
return wrapped


@_verify
def setup(pin, mode, pullup=None):
if mode not in {IN, OUT}:
raise ValueError(mode)
f = _open[pin]['direction']
_write(f, mode)


@_verify
def mode(pin):
'''get the pin mode'''
f = _open[pin]['direction']
return _read(f)


@_verify
def read(pin):
'''read the pin value
Returns:
bool: 0 or 1
'''
f = _open[pin]['value']
return int(_read(f))


@_verify
def set(pin, value):
'''set the pin value to 0 or 1'''
value = int(value)
f = _open[pin]['value']
_write(f, value)


@_verify
def input(pin):
'''read the pin. Same as read'''
return read(pin)


@_verify
def output(pin, value):
'''set the pin. Same as set'''
return set(pin)


if __name__ == '__main__':
print("starting")
skip = {8, 10, 16, 17}
values = []
for n in xrange(24, 29):
if n in skip: continue
# print("pin {:3d} = {}".format(n, read(n)))
values.append(read(n))
print(values)

1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# -*- coding: utf-8 -*-
Binary file added tests/__init__.pyc
Binary file not shown.
Binary file added tests/__pycache__/__init__.cpython-34.pyc
Binary file not shown.
Binary file added tests/__pycache__/test_gpio.cpython-27-PYTEST.pyc
Binary file not shown.
Binary file added tests/__pycache__/test_gpio.cpython-34-PYTEST.pyc
Binary file not shown.
57 changes: 57 additions & 0 deletions tests/test_gpio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
from unittest import TestCase
from unittest.mock import mock_open, patch
import sys
import os
pjoin = os.path.join
import gpio

if sys.version_info.major < 3:
bins = '__builtin__'
else:
bins = 'builtins'

root = gpio.gpio_root


def mockargs(mock):
return [m[0] for m in mock.call_args_list]


def assertInitialized(self, mfile, gpio=0):
margs = mockargs(mfile)
groot = pjoin(root, 'gpio{}'.format(gpio))
self.assertEqual(margs[0], (pjoin(root, 'export'), 'w'))
self.assertEqual(margs[1], (pjoin(groot, 'value'), 'w+'))
self.assertEqual(margs[2], (pjoin(groot, 'direction'), 'w+'))
self.assertEqual(margs[3], (pjoin(groot, 'drive'), 'w+'))


def reset(method):
def wrapped(*args, **kwargs):
gpio._open.clear()
return method(*args, **kwargs)
return wrapped


class TestRead(TestCase):
@reset
def test_basic(self):
mopen = mock_open(read_data='0')
with patch(bins + '.open', mopen, create=True) as m:
result = gpio.read(0)
assertInitialized(self, m)
self.assertEqual(result, 0)


class TestWrite(TestCase):
@reset
def test_basic(self):
mopen = mock_open(read_data='0')
with patch(bins + '.open', mopen, create=True) as m:
import pdb; pdb.set_trace()
gpio.setup(0, gpio.OUT)
gpio.set(0, 0)
assertInitialized(self, m)
written = mockargs(gpio._open[0]['value'].write)
import ipdb; ipdb.set_trace()

0 comments on commit 60a04da

Please sign in to comment.