diff options
author | Brent Stapleton <brent.stapleton@ettus.com> | 2017-11-29 17:05:41 -0800 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-12-22 15:05:58 -0800 |
commit | 0bf22a3e57dab4af3bfc66dbae999d3d9d11341b (patch) | |
tree | fd8af6de9c1578124f8cbd5d8c21052786d24913 /mpm/python/usrp_mpm/sys_utils | |
parent | 3cff6298cea5f3699aa5db5921cd6933f557a034 (diff) | |
download | uhd-0bf22a3e57dab4af3bfc66dbae999d3d9d11341b.tar.gz uhd-0bf22a3e57dab4af3bfc66dbae999d3d9d11341b.tar.bz2 uhd-0bf22a3e57dab4af3bfc66dbae999d3d9d11341b.zip |
mpm: UIOs now open only when necessary
Refactoring to use the C++-based UIO objects. The Liberio and Ethernet
objects now open the UIO before using it, and close it once done.
Reviewed-By: Martin Braun <martin.braun@ettus.com>
Diffstat (limited to 'mpm/python/usrp_mpm/sys_utils')
-rw-r--r-- | mpm/python/usrp_mpm/sys_utils/uio.py | 68 |
1 files changed, 36 insertions, 32 deletions
diff --git a/mpm/python/usrp_mpm/sys_utils/uio.py b/mpm/python/usrp_mpm/sys_utils/uio.py index c07227776..acbe2cc4f 100644 --- a/mpm/python/usrp_mpm/sys_utils/uio.py +++ b/mpm/python/usrp_mpm/sys_utils/uio.py @@ -18,17 +18,27 @@ Access to UIO mapped memory. """ -import struct import os -import mmap -from builtins import hex from builtins import object +from contextlib import contextmanager import pyudev +import usrp_mpm.libpyusrp_periphs as lib from usrp_mpm.mpmlog import get_logger UIO_SYSFS_BASE_DIR = '/sys/class/uio' UIO_DEV_BASE_DIR = '/dev' + +@contextmanager +def open_uio(label=None, path=None, length=None, read_only=True, offset=None): + """Convenience function for creating a UIO object. + Use this like you would open() for a file""" + uio_obj = UIO(label, path, length, read_only, offset) + uio_obj.open() + yield uio_obj + uio_obj.close() + + def get_all_uio_devs(): """ Return a list of all uio devices. Will look something like @@ -43,6 +53,7 @@ def get_all_uio_devs(): # Typically means UIO devices return [] + def get_uio_map_info(uio_dev, map_num): """ Returns all the map info for a given UIO device and map number. @@ -64,6 +75,7 @@ def get_uio_map_info(uio_dev, map_num): map_info[info_file] = map_info_value return map_info + def find_uio_device(label, logger=None): """ Given a label, returns a tuple (uio_device, map_info). @@ -85,6 +97,7 @@ def find_uio_device(label, logger=None): logger.warning("Found no matching UIO device for label `{0}'".format(label)) return None, None + class UIO(object): """ Provides peek/poke interfaces for uio-mapped memory. @@ -123,35 +136,30 @@ class UIO(object): self.log.error("Could not find a UIO device for label {0}".format(label)) raise RuntimeError("Could not find a UIO device for label {0}".format(label)) self._read_only = read_only - self.log.trace("Opening UIO device file {}...".format(self._path)) - self._fd = os.open(self._path, os.O_RDONLY if read_only else os.O_RDWR) - self.log.trace("Calling mmap({fd}, length={length}, offset={offset})".format( - fd=self._fd, length=hex(length), offset=hex(offset) - )) - self._mm = mmap.mmap( - self._fd, - length, - flags=mmap.MAP_SHARED, - prot=mmap.PROT_READ | (0 if read_only else mmap.PROT_WRITE), - offset=offset, - ) - - def __del__(self): - """ - Destructor needs to close the uio-mapped memory - """ - try: - self._mm.close() - os.close(self._fd) - except: - self.log.warning("Failed to properly destruct UIO object.") - pass + # Our UIO objects are managed in C++ land, which gives us more granular control over + # opening and closing + self._uio = lib.types.mmap_regs_iface(self._path, length, offset, self._read_only, False) + + def __enter__(self): + self.open() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.close() + return exc_type is None + + def open(self): + self._uio.open() + return self + + def close(self): + self._uio.close() def peek32(self, addr): """ Returns the 32-bit value starting at address addr as an integer """ - return struct.unpack('@I', self._mm[addr:addr+4])[0] + return self._uio.peek32(addr) def poke32(self, addr, val): """ @@ -160,8 +168,4 @@ class UIO(object): A value that exceeds 32 bits will be truncated to 32 bits. """ assert not self._read_only - self._mm[addr:addr+4] = struct.pack( - '@I', - (val & 0xFFFFFFFF), - ) - + return self._uio.poke32(addr, val) |