diff options
author | Samuel O'Brien <sam.obrien@ni.com> | 2020-07-24 08:35:35 -0500 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-10-28 15:25:48 -0500 |
commit | 00c306d5c441e60e7dfd2516e05e4e433977ecee (patch) | |
tree | 998752676d4ff9dbd06ad194056a214e7fdc763c /mpm/python | |
parent | bd278a4b936f3e30f51d7cb9ff489f3ff7215379 (diff) | |
download | uhd-00c306d5c441e60e7dfd2516e05e4e433977ecee.tar.gz uhd-00c306d5c441e60e7dfd2516e05e4e433977ecee.tar.bz2 uhd-00c306d5c441e60e7dfd2516e05e4e433977ecee.zip |
sim: Integrate simulator into UHD
This commit adds a device::register_device which allows uhd to start up
a simulator when uhd is called with the arguments type=sim. Creating the
device object creates a subprocess using pybind and an embedded
interpreter, and destroying the object cleans up those subprocesses.
Signed-off-by: Samuel O'Brien <sam.obrien@ni.com>
Diffstat (limited to 'mpm/python')
-rwxr-xr-x | mpm/python/usrp_hwd.py | 16 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/CMakeLists.txt | 1 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/process_manager.py | 60 |
3 files changed, 75 insertions, 2 deletions
diff --git a/mpm/python/usrp_hwd.py b/mpm/python/usrp_hwd.py index fb8c1b94e..aaa426fc4 100755 --- a/mpm/python/usrp_hwd.py +++ b/mpm/python/usrp_hwd.py @@ -24,6 +24,10 @@ from threading import Event, Thread _PROCESSES = [] _KILL_EVENT = Event() +# This Global Variable is used by the Simulator to make the spawn_processes, +# and by extension the main method, exit without waiting for the simulator to stop. +# See process_manager.py:bootstrap() for more information. +JOIN_PROCESSES = True def setup_arg_parser(): """ @@ -31,6 +35,12 @@ def setup_arg_parser(): """ parser = argparse.ArgumentParser(description="USRP Hardware Daemon") parser.add_argument( + '--no-logbuf', + dest='use_logbuf', + help="Do not send log messages to UHD", + action="store_false", + ) + parser.add_argument( '--daemon', help="Run as daemon", action="store_true", @@ -169,8 +179,9 @@ def spawn_processes(log, args): Thread(target=kill_thread, daemon=False).start() signal.signal(signal.SIGTERM, kill_time) signal.signal(signal.SIGINT, kill_time) - for proc in _PROCESSES: - proc.join() + if JOIN_PROCESSES: + for proc in _PROCESSES: + proc.join() return True def main(): @@ -181,6 +192,7 @@ def main(): """ args = parse_args() log = mpm.get_main_logger( + use_logbuf=args.use_logbuf, log_default_delta=args.verbose-args.quiet ).getChild('main') version_string = mpm.__version__ diff --git a/mpm/python/usrp_mpm/CMakeLists.txt b/mpm/python/usrp_mpm/CMakeLists.txt index 293892337..f1637ab03 100644 --- a/mpm/python/usrp_mpm/CMakeLists.txt +++ b/mpm/python/usrp_mpm/CMakeLists.txt @@ -23,6 +23,7 @@ set(USRP_MPM_TOP_FILES ${CMAKE_CURRENT_SOURCE_DIR}/mpmutils.py ${CMAKE_CURRENT_SOURCE_DIR}/prefs.py ${CMAKE_CURRENT_SOURCE_DIR}/rpc_server.py + ${CMAKE_CURRENT_SOURCE_DIR}/process_manager.py ) list(APPEND USRP_MPM_FILES ${USRP_MPM_TOP_FILES}) add_subdirectory(chips) diff --git a/mpm/python/usrp_mpm/process_manager.py b/mpm/python/usrp_mpm/process_manager.py new file mode 100644 index 000000000..eb1215ad7 --- /dev/null +++ b/mpm/python/usrp_mpm/process_manager.py @@ -0,0 +1,60 @@ +# +# Copyright 2020 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: GPL-3.0-or-later +# +""" +This module is used as an interface between the sim_find.cpp discovery +and mboard_iface in uhd and the usrp_hwd python file. It manages +starting and stopping the simulator subprocess and configuring logging +""" +from multiprocessing import Process, Event +import sys +try: + # Location if installed from using make install + import usrp_hwd +except ImportError: + # Location if installed from libpyuhd using setuptools + from usrp_mpm import usrp_hwd + +class ProcessManager: + """This object is used to manage a simulator process which is launched + from a python interpreter rather than from an os shell or using systemd + """ + def __init__(self, args): + """args are the command line arguments received by the simulator""" + self.stop_event = Event() + self.process = Process(target=_bootstrap, args=[args, self.stop_event]) + + def start(self): + """Launch the simulator's process""" + self.process.start() + + def stop(self, timeout): + """Attempt to stop the simulator cleanly. Returns True if successful""" + self.stop_event.set() + self.process.join(timeout) + return self.process.exitcode is not None + + def terminate(self): + """Forcefully terminates the simulator""" + self.process.terminate() + + def pid(self): + """Returns the PID of the simulator subprocess""" + return int(self.process.pid) + +def _bootstrap(args, stop_event): + # Set args for new process + # + # Disable UHD log forwarding to avoid + # duplicate messages + sys.argv = ["usrp_hwd.py"] + args + ["--no-logbuf"] + # tell main() not to block + usrp_hwd.JOIN_PROCESSES = False + # Start the discovery and RPC processes + usrp_hwd.main() + # Wait for signal from other process + stop_event.wait() + # Stop the discovery and RPC processes + usrp_hwd.kill_time(None, None) |