[USRP-users] UHD C++ API Questions

Michael West michael.west at ettus.com
Tue Dec 2 15:47:23 EST 2014


Hi Peter,

Much of the underlying code in UHD throws exceptions.  Unfortunately, the
API documentation does not state what functions can throw what exceptions
and what exceptions can propagate from underlying calls.  And since many of
the set_* functions do not have return values, the only way to confirm is
through the corresponding get_* function.

If you are worried about range checking, the UHD API does have functions
that can give you the ranges, such as get_rx_freq_range() or
get_rx_gain_range(), so you can range check your own values before calling
the set functions.

The reset() method is a method of the boost::shared_ptr class.  When you
call reset() on the shared_ptr, it calls the destructor if it holds the
last reference to the object.  Read the boost::shared_ptr documentation for
more information.  But you really don't need to clean up because the
objects are automatically cleaned up when they go out of scope or the
application exits.

Finally, when you call set_rx_freq() with a double value, C++ sees that the
function requires a tune_request_t structure, sees that there is a
tune_request_t constructor that takes a double value, and automatically
converts the double value into a tune_request_t object by calling the
constructor because it assumes that's what you want.

Regards,
Michael

On Tue, Dec 2, 2014 at 10:28 AM, Peter Witkowski via USRP-users <
usrp-users at lists.ettus.com> wrote:

> Where can I find a list or know whether or not a function throws an
> exception or not?  I've spent some time now looking through the Doxygen
> documentation that's available and am still, very much lost.  It would be
> nice to know how errors are handled so that I can deal with them
> accordingly.
>
> In my original question, I asked to see how I can check for errors for
> functions to configure the device using the "set" functions in multi_usrp.
> The response I got indicated that it's best to check the value with the
> corresponding "get" function.  This led me to invalidly assume that these
> functions don't throw exceptions.
>
> So my new question is what functions do throw exceptions, so that I can
> check for this case instead of just having my program exit due to the
> unhandled exception?
>
> Also, once I call make() on a multi_usrp and issue a stream command to it
> to start streaming how do I clean up?  There is no reset() for multi_usrp
> that I've been able to find.  What does the shared pointer point to once
> this clean up is finished?  Finally, it appears that I am using a
> deprecated function for set_rx_freq since I am able to simply pass in a
> double for the frequency.
>
>
> On Tue, Dec 2, 2014 at 1:12 PM, Marcus D. Leech via USRP-users <
> usrp-users at lists.ettus.com> wrote:
>
>>
>>
>> Finally, I just wanted to confirm that the UHD API does NOT throw
>> exceptions.  I guess I was used to lots of try-catch blocks in my code due
>> to working with other libraries.
>>
>> Not sure where you got the impression that UHD, doesn't in general, throw
>> exceptions.  Here's a list I produced with "find" and "grep" on the source
>>   tree:
>>
>> http://www.sbrac.org/files/uhd_exceptions.txt
>>
>> I think that the general error-handling strategy in UHD is to "carry on
>> if possible", so if, for example, you try for a sample-rate that cannot be
>> satisfied,
>>   it will program the hardware for the closest matching sample-rate.
>> Similarly for frequency and gain changes.
>>
>> But for others, such as asking for hardware that doesn't exist, there's
>> no "closest match" possible, so it throws.
>>
>>
>>
>>
>> Thanks again for the help.
>>
>>
>> On Mon, Dec 1, 2014 at 7:31 PM, Michael West <michael.west at ettus.com>
>> wrote:
>>
>>> Answers inline:
>>>
>>> On Mon, Dec 1, 2014 at 3:23 PM, Peter Witkowski via USRP-users <
>>> usrp-users at lists.ettus.com> wrote:
>>>
>>>>     Hello,
>>>>
>>>>  I am in the process of writing a simple RF receiving program that
>>>> follows many of the same steps as rx_samples_to file.  I am following the
>>>> example code found here:
>>>> https://github.com/GREO/uhd/blob/master/host/examples/rx_samples_to_file.cpp
>>>> .
>>>>
>>>>  I had a couple questions come up as I was following the example:
>>>>
>>>>  1.  How are errors handled by the API?  For example, when I call uhd::usrp::multi_usrp::make()
>>>> and it fails, how do I know that the pointer points to an invalid device?
>>>> Do I check the pointer for null or is there an exception thrown?
>>>>
>>>  The return value of make() is a shared_ptr.  You can do a simple check
>>> of the validity of the shared pointer.  Assuming you use
>>> "uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);",
>>> you can simply add "if (not usrp) {}".
>>>
>>>>    2.  Similar question to above, how do I know that device settings
>>>> are actually set?  For example, for set_rx_rate() are any exceptions
>>>> thrown if the rate is bad, or do I just need to call get_rx_rate()
>>>> immediately afterwards?
>>>>
>>>  I recommend doing the get_*() methods for sanity checks.
>>>
>>>>   3.  In a newer version of rx_samples_to_file (see here:
>>>> https://github.com/EttusResearch/uhd/blob/master/host/examples/rx_samples_to_file.cpp
>>>> ) I noticed that a tuning request is used to set the frequency of the
>>>> device.  Is this the preferred method or does a call to set_rx_freq()
>>>> suffice?
>>>>
>>>  Either will work.  The tune request just gives you more control.
>>>
>>>>   4.  In all the example code I've been able to dig up, the connection
>>>> to the device is closed by simply exiting from the program.  Is there a way
>>>> to close the device and perform the necessary clean-up (i.e. the opposite
>>>> of make()) manually?
>>>>
>>>  The necessary clean-up is done in the destructors, which are
>>> automatically called when the program exits cleanly.  You can force the
>>> destructors to be called by using "usrp.reset()".
>>>
>>>>  5.  In the two versions of rx_samples_to_file that I found, I noted a
>>>> difference in the way data is read from the device via recv().  Namely, I'm
>>>> lost on the last two parameters that are passed in.  Do I have to specify
>>>> an io_type and are there different options than RECV_MODE_FULL_BUFF?  Do I
>>>> have to use a STL vector or can I pass it a different data structure (like
>>>> a C-style buffer/array)?  I guess I just need to be pointed to a good few
>>>> lines of code on how recv() works and is implemented.  Also, does recv()
>>>> throw exceptions?
>>>>
>>>  See the UHD API documentation for the information for the recv()
>>> call.  With UHD (and Boost), you have to learn to love templates. ;-)
>>>
>>>  Regards,
>>>  Michael E. West
>>>
>>>>
>>>>  Thanks in advance for the help.
>>>>
>>>>  --
>>>> Peter Witkowski
>>>> pwitkowski at gmail.com
>>>>
>>>> _______________________________________________
>>>> USRP-users mailing list
>>>> USRP-users at lists.ettus.com
>>>> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>>>>
>>>>
>>>
>>
>>
>> --
>> Peter Witkowski
>> pwitkowski at gmail.com
>>
>>
>> _______________________________________________
>> USRP-users mailing listUSRP-users at lists.ettus.comhttp://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>>
>>
>>
>> --
>> Marcus Leech
>> Principal Investigator
>> Shirleys Bay Radio Astronomy Consortiumhttp://www.sbrac.org
>>
>>
>> _______________________________________________
>> USRP-users mailing list
>> USRP-users at lists.ettus.com
>> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>>
>>
>
>
> --
> Peter Witkowski
> pwitkowski at gmail.com
>
> _______________________________________________
> USRP-users mailing list
> USRP-users at lists.ettus.com
> http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/attachments/20141202/3ba89c08/attachment-0002.html>


More information about the USRP-users mailing list