aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/python
diff options
context:
space:
mode:
authorSamuel O'Brien <sam.obrien@ni.com>2020-07-24 08:35:35 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2020-10-28 15:25:48 -0500
commit00c306d5c441e60e7dfd2516e05e4e433977ecee (patch)
tree998752676d4ff9dbd06ad194056a214e7fdc763c /mpm/python
parentbd278a4b936f3e30f51d7cb9ff489f3ff7215379 (diff)
downloaduhd-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-xmpm/python/usrp_hwd.py16
-rw-r--r--mpm/python/usrp_mpm/CMakeLists.txt1
-rw-r--r--mpm/python/usrp_mpm/process_manager.py60
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)