mirror of
https://github.com/saymrwulf/uhd.git
synced 2026-05-14 20:58:09 +00:00
tools: Add general purpose tool for USRP configuration
Over the years the UHD code base got a whole bunch of tools to control and configure devices. This is an attempt to unify these tools into one. Co-authored-by: Alexander Weber <alexander.weber@ni.com>
This commit is contained in:
parent
5d20a5a401
commit
99ad89609b
22 changed files with 510 additions and 10 deletions
|
|
@ -123,6 +123,12 @@ set(man_page_sources
|
|||
usrp2_card_burner.1
|
||||
)
|
||||
|
||||
if (ENABLE_PYTHON_API)
|
||||
set(man_page_sources
|
||||
usrpctl.1
|
||||
)
|
||||
endif(ENABLE_PYTHON_API)
|
||||
|
||||
########################################################################
|
||||
# Setup man pages
|
||||
########################################################################
|
||||
|
|
|
|||
|
|
@ -56,5 +56,9 @@ unless stated otherwise, they will still work with this version of UHD.
|
|||
|
||||
\li \subpage page_octoclock
|
||||
|
||||
## Usrpctl
|
||||
|
||||
\li \subpage page_usrpctl
|
||||
|
||||
*/
|
||||
// vim:ft=doxygen:
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ uhd_cal_tx_dc_offset(1) uhd_cal_tx_iq_balance(1)
|
|||
This manual page was written by Maitland Bottoms and Nicholas Corgan
|
||||
for the Debian project (but may be used by others).
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2012 Ettus Research LLC
|
||||
Copyright (c) 2012-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ uhd_cal_rx_iq_balance(1) uhd_cal_tx_iq_balance(1)
|
|||
This manual page was written by Maitland Bottoms and Nicholas Corgan
|
||||
for the Debian project (but may be used by others).
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2012 Ettus Research LLC
|
||||
Copyright (c) 2012-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ uhd_cal_tx_dc_offset(1) uhd_cal_rx_iq_balance(1)
|
|||
This manual page was written by Maitland Bottoms and Nicholas Corgan
|
||||
for the Debian project (but may be used by others).
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2012 Ettus Research LLC
|
||||
Copyright (c) 2012-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ This manual page was written by Nicholas Corgan
|
|||
for the Debian project (but may be used by others).
|
||||
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2015 National Instruments Corp.
|
||||
Copyright (c) 2015-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ uhd_usrp_probe(1)
|
|||
This manual page was written by Maitland Bottoms and Nicholas Corgan
|
||||
for the Debian project (but may be used by others).
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2010 Ettus Research LLC
|
||||
Copyright (c) 2010-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ uhd_images_downloader(1) usrp2_card_burner(1)
|
|||
This manual page was written by Nicholas Corgan
|
||||
for the Debian project (but may be used by others).
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2015 Ettus Research LLC
|
||||
Copyright (c) 2015-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ usrp2_card_burner(1) usrp_n2xx_simple_net_burner(1) usrp_x3xx_fpga_burner(1) oct
|
|||
This manual page was written by Maitland Bottoms and Nicholas Corgan
|
||||
for the Debian project (but may be used by others).
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2012,2014 Ettus Research LLC
|
||||
Copyright (c) 2012-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ uhd_find_devices(1)
|
|||
This manual page was written by Maitland Bottoms and Nicholas Corgan
|
||||
for the Debian project (but may be used by others).
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2010 Ettus Research LLC
|
||||
Copyright (c) 2010-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ uhd_images_downloader(1) usrp_n2xx_simple_net_burner(1) usrp_x3xx_fpga_burner(1)
|
|||
This manual page was written by Nicholas Corgan
|
||||
for the Debian project (but may be used by others).
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2012,2014 Ettus Research LLC
|
||||
Copyright (c) 2012-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ uhd_images_downloader(1) usrp2_card_burner(1) usrp_x3xx_fpga_burner(1) octoclock
|
|||
This manual page was written by Nicholas Corgan
|
||||
for the Debian project (but may be used by others).
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2012,2014 Ettus Research LLC
|
||||
Copyright (c) 2012-2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
93
host/docs/usrpctl.1
Normal file
93
host/docs/usrpctl.1
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
.TH "usrpctl" 1 "4.0.0" UHD "User Commands"
|
||||
.SH NAME
|
||||
usrpctl \- USRP Hardware Driver Peripheral Configuration Tool
|
||||
.SH DESCRIPTION
|
||||
Report detailed information on UHD-supported Software Radio Peripherals
|
||||
attached by USB, network, or embedded configuration.
|
||||
Allows update and configuration of attached devices.
|
||||
.LP
|
||||
The UHD package is the universal hardware driver for Ettus Research products. The goal
|
||||
is to provide a host driver and API for current and future Ettus Research products.
|
||||
Users will be able to use the UHD driver standalone or with 3rd party applications.
|
||||
.LP
|
||||
Details include unit names, revision numbers, and available sensors on all attached
|
||||
USRP motherboards and daughterboards.
|
||||
.SH SYNOPSIS
|
||||
.B usrpctl [ID] COMMAND [OPTIONS]
|
||||
.SH ID
|
||||
ID is the optional device argument. It is used to define a set
|
||||
of USRP devices that COMMAND should be applied to. If ID is omitted
|
||||
COMMAND is applied to all reachable devices.
|
||||
|
||||
usrpctl understands the device args argument used by other UHD
|
||||
tools like uhd_find_devices.
|
||||
|
||||
.SH COMMAND
|
||||
Is the action the tool is to take. Every command can be either applied to a
|
||||
single device or a group of devices. Commands that run on a group of
|
||||
devices repeat the command for every device.
|
||||
|
||||
- Single device commands:
|
||||
- config: Read/write configuration variables (e.g., IP address)
|
||||
- probe: reads extended information about the USRP
|
||||
- Multi device commands:
|
||||
- update: Update binaries (e.g., FPGA image)
|
||||
- reset: Reset the device or parts thereof (e.g., only reset MPM)
|
||||
- find: finds all available USRPs in this network
|
||||
|
||||
.SH OPTIONS
|
||||
The options are not always mandatory. It depends on the given COMMAND.
|
||||
|
||||
.SH find command
|
||||
|
||||
The find command takes no further options. If ID is not given it scans the
|
||||
system for available, supported devices and prints a list of discovered devices.
|
||||
The print out is compatible to uhd_find_devices.
|
||||
ID can be used to narrow down the list of discovered devices.
|
||||
|
||||
.SH probe command
|
||||
.IP "Print a complete property tree:"
|
||||
-tree
|
||||
.TP
|
||||
The probe command can only be applied to a single device so make sure that
|
||||
ID identifies exactly one device. Without arguments it displays detailed
|
||||
information about the device such as name, serial, revision numbers,
|
||||
firmware version sensor information on attached motherboard and daughterboards.
|
||||
|
||||
.SH EXAMPLES
|
||||
.TP \w'usrpctl\ 'u
|
||||
.BI usrpctl\ find
|
||||
find all supported devices
|
||||
.TP
|
||||
.BI usrpctl\ type=x300,product=X310 find
|
||||
find all x310 devices
|
||||
.TP
|
||||
.BI usrpctl\ name=my_usrp\ find
|
||||
find a device named my_usrp
|
||||
.TP
|
||||
.BI usrpctl\ addr=192.168.10.2\ find
|
||||
find a device with the given IP.
|
||||
.TP
|
||||
.BI usrpctl\ addr=192.168.10.2\ probe
|
||||
display device information for USRP with the given ID
|
||||
.TP
|
||||
.BI usprctl\ name=my_usrp\ probe\ \-tree
|
||||
display property tree of device with the name my_usrp
|
||||
.TP
|
||||
|
||||
.SH SEE ALSO
|
||||
UHD documentation:
|
||||
.B http://files.ettus.com/manual/
|
||||
.LP
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2022 Ettus Research, A National Instruments Brand
|
||||
.LP
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.LP
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
72
host/docs/usrpctl.dox
Normal file
72
host/docs/usrpctl.dox
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*! \page page_usrpctl Usrpctl
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\section usrpctl_description Description
|
||||
|
||||
usrpctl is the central and universal tool to
|
||||
query, update or configure USRP devices. The command structure is:
|
||||
|
||||
usrpctl $ID $COMMAND $OPTIONS
|
||||
|
||||
`usrpctl` will run $COMMAND on the devices identified by $ID. $OPTIONS
|
||||
is dependend on the chosen command.
|
||||
|
||||
\section usrpctl_id $ID
|
||||
|
||||
$ID is the optional device argument. It is used to define a set
|
||||
of USRP devices that `$COMMAND` should be applied to. If `$ID` is omitted
|
||||
$COMMAND is applied to all reachable devices.
|
||||
|
||||
`usrpctl` understands the device args argument used by other UHD
|
||||
tools like `uhd_find_devices`.
|
||||
|
||||
\section usrpctl_command $COMMAND
|
||||
Is the action the tool is to take. Every command can be either applied to a
|
||||
single device or a group of devices. Commands that run on a group of
|
||||
devices repeat the command for every device.
|
||||
|
||||
- Single device commands:
|
||||
- `config`: Read/write configuration variables (e.g., IP address)
|
||||
- `probe`: reads extended information about the USRP
|
||||
- Multi device commands:
|
||||
- `update`: Update binaries (e.g., FPGA image)
|
||||
- `reset`: Reset the device or parts thereof (e.g., only reset MPM)
|
||||
- `find`: finds all available USRPs in this network
|
||||
|
||||
\section usrpctl_options $OPTIONS
|
||||
|
||||
The options depend on the chosen command. Optional arguments are prepended
|
||||
with a dash, mandatory are not.
|
||||
|
||||
\section usrpctl_commands Available commands
|
||||
|
||||
\section usrpctl_find find
|
||||
|
||||
The find command takes no further options. If `$ID` is not given it scans the
|
||||
system for available, supported devices and prints a list of discovered devices.
|
||||
The print out is compatible to \ref id_identifying_cmdline "`uhd_find_devices`".
|
||||
`$ID` can be used to narrow down the list of discovered devices.
|
||||
|
||||
Examples:
|
||||
|
||||
- `usrpctl find` find all supported devices
|
||||
- `usrpctl type=x300,product=X310 find` find all x310 devices
|
||||
- `usrpctl name=my_usrp find` find a device named my_usrp
|
||||
- `usrpctl addr=192.168.10.2 find` find a device with the given IP.
|
||||
|
||||
\subsection usrpctl_probe probe
|
||||
Arguments:
|
||||
-`-tree`: print a list of the device property tree
|
||||
|
||||
The probe command can only be applied to a single device so make sure that
|
||||
$ID identifies exactly one device. Without arguments it displays detailed
|
||||
information about the device such as name, serial, revision numbers,
|
||||
firmware version sensor information on attached motherboard and daughterboards.
|
||||
|
||||
Examples:
|
||||
- `usrpctl addr=192.168.10.2 probe` display device information for USRP with the given ID
|
||||
- `usprctl name=my_usrp probe -tree` display property tree of device with the name my_usrp
|
||||
|
||||
*/
|
||||
// vim:ft=doxygen:
|
||||
|
|
@ -9,6 +9,7 @@ UHD Python API module
|
|||
|
||||
from . import types
|
||||
from . import usrp
|
||||
from . import usrpctl
|
||||
from . import filters
|
||||
from . import rfnoc
|
||||
from . import dsp
|
||||
|
|
|
|||
7
host/python/uhd/usrpctl/__init__.py
Normal file
7
host/python/uhd/usrpctl/__init__.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
"""
|
||||
Copyright (c) 2022 Ettus Research, A National Instruments Brand
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""
|
||||
|
||||
from . import commands
|
||||
9
host/python/uhd/usrpctl/commands/__init__.py
Normal file
9
host/python/uhd/usrpctl/commands/__init__.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
"""
|
||||
Copyright (c) 2022 Ettus Research, A National Instruments Brand
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""
|
||||
|
||||
from .command import BaseCommand
|
||||
from .find import FindCommand
|
||||
from .probe import ProbeCommand
|
||||
133
host/python/uhd/usrpctl/commands/command.py
Normal file
133
host/python/uhd/usrpctl/commands/command.py
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
"""
|
||||
Copyright (c) 2022 Ettus Research, A National Instruments Brand
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""
|
||||
|
||||
import functools
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
SSH_COMMAND = 'ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 {user}@{host}'
|
||||
SCP_COMMAND = 'scp -o StrictHostKeyChecking=no -o ConnectTimeout=10 {src} {user}@{host}:{dest}'
|
||||
|
||||
REBOOT_SCRIPT = r'''
|
||||
max_timeout=600
|
||||
|
||||
function ssh_cmd() {{
|
||||
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 {user}@{host} $1
|
||||
}}
|
||||
|
||||
if ! {{ boot_id=$(ssh_cmd "cat /proc/sys/kernel/random/boot_id") \
|
||||
&& [[ $boot_id ]]; }}; then
|
||||
echo "Unable to retrieve boot ID" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ssh_cmd "reboot"
|
||||
|
||||
timeout_at=$(( SECONDS + max_timeout ))
|
||||
until new_boot_id=$(ssh_cmd "cat /proc/sys/kernel/random/boot_id") \
|
||||
&& [[ $new_boot_id != "$boot_id" ]]; do
|
||||
if (( SECONDS > timeout_at )); then
|
||||
echo "System did not reboot within timeout" >&2
|
||||
exit 1
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "System successfully rebooted" >&2
|
||||
'''
|
||||
|
||||
class BaseCommand:
|
||||
"""
|
||||
Base class for all usrpctl commands
|
||||
|
||||
Implements some helper useful for all command classes.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def command_name(cls):
|
||||
"""
|
||||
By default the command name is the class name (lowercase) without
|
||||
the trailing "Command"
|
||||
"""
|
||||
return re.sub("(.*)Command$", r"\1", cls.__name__).lower()
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, parser):
|
||||
"""
|
||||
add_parser is used to tell usrpctl argparse which command line
|
||||
argument the command accepts.
|
||||
"""
|
||||
|
||||
def _to_arg_list(self, args):
|
||||
"""
|
||||
Takes parsed arguments from argparse and converts it to
|
||||
a flat list of key value pairs where the key is prepended with
|
||||
two dashes. If value is falsy the pair is ommitted.
|
||||
This is suitable to pass parsed arguments into another process.
|
||||
Example: Suppose args is:
|
||||
Namespace(foo='fval', bar=2, baz=None)
|
||||
then this would result in this list:
|
||||
['--foo', 'fval', '--bar', 2]
|
||||
"""
|
||||
arg_list = {f"--{key}": value for key, value in vars(args).items() if value}
|
||||
return list(functools.reduce(
|
||||
lambda left, right: left + right, arg_list.items())) if arg_list else []
|
||||
|
||||
def _external_process(self, command):
|
||||
"""
|
||||
Run command in an external process.
|
||||
|
||||
stderr is redirected into stdout and the oupput is
|
||||
yielded while the process is running.
|
||||
throws CalledProcessError on non zero returncode
|
||||
"""
|
||||
with subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT, text=True) as process:
|
||||
for line in iter(process.stdout.readline, ""):
|
||||
yield line.rstrip()
|
||||
returncode = process.wait()
|
||||
if returncode != 0:
|
||||
raise subprocess.CalledProcessError(returncode, command)
|
||||
|
||||
def _reboot(self, user, host):
|
||||
cmd = REBOOT_SCRIPT.format(user=user, host=host)
|
||||
yield from self._external_process(["bash", "-c", cmd])
|
||||
|
||||
def _remote_cmd(self, user, host, cmd):
|
||||
"""
|
||||
Executes a command via SSH.
|
||||
"""
|
||||
ssh_cmd = SSH_COMMAND.format(user=user, host=host)
|
||||
yield from self._external_process(ssh_cmd.split(' ') + [cmd])
|
||||
|
||||
def _remote_copy(self, user, host, src, dest):
|
||||
"""
|
||||
Uses scp to copy a file to a remote host
|
||||
"""
|
||||
cp_cmd = SCP_COMMAND.format(user=user, host=host, src=src, dest=dest)
|
||||
yield from self._external_process(cp_cmd.split(' '))
|
||||
|
||||
def _process_output(self, line):
|
||||
print(line)
|
||||
|
||||
def _run_commands(self, usrp, args):
|
||||
print(f"{self.__class__.__name__} is not yet implemented."
|
||||
f"arguments usrp: {usrp} args: {args}")
|
||||
|
||||
def is_multi_device_capable(self):
|
||||
"""
|
||||
Tell whether this command can serve multiple USRPs at once
|
||||
"""
|
||||
return False
|
||||
|
||||
def run(self, usrps, args):
|
||||
"""
|
||||
Run the command
|
||||
"""
|
||||
for usrp in usrps:
|
||||
print(f'{self.command_name()} {usrp.to_string()}')
|
||||
for line in self._run_commands(usrp, args):
|
||||
self._process_output(line)
|
||||
43
host/python/uhd/usrpctl/commands/find.py
Normal file
43
host/python/uhd/usrpctl/commands/find.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"""
|
||||
Copyright (c) 2022 Ettus Research, A National Instruments Brand
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""
|
||||
|
||||
from .command import BaseCommand
|
||||
|
||||
class FindCommand(BaseCommand):
|
||||
"""
|
||||
Class that finds USRP devices
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def add_parser(cls, parser):
|
||||
"""
|
||||
Adding subparser for find command
|
||||
"""
|
||||
parser.add_parser(cls.command_name(),
|
||||
help="print devices found using id parameter")
|
||||
|
||||
def is_multi_device_capable(self):
|
||||
"""
|
||||
Can handle multiple USRPs
|
||||
"""
|
||||
return True
|
||||
|
||||
def run(self, usrps, args):
|
||||
"""
|
||||
Because usrpctl issued find to build the usrps list
|
||||
from the id argument the only thing left to do is
|
||||
print the found devices. Print mimics the behaviour
|
||||
of uhd_find_devices.
|
||||
"""
|
||||
for index, usrp in enumerate(usrps):
|
||||
print('--------------------------------------------------')
|
||||
print(f"-- UHD Device {index}")
|
||||
print('--------------------------------------------------')
|
||||
print('Device Address:')
|
||||
for key, value in usrp.to_dict().items():
|
||||
print(f" {key}: {value}")
|
||||
print()
|
||||
print()
|
||||
31
host/python/uhd/usrpctl/commands/probe.py
Normal file
31
host/python/uhd/usrpctl/commands/probe.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
"""
|
||||
Copyright (c) 2022 Ettus Research, A National Instruments Brand
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""
|
||||
|
||||
from .command import BaseCommand
|
||||
|
||||
class ProbeCommand(BaseCommand):
|
||||
"""
|
||||
Command that uses uhd_usrp_probe to query device properties.
|
||||
Acts on single devices only.
|
||||
"""
|
||||
@classmethod
|
||||
def add_parser(cls, parser):
|
||||
"""
|
||||
Allow -tree as argument. other uhd_usrp_probe arguments
|
||||
are not supported right now
|
||||
"""
|
||||
subparser = parser.add_parser(cls.command_name(),
|
||||
help="report detailed information on USRP device")
|
||||
subparser.add_argument("-tree", const="tree", action="store_const",
|
||||
help="reads the device tree")
|
||||
|
||||
def _run_commands(self, usrp, args):
|
||||
"""
|
||||
probe the device
|
||||
"""
|
||||
yield from self._external_process(
|
||||
["uhd_usrp_probe", f"--args={usrp.to_string()}"] +
|
||||
self._to_arg_list(args))
|
||||
|
|
@ -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
|
||||
|
|
|
|||
91
host/utils/usrpctl.py
Normal file
91
host/utils/usrpctl.py
Normal file
|
|
@ -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())
|
||||
Loading…
Reference in a new issue