A USRP device has two stages of tuning:
In a typical use-case, the user specifies an overall center frequency for the signal chain. The RF front-end will be tuned as close as possible to the center frequency, and the DSP will account for the error in tuning between target frequency and actual frequency. The user may also explicitly control both stages of tuning through through the uhd::tune_request_t object, which allows for more advanced tuning.
In general, Using UHD software's advanced tuning is highly recommended as it makes it easy to move the DC component out of your band-of-interest. This can be done by passing your desired LO offset to the uhd::tune_request_t object, and letting the UHD software handle the rest.
The uhd::tune_request_t object can also be used with certain daughterboards to use Integer-N tuning instead of the default fractional tuning, allowing for better spur performance. The daughterboards that support this functionality are:
More information can be found in uhd::tune_request_t.
As mentioned above, a tune request (regardless of whether or not the actual uhd::tune_request_t object is used) is split into an RF tune (i.e., tuning the local oscillator) and a frequency shift that is performed in DSP (typically on the FPGA). For example, when integer-N tuning is requested, UHD will automatically pick an LO frequency that is closest to the desired RF frequency, and tune the rest digitally. The BasicRX board, on the other hand, has no LO so all tuning will be handled by the FPGA. In many cases, the actual DSP tuning is pretty low, because many LO synthesizers have a good resolution not operating in integer-N mode.
When using hand-crafted tune requests, it is necessary to observe sampling theory. If the LO offset of a tune request exceeds the sampling rate, the actual DSP frequency will wrap around. For example, if a B210 is used at a master clock rate of 20 MHz, and the LO frequency is set to 100 MHz, the digital tuning range is 90 MHz to 110 MHz. Now, if an LO offset of 12 MHz is selected, it will wrap and become an LO offset of -8 MHz, and the final frequency will become 92 MHz. However, if there is no anti-aliasing filter enabled, there will be an alias at 112 MHz, as requested.
Most USRPs do have anti-aliasing filters, so this does not always work (the BasicTX and BasicRX are a notable exception here). For the same reason, it is typically recommended to not use DSP tuning to get too close to the edge of the Nyquist zone. In the example above, if the signal bandwidth is 2 MHz, the LO offset should not exceed 9 MHz, or the signal would wrap around the edges of the Nyquist zone. In fact, it is recommended to avoid the outer 20% of the Nyquist zone due to analog anti-aliasing filter influences.
Please note that the meaning of the sign of uhd::tune_request_t::dsp_freq differs between TX and RX tuning. See also uhd::tune_request::dsp_freq.
After tuning, the RF front-end will need time to settle into a usable state. Typically, this means that the local oscillators must be given time to lock before streaming begins. Lock time is not consistent; it varies depending upon the device and requested settings. After tuning and before streaming, the user should wait for the lo_locked sensor to become true or sleep for a conservative amount of time (perhaps a second).
Sample rates as delivered to the host computer for USRP devices are constrained to follow several important rules.
It is important to understand that strictly-integer decimation and interpolation are used within USRP hardware to meet the requested sample-rate requirements of the application at hand. That means that the desired sample rate must meet the requirement that master-clock-rate/desired-sample-rate be an integer ratio. Further, it is strongly desirable for that ratio to be even.
There are further constraints on the desired sample rate, such that if the required decimation or interpolation exceeds 128, then the resulting decimation must be evenly divisible by 2, and that if the required decimation exceeds 256, the resulting decimation must be evenly divisible by 4.
For USRP devices with fixed master clocks (notably: USRP1, USRP2, N2xx), there are fewer effective sample rates available than on USRP hardware that provides some flexibility in selecting a master clock. Several USRP devices support flexible master clock selection, allowing a broader range of sample rate selections by applications. See the individual devices' manual pages for more details.
In many cases using USRPs with flexible master-clock rates, it is possible to achieve lower sample rates without running into the constraints of higher decimation rates, simply by choosing a lower master-clock rate to keep required decimation below 128.
In recent versions of UHD software (3.8.5 and newer), and on some devices (currently: B2xx and E3xx series), the master clock rate is chosen automatically (unless specified by the user). UHD will select a master clock rate that is consistent with the desired sample rate indicated by the application.
In selecting a master clock rate on certain USRP hardware (X3xx and B1xx), it is important to select a rate that still provides correct alias suppression by the analog hardware. For daughtercards with a 40 MHz analog bandwidth, this means the clock rate must be at least 40 MHz, with better performance to be expected with a higher clock rate. For daughtercards with 160 MHz bandwidth, it must be at least 160 MHz, again, better performance is to expected with a higher clock rate.
For hardware with fixed master clock rates, of course, this isn't a consideration.
For B2xx and E3xx hardware, the alias suppression is handled differently by the AD936x RFIC, and master clock rate is significantly more flexible as a result.
Note: The following overflow/underflow notes do not apply to USRP1, which does not support the advanced features available in newer products.
When receiving, the device produces samples at a constant rate. Overflows occurs when the host does not consume data fast enough. When UHD software detects the overflow, it prints an "O" or "D" to stdout, and pushes an inline message packet into the receive stream.
Network-based devices: The host does not back-pressure the receive stream. When the kernel's socket buffer becomes full, it will drop subsequent packets. UHD software detects the overflow as a discontinuity in the packet's sequence numbers, and pushes an inline message packet into the receive stream. In this case the character "D" is printed to stdout as an indication.
Other devices: The host back-pressures the receive stream. Therefore, overflows always occur in the device itself. When the device's internal buffers become full, streaming is shut off, and an inline message packet is sent to the host. In this case the character "O" is printed to stdout as an indication. If the device was in continuous streaming mode, the UHD software will automatically restart streaming when the buffer has space again.
When transmitting, the device consumes samples at a constant rate. Underflow occurs when the host does not produce data fast enough. When UHD software detects the underflow, it prints a "U" to stdout, and pushes a message packet into the async message stream.
Note: "O" and "U" message are generally harmless, and just mean the host machine can't keep up with the requested rates.
For the most part, UHD software is thread-safe. Please observe the following limitations:
Fast-path thread requirements: There are three fast-path methods for a device: uhd::tx_streamer::send(), uhd::rx_streamer::recv(), and uhd::tx_streamer::recv_async_msg(). It is safe to call all three methods from different threads, and that may even be advantageous from a performance perspective in the user application. It is not safe, however, to call recv()
or send()
on the same streamer from different threads (for example, it is not allowed to have a multi-producer software architecture, and share access to the send()
call without serializing its access). These methods can also be used in a non-blocking fashion by using a timeout of zero.
Slow-path thread requirements: It is safe to change multiple settings simultaneously. However, this could leave the settings for a device in an uncertain state. This is because changing one setting could have an impact on how a call affects other settings. Example: setting the channel mapping affects how the antennas are set. It is recommended to use at most one thread context for manipulating device settings.
When UHD software spawns a new thread, it may try to boost the thread's scheduling priority. If setting the new priority fails, the UHD software prints a warning to the console, as shown below. This warning is harmless; it simply means that the thread will retain a normal or default scheduling priority.
UHD Warning: Unable to set the thread priority. Performance may be negatively affected. Please see the general application notes in the manual for instructions. EnvironmentError: OSError: error in pthread_setschedparam
Linux Notes:
Non-privileged users need special permission to change the scheduling priority. Add the following line to the file /etc/security/limits.conf
:
@GROUP - rtprio 99
Replace GROUP
with a group in which your user is a member. You may need to log out and log back into the account for the settings to take effect. In most Linux distributions, a list of groups and group members can be found in the file /etc/group
.
For a module to be loaded at runtime, it must be:
UHD_MODULE_PATH
environment variable,\<install-path\>/share/uhd/modules
directory,/usr/share/uhd/modules
directory (UNIX only).UHD will never print to stdout (this was changed in the 3.11.0.0 release). To find out more about configuring UHD logging, see UHD Logging.