aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils
diff options
context:
space:
mode:
Diffstat (limited to 'host/utils')
-rw-r--r--host/utils/CMakeLists.txt10
-rw-r--r--host/utils/usrpctl.py91
2 files changed, 101 insertions, 0 deletions
diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt
index 1ac0b1c99..fcb4fd9b0 100644
--- a/host/utils/CMakeLists.txt
+++ b/host/utils/CMakeLists.txt
@@ -38,6 +38,16 @@ UHD_INSTALL(PROGRAMS
DESTINATION ${RUNTIME_DIR}
COMPONENT utilities
)
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/usrpctl.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/usrpctl"
+)
+UHD_INSTALL(PROGRAMS
+ ${CMAKE_CURRENT_BINARY_DIR}/usrpctl
+ RENAME usrpctl
+ DESTINATION ${RUNTIME_DIR}
+ COMPONENT utilities
+)
########################################################################
# Utilities that get installed into the share path
diff --git a/host/utils/usrpctl.py b/host/utils/usrpctl.py
new file mode 100644
index 000000000..c184befee
--- /dev/null
+++ b/host/utils/usrpctl.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+
+"""
+Copyright (c) 2022 Ettus Research, A National Instruments Brand
+
+SPDX-License-Identifier: GPL-3.0-or-later
+"""
+
+import argparse
+import inspect
+import os
+import re
+import sys
+
+import uhd
+import uhd.usrpctl.commands
+
+def get_commands():
+ """
+ Returns a dictionary of all subclasses of BaseCommand
+
+ Classes are searched in uhd.usrpctl.commands module.
+ Key is the command name of the command class.
+ Value is the command class itself.
+
+ BaseCommand is not part of the resulting dictionary
+ """
+ return {command[1].command_name(): command[1] for command in
+ inspect.getmembers(uhd.usrpctl.commands, inspect.isclass)
+ if issubclass(command[1], uhd.usrpctl.commands.BaseCommand)
+ and command[1] != uhd.usrpctl.commands.BaseCommand}
+
+def parse_args(commands):
+ """
+ parse command line arguments and return USRPs to search for as well
+ as command to execute and command arguments
+ """
+ parser = argparse.ArgumentParser()
+ parser.add_argument("id", nargs="?",
+ help="identifies USRPs devices utilizing dev_addr_type")
+ parser.add_argument("-v", action="count", default=0,
+ help="increase verbosity level ranging from -v to -vvvvv")
+
+ subparsers = parser.add_subparsers(dest="command",
+ help="supported commands, detailed help with usrpctl <cmd> --help")
+
+ for command, cls in commands.items():
+ cls.add_parser(subparsers)
+
+ args = parser.parse_args()
+ script_args = argparse.Namespace()
+ script_args.id = args.id
+ script_args.v = args.v
+ command = args.command
+ del args.id
+ del args.v
+ del args.command
+ return (script_args, command, args)
+
+def find_usrps(id_args):
+ """
+ Find USRPs based on the given id_args.
+ """
+ return uhd.find(id_args or "")
+
+def main():
+ """
+ Control all the USRPs!
+ """
+ commands = get_commands()
+ script_args, cmd_name, cmd_args = parse_args(commands)
+ env = os.environ
+ env['UHD_LOG_CONSOLE_LEVEL'] = str(max(0, 5 - script_args.v))
+ usrps = find_usrps(script_args.id)
+
+ if not usrps:
+ print(f"No USRP found to act on (id={script_args.id})")
+ return 1
+
+ command = commands[cmd_name]()
+
+ if not command.is_multi_device_capable():
+ if len(usrps) > 1:
+ print(f"Found {len(usrps)} USRPs but {cmd_name} "
+ "can only act on single device")
+ return 2
+
+ return command.run(usrps, cmd_args)
+
+if __name__ == "__main__":
+ sys.exit(main())