mirror of
https://github.com/saymrwulf/uhd.git
synced 2026-05-16 21:10:10 +00:00
This is a new API call, only available on Python, and only available for
MPM devices (it is added dynamically). It returns an object that allows
calling RPC calls in a Pythonic manner.
Example:
>>> rpcc = usrp.get_mpm_client()
>>> print(rpcc.get_device_info()) # Will print device info, as returned
# by uhd_find_devices
129 lines
5.5 KiB
Text
129 lines
5.5 KiB
Text
/*! \page page_mpm The Module Peripheral Manager (MPM) Architecture
|
|
|
|
\tableofcontents
|
|
|
|
For embedded USRP devices, there is an additional layer of control that UHD uses
|
|
to access, configure, and control the hardware: The Module Peripheral Manager
|
|
(MPM) daemon. In most cases, users of UHD do not need to know any details about
|
|
MPM, but for some advanced use cases, it can be a useful tool.
|
|
|
|
\section mpm_arch Architecture Overview
|
|
|
|
Devices built using the MPM architecture must be capable of running an embedded
|
|
Linux system. Within that system, the MPM daemon is continuously running and
|
|
will allow access to device through a network-RPC based API. The UHD session
|
|
calling into the device will thus be able to access that high-level API instead
|
|
of directly having to interact with registers or other low-level components.
|
|
This way, there is only a single driver in UHD for all MPM-powered devices.
|
|
|
|
The source code for the MPM daemon is located in the `mpm/` subdirectory of the
|
|
UHD repository (note that the UHD library's source code is located in the
|
|
`host/` subdirectory). MPM is written in Python 3, C, and C++14.
|
|
|
|
When starting a UHD session to control an MPM device, UHD will, under the hood,
|
|
first try to access MPM over a network link to gain full control of the device.
|
|
Once it has accessed MPM, it will send commands to MPM to start initializing the
|
|
device for streaming usage.
|
|
|
|
The MPM RPC connection is only used for command & control. Data is streamed over
|
|
a separate connection, directly accessing the FPGA. This combines the
|
|
flexibility of a network-RPC control with the high performance of direct
|
|
streaming access.
|
|
|
|
\section mpm_arch_claiming Device Claiming
|
|
|
|
For most functionality, only a single UHD session can control MPM at the same
|
|
time. To guarantee this, MPM implements a claiming mechanism. At the beginning
|
|
of a UHD session, UHD will attempt to claim a device, which will either fail,
|
|
or will succeed and create a \b token. This token can be used by the controlling
|
|
UHD session to access peripherals which require exclusive access. UHD needs to
|
|
re-claim the device within a certain interval to not lose access to the device.
|
|
If UHD fails to claim a device, the assumption is made that the UHD process has
|
|
terminated, and MPM will disallow further access until another, valid claim has
|
|
been made.
|
|
|
|
This is similar to the X3x0, which uses a claiming mechanism controlled by the
|
|
ZPU.
|
|
|
|
\section mpm_modes Network vs. Embedded Mode
|
|
|
|
Devices such as the N310 allow running a UHD session both on the device, as well
|
|
as off device. The former is called <em>Embedded Mode</em>, the latter <em>
|
|
Network Mode</em>.
|
|
|
|
In both cases, UHD will connect to MPM over a network socket. This allows the
|
|
usage of the exact same driver for network and embedded modes, and thus, the
|
|
same software can be compiled against UHD in both modes (keep in mind that the
|
|
embedded systems are usually not as powerful as dedicated computers, so
|
|
typically, high-performance applications will always run in network mode).
|
|
|
|
\section mpm_debug Debugging Tools
|
|
|
|
\subsection mpm_debug_python Python-based Debugging
|
|
|
|
The Python API has additional methods for interacting with MPM. When creating a
|
|
multi_usrp object, it is possible to get a direct reference to an MPM client:
|
|
|
|
~~~{.python}
|
|
import uhd
|
|
# Assume args contains valid device args:
|
|
usrp = uhd.MultiUSRP(args)
|
|
mpmc = usrp.get_mpm_client()
|
|
# Now load device info over RPC and print:
|
|
print(mpmc.get_device_info())
|
|
~~~
|
|
|
|
The RPC API calls are directly mapped to Python.
|
|
|
|
\b Note: When using the MPM client directly, it is possible to put UHD and the
|
|
device into unsynchronized states. It is an advanced API, only recommended for
|
|
unusual low-level access to the device, or debugging.
|
|
|
|
\subsection mpm_debug_other MPM Tools
|
|
|
|
The `mpm/tools/` subdirectory provides a useful tool for debugging and
|
|
interacting with MPM called `mpm_shell.py`. It is a command line tool to
|
|
directly access MPM commands. Like MPM, it requires Python 3. It can be invoked
|
|
as follows:
|
|
|
|
$ python3 tools/mpm_shell.py [-c] ni-n3xx-ABCD123
|
|
|
|
The `-c` switch will attempt to claim the device. The only other command line
|
|
argument is a network address at which the device can be reached.
|
|
|
|
If the connection succeeds, commands can be directly entered on the command
|
|
line. MPM Shell supports tab completion and on-line help using the `?` operator:
|
|
By prepending it to a command, its docstring will be displayed.
|
|
|
|
> ?get_clock_source
|
|
|
|
Arguments to the commands can simply be appended to the command itself:
|
|
|
|
> set_clock_source external
|
|
|
|
Arguments can also be Python expression, if the first character after the
|
|
command itself is an `=` symbol:
|
|
|
|
> set_db_eeprom =[0, open('eeprom.dat', 'w').read()]
|
|
|
|
In this example, a list is created where the first element is a '0', and the
|
|
second element is a string, read from a binary file. The list will be expanded
|
|
to become the function arguments. In this case, the RPC call `set_db_eeprom`
|
|
must thus have 2 arguments with the appropriate argument types.
|
|
|
|
Note that MPM Shell can make use of non-standard RPC features, such as
|
|
propagation of Python exceptions, which makes it a versatile debugging tool.
|
|
|
|
\section mpm_shell_hijack Hijack Mode
|
|
|
|
In hijack mode, MPM Shell is launched after another process, such as a UHD
|
|
session, is already controlling the device. By passing the token to MPM Shell,
|
|
it can access the device and perform low-level operations on the device.
|
|
The token can be gained by scanning the log messages of the UHD session.
|
|
|
|
It can be invoked as follows:
|
|
|
|
$ python3 tools/mpm_shell.py -j $TOKEN ni-n3xx-ABCD123
|
|
|
|
*/
|
|
// vim:ft=doxygen:
|